Example #1
0
        /**
         * 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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        /// <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 &gt;= 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;
            }
        }
Example #7
0
        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));
        }
Example #8
0
        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);
        }
Example #10
0
        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);
        }