/** * Creates a new zlib encoder with the specified {@code compressionLevel}, * the specified {@code windowBits}, the specified {@code memLevel}, and * the specified wrapper. * * @param compressionLevel * {@code 1} yields the fastest compression and {@code 9} yields the * best compression. {@code 0} means no compression. The default * compression level is {@code 6}. * @param windowBits * The base two logarithm of the size of the history buffer. The * value should be in the range {@code 9} to {@code 15} inclusive. * Larger values result in better compression at the expense of * memory usage. The default value is {@code 15}. * @param memLevel * How much memory should be allocated for the internal compression * state. {@code 1} uses minimum memory and {@code 9} uses maximum * memory. Larger values result in better and faster compression * at the expense of memory usage. The default value is {@code 8} * * @throws CompressionException if failed to initialize zlib */ public JZlibEncoder(ZlibWrapper wrapper, int compressionLevel, int windowBits, int memLevel) { if (compressionLevel < 0 || compressionLevel > 9) { CThrowHelper.ThrowArgumentException_CompressionLevel(compressionLevel); } if (windowBits < 9 || windowBits > 15) { CThrowHelper.ThrowArgumentException_WindowBits(windowBits); } if (memLevel < 1 || memLevel > 9) { CThrowHelper.ThrowArgumentException_MemLevel(memLevel); } int resultCode = this.z.Init( compressionLevel, windowBits, memLevel, ZlibUtil.ConvertWrapperType(wrapper)); if (resultCode != JZlib.Z_OK) { ZlibUtil.Fail(this.z, "initialization failure", resultCode); } this.wrapperOverhead = ZlibUtil.WrapperOverhead(wrapper); }
/// <summary> /// Allocate or expand the decompression buffer, without exceeding the maximum allocation. /// Calls <see cref="DecompressionBufferExhausted(IByteBuffer)"/> if the buffer is full and cannot be expanded further. /// </summary> /// <param name="ctx"></param> /// <param name="buffer"></param> /// <param name="preferredSize"></param> /// <returns></returns> protected IByteBuffer PrepareDecompressBuffer(IChannelHandlerContext ctx, IByteBuffer buffer, int preferredSize) { if (buffer is null) { if (0u >= (uint)_maxAllocation) { return(ctx.Allocator.HeapBuffer(preferredSize)); } return(ctx.Allocator.HeapBuffer(Math.Min(preferredSize, _maxAllocation), _maxAllocation)); } // this always expands the buffer if possible, even if the expansion is less than preferredSize // we throw the exception only if the buffer could not be expanded at all // this means that one final attempt to deserialize will always be made with the buffer at maxAllocation if (buffer.EnsureWritable(preferredSize, true) == 1) { // buffer must be consumed so subclasses don't add it to output // we therefore duplicate it when calling decompressionBufferExhausted() to guarantee non-interference // but wait until after to consume it so the subclass can tell how much output is really in the buffer DecompressionBufferExhausted(buffer.Duplicate()); _ = buffer.SkipBytes(buffer.ReadableBytes); CThrowHelper.ThrowDecompressionException_Decompression_buffer_has_reached_maximum_size(buffer.MaxCapacity); } return(buffer); }
public JZlibEncoder(int compressionLevel, int windowBits, int memLevel, byte[] dictionary) { if (compressionLevel < 0 || compressionLevel > 9) { CThrowHelper.ThrowArgumentException_CompressionLevel(compressionLevel); } if (windowBits < 9 || windowBits > 15) { CThrowHelper.ThrowArgumentException_WindowBits(windowBits); } if (memLevel < 1 || memLevel > 9) { CThrowHelper.ThrowArgumentException_MemLevel(memLevel); } int resultCode = this.z.DeflateInit( compressionLevel, windowBits, memLevel, JZlib.W_ZLIB); // Default: ZLIB format if (resultCode != JZlib.Z_OK) { ZlibUtil.Fail(this.z, "initialization failure", resultCode); } else { resultCode = this.z.DeflateSetDictionary(dictionary, dictionary.Length); if (resultCode != JZlib.Z_OK) { ZlibUtil.Fail(this.z, "failed to set the dictionary", resultCode); } } this.wrapperOverhead = ZlibUtil.WrapperOverhead(ZlibWrapper.Zlib); }
static unsafe int DecodeUsingGetSet(IByteBuffer src, IByteBuffer dest, sbyte *decodabet, int offset, int length) { int charCount = 0; byte *b4 = stackalloc byte[4]; int b4Count = 0; int i = 0; for (i = offset; i < offset + length; ++i) { var value = src.GetByte(i); var sbiDecode = decodabet[value]; if (sbiDecode < WHITE_SPACE_ENC) { CThrowHelper.ThrowArgumentException_InvalidBase64InputChar(i, value); } if (sbiDecode >= EQUALS_SIGN_ENC) { b4[b4Count++] = value; if (b4Count <= 3) { continue; } if (0u >= (uint)(b4[2] - EQUALS_SIGN)) { int output = ((decodabet[b4[0]] & 0xFF) << 18) | ((decodabet[b4[1]] & 0xFF) << 12); _ = dest.SetByte(charCount++, (int)((uint)output >> 16)); } else if (0u >= (uint)(b4[3] - EQUALS_SIGN)) { int output = ((decodabet[b4[0]] & 0xFF) << 18) | ((decodabet[b4[1]] & 0xFF) << 12) | ((decodabet[b4[2]] & 0xFF) << 6); _ = dest.SetByte(charCount++, (int)((uint)output >> 16)); _ = dest.SetByte(charCount++, (int)((uint)output >> 8)); } else { int output = ((decodabet[b4[0]] & 0xFF) << 18) | ((decodabet[b4[1]] & 0xFF) << 12) | ((decodabet[b4[2]] & 0xFF) << 6) | ((decodabet[b4[3]] & 0xFF) << 0); _ = dest.SetByte(charCount++, (int)((uint)output >> 16)); _ = dest.SetByte(charCount++, (int)((uint)output >> 8)); _ = dest.SetByte(charCount++, (int)((uint)output >> 0)); } b4Count = 0; if (0u >= (uint)(value - EQUALS_SIGN)) { break; } } } return(charCount); }
/// <summary> /// Creates a new instance with the specified preset dictionary and maximum buffer allocation. /// The wrapper is always <see cref="ZlibWrapper.Zlib"/> because it is the only format that /// supports the preset dictionary. /// </summary> /// <param name="dictionary"></param> /// <param name="maxAllocation">Maximum size of the decompression buffer. Must be >= 0. /// If zero, maximum size is decided by the <see cref="IByteBufferAllocator"/>.</param> public JZlibDecoder(byte[] dictionary, int maxAllocation) : base(maxAllocation) { if (dictionary is null) { CThrowHelper.ThrowArgumentNullException(CExceptionArgument.dictionary); } this.dictionary = dictionary; int resultCode; resultCode = this.z.InflateInit(JZlib.W_ZLIB); if (resultCode != JZlib.Z_OK) { ZlibUtil.Fail(this.z, "initialization failure", resultCode); } }
internal static void WriteRawVarint32(IByteBuffer output, int value) { if (output is null) { CThrowHelper.ThrowArgumentNullException(CExceptionArgument.output); } while (true) { if (0u >= (uint)(value & ~0x7F)) { _ = output.WriteByte(value); return; } _ = output.WriteByte((value & 0x7F) | 0x80); value >>= 7; } }
public static unsafe IByteBuffer Encode(IByteBuffer src, int offset, int length, bool breakLines, IBase64Dialect dialect, IByteBufferAllocator allocator) { if (src is null) { CThrowHelper.ThrowArgumentNullException(CExceptionArgument.src); } //if (dialect.alphabet is null) //{ // CThrowHelper.ThrowArgumentNullException(CExceptionArgument.dialect_alphabet); //} Debug.Assert(dialect.Alphabet.Length == 64, "alphabet.Length must be 64!"); if ((offset < src.ReaderIndex) || (offset + length > src.WriterIndex /*src.ReaderIndex + src.ReadableBytes*/)) { CThrowHelper.ThrowArgumentOutOfRangeException(CExceptionArgument.offset); } if ((uint)(length - 1) > SharedConstants.TooBigOrNegative) { return(Unpooled.Empty); } int remainderLength = length % 3; int outLength = length / 3 * 4 + (remainderLength > 0 ? 4 : 0); outLength += breakLines ? outLength / MAX_LINE_LENGTH : 0; IByteBuffer dest = allocator.Buffer(outLength); int destLength = 0; int destIndex = dest.WriterIndex; fixed(byte *alphabet = &MemoryMarshal.GetReference(dialect.Alphabet)) { if (src.IsSingleIoBuffer && dest.IsSingleIoBuffer) { destLength = EncodeUsingPointer(alphabet, src, dest, offset, length, breakLines); } else { destLength = EncodeUsingGetSet(alphabet, src, dest, offset, length, breakLines); } } return(dest.SetIndex(destIndex, destIndex + destLength)); }
public static unsafe IByteBuffer Decode(IByteBuffer src, int offset, int length, IBase64Dialect dialect, IByteBufferAllocator allocator) { if (src is null) { CThrowHelper.ThrowArgumentNullException(CExceptionArgument.src); } //if (dialect.Decodabet is null) //{ // CThrowHelper.ThrowArgumentNullException(CExceptionArgument.dialect_decodabet); //} if ((offset < src.ReaderIndex) || (offset + length > src.WriterIndex /*src.ReaderIndex + src.ReadableBytes*/)) { CThrowHelper.ThrowArgumentOutOfRangeException(CExceptionArgument.offset); } Debug.Assert(dialect.Decodabet.Length == 256, "decodabet.Length must be 256!"); if ((uint)(length - 1) > SharedConstants.TooBigOrNegative) { return(Unpooled.Empty); } int outLength = length * 3 / 4; IByteBuffer dest = allocator.Buffer(outLength); int charCount = 0; int destIndex = dest.WriterIndex; fixed(sbyte *decodabet = &MemoryMarshal.GetReference(dialect.Decodabet)) { if (src.IsSingleIoBuffer && dest.IsSingleIoBuffer) { charCount = DecodeUsingPointer(src, dest, decodabet, offset, length); } else { charCount = DecodeUsingGetSet(src, dest, decodabet, offset, length); } } return(dest.SetIndex(destIndex, destIndex + charCount)); }
protected override void Encode(IChannelHandlerContext context, IByteBuffer message, IByteBuffer output) { if (context is null) { CThrowHelper.ThrowArgumentNullException(CExceptionArgument.context); } if (message is null) { CThrowHelper.ThrowArgumentNullException(CExceptionArgument.message); } if (output is null) { CThrowHelper.ThrowArgumentNullException(CExceptionArgument.output); } int bodyLength = message.ReadableBytes; int headerLength = ComputeRawVarint32Size(bodyLength); _ = output.EnsureWritable(headerLength + bodyLength); WriteRawVarint32(output, bodyLength); _ = output.WriteBytes(message, message.ReaderIndex, bodyLength); }
static unsafe int DecodeUsingPointer(IByteBuffer src, IByteBuffer dest, sbyte *decodabet, int offset, int length) { int charCount = 0; fixed(byte *srcArray = src.Array, d = dest.Array) { byte *destArray = d + dest.ArrayOffset + dest.WriterIndex; byte *b4 = stackalloc byte[4]; int b4Count = 0; int i = src.ArrayOffset + offset; int calcLength = src.ArrayOffset + offset + length; for (; i < calcLength; ++i) { var value = srcArray[i]; var sbiDecode = decodabet[value]; if (sbiDecode < WHITE_SPACE_ENC) { CThrowHelper.ThrowArgumentException_InvalidBase64InputChar(i, value); } if (sbiDecode >= EQUALS_SIGN_ENC) { b4[b4Count++] = value; if (b4Count <= 3) { continue; } if (0u >= (uint)(b4[2] - EQUALS_SIGN)) { int output = ((decodabet[b4[0]] & 0xFF) << 18) | ((decodabet[b4[1]] & 0xFF) << 12); destArray[charCount++] = (byte)((uint)output >> 16); } else if (0u >= (uint)(b4[3] - EQUALS_SIGN)) { int output = ((decodabet[b4[0]] & 0xFF) << 18) | ((decodabet[b4[1]] & 0xFF) << 12) | ((decodabet[b4[2]] & 0xFF) << 6); destArray[charCount++] = (byte)((uint)output >> 16); destArray[charCount++] = (byte)((uint)output >> 8); } else { int output = ((decodabet[b4[0]] & 0xFF) << 18) | ((decodabet[b4[1]] & 0xFF) << 12) | ((decodabet[b4[2]] & 0xFF) << 6) | ((decodabet[b4[3]] & 0xFF) << 0); destArray[charCount++] = (byte)((uint)output >> 16); destArray[charCount++] = (byte)((uint)output >> 8); destArray[charCount++] = (byte)((uint)output >> 0); } b4Count = 0; if (0u >= (uint)(value - EQUALS_SIGN)) { break; } } } } return(charCount); }
static int ReadRawVarint32(IByteBuffer buffer) { if (buffer is null) { CThrowHelper.ThrowArgumentNullException(CExceptionArgument.buffer); } if (!buffer.IsReadable()) { return(0); } _ = buffer.MarkReaderIndex(); byte rawByte = buffer.ReadByte(); if (rawByte < 128) { return(rawByte); } int result = rawByte & 127; if (!buffer.IsReadable()) { _ = buffer.ResetReaderIndex(); return(0); } rawByte = buffer.ReadByte(); if (rawByte < 128) { result |= rawByte << 7; } else { result |= (rawByte & 127) << 7; if (!buffer.IsReadable()) { _ = buffer.ResetReaderIndex(); return(0); } rawByte = buffer.ReadByte(); if (rawByte < 128) { result |= rawByte << 14; } else { result |= (rawByte & 127) << 14; if (!buffer.IsReadable()) { _ = buffer.ResetReaderIndex(); return(0); } rawByte = buffer.ReadByte(); if (rawByte < 128) { result |= rawByte << 21; } else { result |= (rawByte & 127) << 21; if (!buffer.IsReadable()) { _ = buffer.ResetReaderIndex(); return(0); } rawByte = buffer.ReadByte(); result |= rawByte << 28; if (rawByte >= 128) { throw new CorruptedFrameException("Malformed varint."); } } } } return(result); }