private void DeflateInit(ZLibNative.CompressionLevel compressionLevel, int windowBits, int memLevel, ZLibNative.CompressionStrategy strategy) { ZErrorCode errC; try { errC = ZLibNative.CreateZLibStreamForDeflate(out _zlibStream, compressionLevel, windowBits, memLevel, strategy); } catch (Exception cause) { throw new ZLibException(SR.ZLibErrorDLLLoadError, cause); } switch (errC) { case ZErrorCode.Ok: return; case ZErrorCode.MemError: throw new ZLibException(SR.ZLibErrorNotEnoughMemory, "deflateInit2_", (int)errC, _zlibStream.GetErrorMessage()); case ZErrorCode.VersionError: throw new ZLibException(SR.ZLibErrorVersionMismatch, "deflateInit2_", (int)errC, _zlibStream.GetErrorMessage()); case ZErrorCode.StreamError: throw new ZLibException(SR.ZLibErrorIncorrectInitParameters, "deflateInit2_", (int)errC, _zlibStream.GetErrorMessage()); default: throw new ZLibException(SR.ZLibErrorUnexpected, "deflateInit2_", (int)errC, _zlibStream.GetErrorMessage()); } }
internal static extern ZLibNative.ErrorCode DeflateInit2_( ref ZLibNative.ZStream stream, ZLibNative.CompressionLevel level, ZLibNative.CompressionMethod method, int windowBits, int memLevel, ZLibNative.CompressionStrategy strategy);
private void InflateInit(int windowBits) { ZLibNative.ErrorCode error; try { error = ZLibNative.CreateZLibStreamForInflate(out _zlibStream, windowBits); } catch (Exception exception) // could not load the ZLib dll { throw new ZLibException("SR.ZLibErrorDLLLoadError", exception); } switch (error) { case ZLibNative.ErrorCode.Ok: // Successful initialization return; case ZLibNative.ErrorCode.MemError: // Not enough memory throw new ZLibException("SR.ZLibErrorNotEnoughMemory", "inflateInit2_", (int)error, _zlibStream.GetErrorMessage()); case ZLibNative.ErrorCode.VersionError: //zlib library is incompatible with the version assumed throw new ZLibException("SR.ZLibErrorVersionMismatch", "inflateInit2_", (int)error, _zlibStream.GetErrorMessage()); case ZLibNative.ErrorCode.StreamError: // Parameters are invalid throw new ZLibException("SR.ZLibErrorIncorrectInitParameters", "inflateInit2_", (int)error, _zlibStream.GetErrorMessage()); default: throw new ZLibException("SR.ZLibErrorUnexpected", "inflateInit2_", (int)error, _zlibStream.GetErrorMessage()); } }
internal static unsafe ZLibNative.ErrorCode Deflate(ref ZLibNative.ZStream stream, ZLibNative.FlushCode flush) { fixed (ZLibNative.ZStream* streamBytes = &stream) { byte* pBytes = (byte*)streamBytes; return (ZLibNative.ErrorCode)deflate(pBytes, (int)flush); } }
internal static unsafe ZLibNative.ErrorCode DeflateEnd(ref ZLibNative.ZStream stream) { fixed (ZLibNative.ZStream* streamBytes = &stream) { byte* pBytes = (byte*)streamBytes; return (ZLibNative.ErrorCode)deflateEnd(pBytes); } }
internal static unsafe ZLibNative.ErrorCode InflateInit2_( ref ZLibNative.ZStream stream, int windowBits) { fixed (byte* versionString = ZLibVersion) fixed (ZLibNative.ZStream* streamBytes = &stream) { byte* pBytes = (byte*)streamBytes; return (ZLibNative.ErrorCode)inflateInit2_(pBytes, (int)windowBits, versionString, sizeof(ZLibNative.ZStream)); } }
internal static unsafe ZLibNative.ErrorCode DeflateInit2_( ref ZLibNative.ZStream stream, ZLibNative.CompressionLevel level, ZLibNative.CompressionMethod method, int windowBits, int memLevel, ZLibNative.CompressionStrategy strategy) { fixed (byte* versionString = ZLibVersion) fixed (ZLibNative.ZStream* streamBytes = &stream) { byte* pBytes = (byte*)streamBytes; return (ZLibNative.ErrorCode)deflateInit2_(pBytes, (int)level, (int)method, (int)windowBits, (int)memLevel, (int)strategy, versionString, sizeof(ZLibNative.ZStream)); } }
internal static extern ZLibNative.ErrorCode InflateEnd(ref ZLibNative.ZStream stream);
internal static extern ZLibNative.ErrorCode Inflate(ref ZLibNative.ZStream stream, ZLibNative.FlushCode flush);
internal static extern ZLibNative.ErrorCode InflateInit2_(ref ZLibNative.ZStream stream, int windowBits);
internal Deflater(CompressionLevel compressionLevel, int windowBits) { Debug.Assert(windowBits >= minWindowBits && windowBits <= maxWindowBits); ZLibNative.CompressionLevel zlibCompressionLevel; int memLevel; switch (compressionLevel) { // See the note in ZLibNative.CompressionLevel for the recommended combinations. case CompressionLevel.Optimal: zlibCompressionLevel = ZLibNative.CompressionLevel.DefaultCompression; memLevel = ZLibNative.Deflate_DefaultMemLevel; break; case CompressionLevel.Fastest: zlibCompressionLevel = ZLibNative.CompressionLevel.BestSpeed; memLevel = ZLibNative.Deflate_DefaultMemLevel; break; case CompressionLevel.NoCompression: zlibCompressionLevel = ZLibNative.CompressionLevel.NoCompression; memLevel = ZLibNative.Deflate_NoCompressionMemLevel; break; default: throw new ArgumentOutOfRangeException(nameof(compressionLevel)); } ZLibNative.CompressionStrategy strategy = ZLibNative.CompressionStrategy.DefaultStrategy; ZErrorCode errC; try { errC = ZLibNative.CreateZLibStreamForDeflate(out _zlibStream, zlibCompressionLevel, windowBits, memLevel, strategy); } catch (Exception cause) { throw new ZLibException(SR.ZLibErrorDLLLoadError, cause); } switch (errC) { case ZErrorCode.Ok: return; case ZErrorCode.MemError: throw new ZLibException(SR.ZLibErrorNotEnoughMemory, "deflateInit2_", (int)errC, _zlibStream.GetErrorMessage()); case ZErrorCode.VersionError: throw new ZLibException(SR.ZLibErrorVersionMismatch, "deflateInit2_", (int)errC, _zlibStream.GetErrorMessage()); case ZErrorCode.StreamError: throw new ZLibException(SR.ZLibErrorIncorrectInitParameters, "deflateInit2_", (int)errC, _zlibStream.GetErrorMessage()); default: throw new ZLibException(SR.ZLibErrorUnexpected, "deflateInit2_", (int)errC, _zlibStream.GetErrorMessage()); } }
private ZLibNative.ErrorCode Inflate(ZLibNative.FlushCode flushCode) { ZLibNative.ErrorCode errC; try { errC = _zlibStream.Inflate(flushCode); } catch (Exception cause) // could not load the Zlib DLL correctly { throw new ZLibException(SR.ZLibErrorDLLLoadError, cause); } switch (errC) { case ZLibNative.ErrorCode.Ok: // progress has been made inflating case ZLibNative.ErrorCode.StreamEnd: // The end of the input stream has been reached return errC; case ZLibNative.ErrorCode.BufError: // No room in the output buffer - inflate() can be called again with more space to continue return errC; case ZLibNative.ErrorCode.MemError: // Not enough memory to complete the operation throw new ZLibException(SR.ZLibErrorNotEnoughMemory, "inflate_", (int)errC, _zlibStream.GetErrorMessage()); case ZLibNative.ErrorCode.DataError: // The input data was corrupted (input stream not conforming to the zlib format or incorrect check value) throw new InvalidDataException(SR.UnsupportedCompression); case ZLibNative.ErrorCode.StreamError: //the stream structure was inconsistent (for example if next_in or next_out was NULL), throw new ZLibException(SR.ZLibErrorInconsistentStream, "inflate_", (int)errC, _zlibStream.GetErrorMessage()); default: throw new ZLibException(SR.ZLibErrorUnexpected, "inflate_", (int)errC, _zlibStream.GetErrorMessage()); } }
/// <summary> /// Wrapper around the ZLib inflate function, configuring the stream appropriately. /// </summary> private unsafe ZLibNative.ErrorCode ReadInflateOutput(byte* bufPtr, int length, ZLibNative.FlushCode flushCode, out int bytesRead) { lock (SyncLock) { _zlibStream.NextOut = (IntPtr)bufPtr; _zlibStream.AvailOut = (uint)length; ZLibNative.ErrorCode errC = Inflate(flushCode); bytesRead = length - (int)_zlibStream.AvailOut; return errC; } }
/// <summary> /// Translates the given byte array to a GCHandle so that it can be passed to the ZLib /// Inflate function, then returns the result of that call. /// </summary> private unsafe ZLibNative.ErrorCode ReadInflateOutput(byte[] outputBuffer, int offset, int length, ZLibNative.FlushCode flushCode, out int bytesRead) { lock (_syncLock) { fixed (byte* bufPtr = outputBuffer) { _zlibStream.NextOut = (IntPtr)bufPtr + offset; _zlibStream.AvailOut = (uint)length; ZLibNative.ErrorCode errC = Inflate(flushCode); bytesRead = length - (int)_zlibStream.AvailOut; return errC; } } }
/// <summary> /// Throw exception based on ZLib error code /// </summary> /// <param name="retVal"></param> private static void ThrowIfZLibError(ZLibNative.ErrorCode retVal) { // switch does not support fall-through bool invalidOperation = false; bool corruption = false; switch (retVal) { case ZLibNative.ErrorCode.Ok: return; case ZLibNative.ErrorCode.StreamEnd: invalidOperation = true; break; case ZLibNative.ErrorCode.NeedDictionary: corruption = true; break; case ZLibNative.ErrorCode.StreamError: corruption = true; break; case ZLibNative.ErrorCode.DataError: corruption = true; break; case ZLibNative.ErrorCode.MemError: throw new OutOfMemoryException(); case ZLibNative.ErrorCode.BufError: invalidOperation = true; break; case ZLibNative.ErrorCode.VersionError: throw new InvalidOperationException(SR.Get(SRID.ZLibVersionError, ZLibNative.ZLibVersion)); default: { // ErrorNo throw new IOException(); } } if (invalidOperation) throw new InvalidOperationException(); if (corruption) throw new FileFormatException(SR.Get(SRID.CorruptStream)); }