Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / Log / System / IO / Log / FileLogRecordStream.cs / 1305376 / FileLogRecordStream.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; namespace System.IO.Log { // This class is not thread safe. // FileLogRecordStream lets the user read log records in the form of a stream. internal class FileLogRecordStream : System.IO.Stream { // The stream initialy reads the first 4K bytes of the log record. // When need arises, it reads the entire record and creates a new Memory stream with the record data. const int INITIAL_READ = 4096; // The memory stream is created from the record data. It handles all stream operations. MemoryStream stream; SequenceNumber recordSequenceNumber; SimpleFileLog log; FileLogRecordHeader header; // Sequence numbers of the previous and next records. Returned from ReadRecord and ReadRecordPrefix. SequenceNumber prevSeqNum; SequenceNumber nextSeqNum; int recordSize; bool entireRecordRead; object streamLock; internal FileLogRecordStream(SimpleFileLog log, SequenceNumber recordSequenceNumber) { this.log = log; this.recordSequenceNumber = recordSequenceNumber; this.stream = null; this.recordSize = 0; this.entireRecordRead = false; this.streamLock = new object(); CreateMemoryStream(); } // Creates a memory stream with the first 4K bytes of the record. private void CreateMemoryStream() { byte[] pData; int cbData = INITIAL_READ; int totalSize; log.ReadRecordPrefix(this.recordSequenceNumber, out pData, ref cbData, out totalSize, out this.prevSeqNum, out this.nextSeqNum); if (cbData < FileLogRecordHeader.Size) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.LogCorrupt()); this.header = new FileLogRecordHeader(pData); this.recordSize = totalSize - FileLogRecordHeader.Size; int streamSize = Math.Min(this.recordSize, INITIAL_READ - FileLogRecordHeader.Size); this.stream = new MemoryStream( pData, FileLogRecordHeader.Size, streamSize, false); if (totalSize <= INITIAL_READ) { // Record is smaller than 4K. We have read the entire record. this.entireRecordRead = true; } } internal FileLogRecordHeader Header { get { return this.header; } } internal SequenceNumber RecordSequenceNumber { get { return this.recordSequenceNumber; } } internal SequenceNumber PrevLsn { get { return this.prevSeqNum; } } internal SequenceNumber NextLsn { get { return this.nextSeqNum; } } private MemoryStream Stream { get { return this.stream; } } // Multiple threads in Read can result in corrupt data. public override int Read(byte[] buffer, int offset, int count) { int bytesRead = this.Stream.Read(buffer, offset, count); if (bytesRead == count || this.entireRecordRead) { return bytesRead; } else { // We have reached the end of the stream. Read the entire record and create a new stream. ReadEntireRecord(); return this.Stream.Read(buffer, offset+bytesRead, count-bytesRead) + bytesRead; } } // The method reads the entire record and creates a new memory stream. private void ReadEntireRecord() { lock (this.streamLock) { if (this.entireRecordRead) return; // Check if the stream is open. if (!this.stream.CanRead) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ObjectDisposed()); } byte[] data; int size; SequenceNumber prev; SequenceNumber next; log.ReadRecord(this.recordSequenceNumber, out data, out size, out prev, out next); if (!(size == (this.recordSize + FileLogRecordHeader.Size) && next == this.nextSeqNum)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.LogCorrupt()); } long position = this.Stream.Position; // Create a new stream this.stream = new MemoryStream( data, FileLogRecordHeader.Size, data.Length - FileLogRecordHeader.Size, false); this.Stream.Position = position; this.entireRecordRead = true; } } public override bool CanRead { get { return this.stream.CanRead; } } public override bool CanSeek { get { return this.stream.CanSeek; } } public override bool CanWrite { get { return this.stream.CanWrite; } } public override void Close() { lock (this.streamLock) { this.stream.Close(); } } public override void Flush() { this.Stream.Flush(); } public override long Length { get { if (!this.stream.CanRead) { #pragma warning suppress 56503 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ObjectDisposed()); } return this.recordSize; } } public override long Position { get { return this.Stream.Position; } set { this.Stream.Position = value; } } public override long Seek(long offset, SeekOrigin origin) { if (origin == SeekOrigin.End && !this.entireRecordRead) { // The stream we have was created with the first 4K bytes of the record. offset += this.recordSize; origin = SeekOrigin.Begin; } return this.Stream.Seek(offset, origin); } public override void SetLength(long value) { this.stream.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { if (!this.stream.CanRead) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ObjectDisposed()); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.NotSupported()); } } public override void WriteByte(byte value) { if (!this.stream.CanRead) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ObjectDisposed()); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.NotSupported()); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; namespace System.IO.Log { // This class is not thread safe. // FileLogRecordStream lets the user read log records in the form of a stream. internal class FileLogRecordStream : System.IO.Stream { // The stream initialy reads the first 4K bytes of the log record. // When need arises, it reads the entire record and creates a new Memory stream with the record data. const int INITIAL_READ = 4096; // The memory stream is created from the record data. It handles all stream operations. MemoryStream stream; SequenceNumber recordSequenceNumber; SimpleFileLog log; FileLogRecordHeader header; // Sequence numbers of the previous and next records. Returned from ReadRecord and ReadRecordPrefix. SequenceNumber prevSeqNum; SequenceNumber nextSeqNum; int recordSize; bool entireRecordRead; object streamLock; internal FileLogRecordStream(SimpleFileLog log, SequenceNumber recordSequenceNumber) { this.log = log; this.recordSequenceNumber = recordSequenceNumber; this.stream = null; this.recordSize = 0; this.entireRecordRead = false; this.streamLock = new object(); CreateMemoryStream(); } // Creates a memory stream with the first 4K bytes of the record. private void CreateMemoryStream() { byte[] pData; int cbData = INITIAL_READ; int totalSize; log.ReadRecordPrefix(this.recordSequenceNumber, out pData, ref cbData, out totalSize, out this.prevSeqNum, out this.nextSeqNum); if (cbData < FileLogRecordHeader.Size) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.LogCorrupt()); this.header = new FileLogRecordHeader(pData); this.recordSize = totalSize - FileLogRecordHeader.Size; int streamSize = Math.Min(this.recordSize, INITIAL_READ - FileLogRecordHeader.Size); this.stream = new MemoryStream( pData, FileLogRecordHeader.Size, streamSize, false); if (totalSize <= INITIAL_READ) { // Record is smaller than 4K. We have read the entire record. this.entireRecordRead = true; } } internal FileLogRecordHeader Header { get { return this.header; } } internal SequenceNumber RecordSequenceNumber { get { return this.recordSequenceNumber; } } internal SequenceNumber PrevLsn { get { return this.prevSeqNum; } } internal SequenceNumber NextLsn { get { return this.nextSeqNum; } } private MemoryStream Stream { get { return this.stream; } } // Multiple threads in Read can result in corrupt data. public override int Read(byte[] buffer, int offset, int count) { int bytesRead = this.Stream.Read(buffer, offset, count); if (bytesRead == count || this.entireRecordRead) { return bytesRead; } else { // We have reached the end of the stream. Read the entire record and create a new stream. ReadEntireRecord(); return this.Stream.Read(buffer, offset+bytesRead, count-bytesRead) + bytesRead; } } // The method reads the entire record and creates a new memory stream. private void ReadEntireRecord() { lock (this.streamLock) { if (this.entireRecordRead) return; // Check if the stream is open. if (!this.stream.CanRead) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ObjectDisposed()); } byte[] data; int size; SequenceNumber prev; SequenceNumber next; log.ReadRecord(this.recordSequenceNumber, out data, out size, out prev, out next); if (!(size == (this.recordSize + FileLogRecordHeader.Size) && next == this.nextSeqNum)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.LogCorrupt()); } long position = this.Stream.Position; // Create a new stream this.stream = new MemoryStream( data, FileLogRecordHeader.Size, data.Length - FileLogRecordHeader.Size, false); this.Stream.Position = position; this.entireRecordRead = true; } } public override bool CanRead { get { return this.stream.CanRead; } } public override bool CanSeek { get { return this.stream.CanSeek; } } public override bool CanWrite { get { return this.stream.CanWrite; } } public override void Close() { lock (this.streamLock) { this.stream.Close(); } } public override void Flush() { this.Stream.Flush(); } public override long Length { get { if (!this.stream.CanRead) { #pragma warning suppress 56503 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ObjectDisposed()); } return this.recordSize; } } public override long Position { get { return this.Stream.Position; } set { this.Stream.Position = value; } } public override long Seek(long offset, SeekOrigin origin) { if (origin == SeekOrigin.End && !this.entireRecordRead) { // The stream we have was created with the first 4K bytes of the record. offset += this.recordSize; origin = SeekOrigin.Begin; } return this.Stream.Seek(offset, origin); } public override void SetLength(long value) { this.stream.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { if (!this.stream.CanRead) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ObjectDisposed()); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.NotSupported()); } } public override void WriteByte(byte value) { if (!this.stream.CanRead) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ObjectDisposed()); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.NotSupported()); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- GenericAuthenticationEventArgs.cs
- WebBrowserUriTypeConverter.cs
- SqlHelper.cs
- ImageAttributes.cs
- DrawItemEvent.cs
- EnumerableWrapperWeakToStrong.cs
- DataViewSetting.cs
- ContentOperations.cs
- XmlEventCache.cs
- Pen.cs
- SoapIncludeAttribute.cs
- ConstructorNeedsTagAttribute.cs
- TrustLevelCollection.cs
- GridViewCellAutomationPeer.cs
- DataViewSettingCollection.cs
- SemaphoreSlim.cs
- FixUpCollection.cs
- BufferModeSettings.cs
- ToolStripDropDownClosingEventArgs.cs
- SmiEventSink_Default.cs
- XmlProcessingInstruction.cs
- WorkflowQueuingService.cs
- CurrentTimeZone.cs
- EditorZoneDesigner.cs
- WindowsBrush.cs
- IRCollection.cs
- EventRouteFactory.cs
- ToolStrip.cs
- BindableAttribute.cs
- InitializationEventAttribute.cs
- RuleSettings.cs
- Rectangle.cs
- CodeTypeDelegate.cs
- AddValidationError.cs
- XamlBrushSerializer.cs
- RegionInfo.cs
- DesignerVerbCollection.cs
- GorillaCodec.cs
- RequestQueue.cs
- BamlRecordHelper.cs
- TreeWalkHelper.cs
- DbTypeMap.cs
- RegexParser.cs
- OdbcParameter.cs
- CollectionDataContractAttribute.cs
- SystemTcpStatistics.cs
- Cloud.cs
- ParameterDataSourceExpression.cs
- CompositeDispatchFormatter.cs
- ClosableStream.cs
- PartialTrustValidationBehavior.cs
- ApplyTemplatesAction.cs
- ChtmlTextWriter.cs
- SafeWaitHandle.cs
- IIS7WorkerRequest.cs
- ProxyDataContractResolver.cs
- FixedTextPointer.cs
- MatrixAnimationUsingPath.cs
- EntitySetDataBindingList.cs
- XmlNodeComparer.cs
- TreeIterators.cs
- LabelEditEvent.cs
- HtmlDocument.cs
- Propagator.cs
- FixedDSBuilder.cs
- PopupRoot.cs
- KeyValueInternalCollection.cs
- XmlSchemaInclude.cs
- SchemaNamespaceManager.cs
- MessagePartDescription.cs
- LingerOption.cs
- DebugView.cs
- AttachedAnnotation.cs
- DeclaredTypeValidator.cs
- CodeBinaryOperatorExpression.cs
- StringExpressionSet.cs
- SqlDependency.cs
- TreeView.cs
- FileLevelControlBuilderAttribute.cs
- BlurEffect.cs
- QueryCacheKey.cs
- ApplicationManager.cs
- RelatedCurrencyManager.cs
- PagerStyle.cs
- DiscreteKeyFrames.cs
- GeneralTransform2DTo3D.cs
- ImpersonationOption.cs
- SharedHttpsTransportManager.cs
- X509CertificateChain.cs
- CodeExpressionStatement.cs
- XmlSchemaExternal.cs
- ParameterCollectionEditor.cs
- PKCS1MaskGenerationMethod.cs
- ToolStripActionList.cs
- CodeConditionStatement.cs
- UpdateManifestForBrowserApplication.cs
- _SSPIWrapper.cs
- RemotingSurrogateSelector.cs
- ComponentDispatcher.cs
- ResourcesChangeInfo.cs