Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Sys / System / IO / compression / GZipDecoder.cs / 1305376 / GZipDecoder.cs
namespace System.IO.Compression { using System; using System.Diagnostics; // This class decodes GZip header and footer information. // See RFC 1952 for details about the format. internal class GZipDecoder : IFileFormatReader { private GzipHeaderState gzipHeaderSubstate; private GzipHeaderState gzipFooterSubstate; private int gzip_header_flag; private int gzip_header_xlen; private uint expectedCrc32; private uint expectedOutputStreamSize; private int loopCounter; private uint actualCrc32; private long actualStreamSize; public GZipDecoder() { Reset(); } public void Reset() { gzipHeaderSubstate = GzipHeaderState.ReadingID1; gzipFooterSubstate = GzipHeaderState.ReadingCRC; expectedCrc32 = 0; expectedOutputStreamSize = 0; } public bool ReadHeader(InputBuffer input) { while (true) { int bits; switch (gzipHeaderSubstate) { case GzipHeaderState.ReadingID1: bits = input.GetBits(8); if (bits < 0) { return false; } if (bits != GZipConstants.ID1) { throw new InvalidDataException(SR.GetString(SR.CorruptedGZipHeader)); } gzipHeaderSubstate = GzipHeaderState.ReadingID2; goto case GzipHeaderState.ReadingID2; case GzipHeaderState.ReadingID2: bits = input.GetBits(8); if (bits < 0) { return false; } if (bits != GZipConstants.ID2) { throw new InvalidDataException(SR.GetString(SR.CorruptedGZipHeader)); } gzipHeaderSubstate = GzipHeaderState.ReadingCM; goto case GzipHeaderState.ReadingCM; case GzipHeaderState.ReadingCM: bits = input.GetBits(8); if (bits < 0) { return false; } if (bits != GZipConstants.Deflate) { // compression mode must be 8 (deflate) throw new InvalidDataException(SR.GetString(SR.UnknownCompressionMode)); } gzipHeaderSubstate = GzipHeaderState.ReadingFLG; ; goto case GzipHeaderState.ReadingFLG; case GzipHeaderState.ReadingFLG: bits = input.GetBits(8); if (bits < 0) { return false; } gzip_header_flag = bits; gzipHeaderSubstate = GzipHeaderState.ReadingMMTime; loopCounter = 0; // 4 MMTIME bytes goto case GzipHeaderState.ReadingMMTime; case GzipHeaderState.ReadingMMTime: bits = 0; while (loopCounter < 4) { bits = input.GetBits(8); if (bits < 0) { return false; } loopCounter++; } gzipHeaderSubstate = GzipHeaderState.ReadingXFL; loopCounter = 0; goto case GzipHeaderState.ReadingXFL; case GzipHeaderState.ReadingXFL: // ignore XFL bits = input.GetBits(8); if (bits < 0) { return false; } gzipHeaderSubstate = GzipHeaderState.ReadingOS; goto case GzipHeaderState.ReadingOS; case GzipHeaderState.ReadingOS: // ignore OS bits = input.GetBits(8); if (bits < 0) { return false; } gzipHeaderSubstate = GzipHeaderState.ReadingXLen1; goto case GzipHeaderState.ReadingXLen1; case GzipHeaderState.ReadingXLen1: if ((gzip_header_flag & (int)GZipOptionalHeaderFlags.ExtraFieldsFlag) == 0) { goto case GzipHeaderState.ReadingFileName; } bits = input.GetBits(8); if (bits < 0) { return false; } gzip_header_xlen = bits; gzipHeaderSubstate = GzipHeaderState.ReadingXLen2; goto case GzipHeaderState.ReadingXLen2; case GzipHeaderState.ReadingXLen2: bits = input.GetBits(8); if (bits < 0) { return false; } gzip_header_xlen |= (bits << 8); gzipHeaderSubstate = GzipHeaderState.ReadingXLenData; loopCounter = 0; // 0 bytes of XLEN data read so far goto case GzipHeaderState.ReadingXLenData; case GzipHeaderState.ReadingXLenData: bits = 0; while (loopCounter < gzip_header_xlen) { bits = input.GetBits(8); if (bits < 0) { return false; } loopCounter++; } gzipHeaderSubstate = GzipHeaderState.ReadingFileName; loopCounter = 0; goto case GzipHeaderState.ReadingFileName; case GzipHeaderState.ReadingFileName: if ((gzip_header_flag & (int)GZipOptionalHeaderFlags.FileNameFlag) == 0) { gzipHeaderSubstate = GzipHeaderState.ReadingComment; goto case GzipHeaderState.ReadingComment; } do { bits = input.GetBits(8); if (bits < 0) { return false; } if (bits == 0) { // see '\0' in the file name string break; } } while (true); gzipHeaderSubstate = GzipHeaderState.ReadingComment; goto case GzipHeaderState.ReadingComment; case GzipHeaderState.ReadingComment: if ((gzip_header_flag & (int)GZipOptionalHeaderFlags.CommentFlag) == 0) { gzipHeaderSubstate = GzipHeaderState.ReadingCRC16Part1; goto case GzipHeaderState.ReadingCRC16Part1; } do { bits = input.GetBits(8); if (bits < 0) { return false; } if (bits == 0) { // see '\0' in the file name string break; } } while (true); gzipHeaderSubstate = GzipHeaderState.ReadingCRC16Part1; goto case GzipHeaderState.ReadingCRC16Part1; case GzipHeaderState.ReadingCRC16Part1: if ((gzip_header_flag & (int)GZipOptionalHeaderFlags.CRCFlag) == 0) { gzipHeaderSubstate = GzipHeaderState.Done; goto case GzipHeaderState.Done; } bits = input.GetBits(8); // ignore crc if (bits < 0) { return false; } gzipHeaderSubstate = GzipHeaderState.ReadingCRC16Part2; goto case GzipHeaderState.ReadingCRC16Part2; case GzipHeaderState.ReadingCRC16Part2: bits = input.GetBits(8); // ignore crc if (bits < 0) { return false; } gzipHeaderSubstate = GzipHeaderState.Done; goto case GzipHeaderState.Done; case GzipHeaderState.Done: return true; default: Debug.Assert(false, "We should not reach unknown state!"); throw new InvalidDataException(SR.GetString(SR.UnknownState)); } } } public bool ReadFooter(InputBuffer input) { input.SkipToByteBoundary(); if (gzipFooterSubstate == GzipHeaderState.ReadingCRC) { while (loopCounter < 4) { int bits = input.GetBits(8); if (bits < 0) { return false; } expectedCrc32 |= ((uint)bits << (8 * loopCounter)); loopCounter++; } gzipFooterSubstate = GzipHeaderState.ReadingFileSize; loopCounter = 0; } if (gzipFooterSubstate == GzipHeaderState.ReadingFileSize) { if (loopCounter == 0) expectedOutputStreamSize = 0; while (loopCounter < 4) { int bits = input.GetBits(8); if (bits < 0) { return false; } expectedOutputStreamSize |= ((uint)bits << (8 * loopCounter)); loopCounter++; } } return true; } public void UpdateWithBytesRead(byte[] buffer, int offset, int copied) { actualCrc32 = Crc32Helper.UpdateCrc32(actualCrc32, buffer, offset, copied); long n = actualStreamSize + (uint)copied; if (n > GZipConstants.FileLengthModulo) { long temp = Math.DivRem(n, GZipConstants.FileLengthModulo, out n); } actualStreamSize = n; } public void Validate() { if (expectedCrc32 != actualCrc32) { throw new InvalidDataException(SR.GetString(SR.InvalidCRC)); } if (actualStreamSize != expectedOutputStreamSize) { throw new InvalidDataException(SR.GetString(SR.InvalidStreamSize)); } } internal enum GzipHeaderState { // GZIP header ReadingID1, ReadingID2, ReadingCM, ReadingFLG, ReadingMMTime, // iterates 4 times ReadingXFL, ReadingOS, ReadingXLen1, ReadingXLen2, ReadingXLenData, ReadingFileName, ReadingComment, ReadingCRC16Part1, ReadingCRC16Part2, Done, // done reading GZIP header // GZIP footer ReadingCRC, // iterates 4 times ReadingFileSize // iterates 4 times } [Flags] internal enum GZipOptionalHeaderFlags { CRCFlag = 2, ExtraFieldsFlag = 4, FileNameFlag = 8, CommentFlag = 16 } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TextContainerHelper.cs
- CryptoStream.cs
- LexicalChunk.cs
- ArgumentDirectionHelper.cs
- Oid.cs
- input.cs
- UserPreferenceChangingEventArgs.cs
- GridViewHeaderRowPresenter.cs
- TextChange.cs
- GridViewColumnCollectionChangedEventArgs.cs
- SolidColorBrush.cs
- FontStyles.cs
- TypeSemantics.cs
- AuthenticationConfig.cs
- XmlDocumentType.cs
- ImportException.cs
- DBParameter.cs
- ResourceProviderFactory.cs
- GlobalItem.cs
- OrderedDictionary.cs
- TabControlEvent.cs
- QueryAccessibilityHelpEvent.cs
- RTLAwareMessageBox.cs
- SplineKeyFrames.cs
- TreeNodeStyleCollection.cs
- LowerCaseStringConverter.cs
- ObjectViewQueryResultData.cs
- InfoCardArgumentException.cs
- StyleTypedPropertyAttribute.cs
- WinInet.cs
- TableLayoutSettings.cs
- PostBackOptions.cs
- Geometry3D.cs
- QilPatternVisitor.cs
- RefExpr.cs
- DataGridViewBindingCompleteEventArgs.cs
- ProcessModule.cs
- WebDisplayNameAttribute.cs
- ArrayList.cs
- ComponentResourceKey.cs
- PopOutPanel.cs
- BitmapEffectDrawing.cs
- TextSpan.cs
- XmlSequenceWriter.cs
- ListenerConfig.cs
- OracleSqlParser.cs
- PowerStatus.cs
- TemplateBindingExtensionConverter.cs
- ConfigUtil.cs
- cache.cs
- CompiledQuery.cs
- BindingFormattingDialog.cs
- GlyphTypeface.cs
- QuaternionRotation3D.cs
- ClockGroup.cs
- ServicesExceptionNotHandledEventArgs.cs
- SymLanguageVendor.cs
- HttpFileCollection.cs
- WebPartDeleteVerb.cs
- DesignerActionItem.cs
- RoleGroupCollection.cs
- StylusDownEventArgs.cs
- FieldBuilder.cs
- LineServices.cs
- SerializationAttributes.cs
- SqlCrossApplyToCrossJoin.cs
- BlurBitmapEffect.cs
- SqlTransaction.cs
- DataGridTextBox.cs
- FixedStringLookup.cs
- BinaryHeap.cs
- BamlRecordHelper.cs
- PowerModeChangedEventArgs.cs
- HeaderCollection.cs
- LockCookie.cs
- OdbcErrorCollection.cs
- HeaderUtility.cs
- SimpleHandlerBuildProvider.cs
- FontFamilyIdentifier.cs
- WebEventCodes.cs
- DiscoveryMessageSequence11.cs
- SafeNativeMethods.cs
- BaseResourcesBuildProvider.cs
- LoginUtil.cs
- WindowsScrollBarBits.cs
- hresults.cs
- ColorContext.cs
- BufferedResponseStream.cs
- MSHTMLHost.cs
- Compiler.cs
- BrushProxy.cs
- TypefaceMetricsCache.cs
- IPAddress.cs
- DataSourceCollectionBase.cs
- FileDialog.cs
- ServiceOperationParameter.cs
- ListViewGroupCollectionEditor.cs
- SoapSchemaImporter.cs
- AppDomainFactory.cs
- MulticastNotSupportedException.cs