public static byte[] Compress(byte[] input)
        {
            var compressionArray = new byte[input.Length + 2];
            var compressedLength = SnappyCompress.Compress(SnappyByteBuffer.NewSync(compressionArray), SnappyByteBuffer.NewSync(input));

            var output = new byte[compressedLength];

            Array.Copy(compressionArray, output, compressedLength);

            return(output);
        }
        public static bool TryCompress(ref SnappyByteBuffer data, int maxSizeInPercent)
        {
            var compressed       = SnappyByteBuffer.NewAsync(new byte[data.Length * (long)maxSizeInPercent / 100]);
            var compressedLength = Compress(compressed, data);

            if (compressedLength < 0)
            {
                return(false);
            }
            data = SnappyByteBuffer.NewAsync(compressed.Buffer, 0, compressedLength);
            return(true);
        }
예제 #3
0
        public SnappyByteBuffer ResizingAppend(SnappyByteBuffer append)
        {
            if (AsyncSafe)
            {
                if (Offset + Length + append.Length <= Buffer.Length)
                {
                    Array.Copy(append.Buffer, append.Offset, Buffer, Offset + Length, append.Length);
                    return(NewAsync(Buffer, Offset, Length + append.Length));
                }
            }
            var newCapacity = Math.Max(Length + append.Length, Length * 2);
            var newBuffer   = new byte[newCapacity];

            Array.Copy(Buffer, Offset, newBuffer, 0, Length);
            Array.Copy(append.Buffer, append.Offset, newBuffer, Length, append.Length);
            return(NewAsync(newBuffer, 0, Length + append.Length));
        }
예제 #4
0
        public static SnappyByteBuffer Decompress(SnappyByteBuffer compressedBytes)
        {
            int ofs;
            var decompressedSize = DecompressedSize(compressedBytes, out ofs);

            if (decompressedSize < 0)
            {
                throw new InvalidDataException();
            }
            var dst    = new byte[decompressedSize];
            var dstBuf = SnappyByteBuffer.NewAsync(dst);

            if (!DecompressRaw(dstBuf, SnappyByteBuffer.NewSync(compressedBytes.Buffer, compressedBytes.Offset + ofs, compressedBytes.Length - ofs)))
            {
                throw new InvalidDataException();
            }
            return(dstBuf);
        }
예제 #5
0
        public static byte[] Decompress(byte[] input)
        {
            var buffer = SnappyDecompress.Decompress(SnappyByteBuffer.NewSync(input));

            return(buffer.ToByteArray());
        }
예제 #6
0
        public static int DecompressedSize(SnappyByteBuffer compressedBytes, out int length)
        {
            var offset = compressedBytes.Offset;
            var limit  = offset + compressedBytes.Length;
            var buf    = compressedBytes.Buffer;

            if (offset >= limit)
            {
                goto error;
            }
            var b = buf[offset];

            offset++;
            var result = (uint)(b & 127);

            if (b < 128)
            {
                goto done;
            }
            if (offset >= limit)
            {
                goto error;
            }
            b = buf[offset];
            offset++;
            result |= ((uint)(b & 127) << 7);
            if (b < 128)
            {
                goto done;
            }
            if (offset >= limit)
            {
                goto error;
            }
            b = buf[offset];
            offset++;
            result |= ((uint)(b & 127) << 14);
            if (b < 128)
            {
                goto done;
            }
            if (offset >= limit)
            {
                goto error;
            }
            b = buf[offset];
            offset++;
            result |= ((uint)(b & 127) << 21);
            if (b < 128)
            {
                goto done;
            }
            if (offset >= limit)
            {
                goto error;
            }
            b = buf[offset];
            offset++;
            result |= ((uint)(b & 127) << 28);
            if (b >= 16)
            {
                goto error;
            }
done:
            length = offset - compressedBytes.Offset;
            return((int)result);

error:
            length = 0;
            return(-1);
        }
예제 #7
0
        public static bool DecompressRaw(SnappyByteBuffer dstBuf, SnappyByteBuffer srcBuf)
        {
            var src = srcBuf.Buffer;
            var dst = dstBuf.Buffer;
            var s   = srcBuf.Offset;
            var d   = dstBuf.Offset;
            var sL  = srcBuf.Length;
            var dL  = dstBuf.Length;
            int len = 0;
            int o   = 0;

            while (sL > 0)
            {
                var b = src[s];
                s++;
                sL--;
                switch (b & 3)
                {
                case 0:
                    len = b >> 2;
                    if (len < 60)
                    {
                        len++;
                    }
                    else if (len == 60)
                    {
                        if (sL < 1)
                        {
                            return(false);
                        }
                        len = src[s] + 1;
                        s++;
                        sL--;
                    }
                    else if (len == 61)
                    {
                        if (sL < 2)
                        {
                            return(false);
                        }
                        len = src[s] + 0x100 * src[s + 1] + 1;
                        s  += 2;
                        sL -= 2;
                    }
                    else if (len == 62)
                    {
                        if (sL < 3)
                        {
                            return(false);
                        }
                        len = src[s] + 0x100 * src[s + 1] + 0x10000 * src[s + 2] + 1;
                        s  += 3;
                        sL -= 3;
                    }
                    else
                    {
                        if (sL < 4)
                        {
                            return(false);
                        }
                        len = src[s] + 0x100 * src[s + 1] + 0x10000 * src[s + 2] + 0x1000000 * src[s + 3] + 1;
                        s  += 3;
                        sL -= 3;
                    }

                    if (len <= 0)
                    {
                        return(false);
                    }
                    if (len > dL || len > sL)
                    {
                        return(false);
                    }
                    Array.Copy(src, s, dst, d, len);
                    s  += len;
                    d  += len;
                    sL -= len;
                    dL -= len;
                    continue;

                case 1:
                    if (sL < 1)
                    {
                        return(false);
                    }
                    len = 4 + ((b >> 2) & 7);
                    o   = (b & 0xe0) << 3 | src[s];
                    s++;
                    sL--;
                    break;

                case 2:
                    if (sL < 2)
                    {
                        return(false);
                    }
                    len = 1 + (b >> 2);
                    o   = src[s] + src[s + 1] * 0x100;
                    s  += 2;
                    sL -= 2;
                    break;

                case 3:
                    return(false);
                }

                var end = d + len;
                if (o > d || len > dL)
                {
                    return(false);
                }
                for (; d < end; d++)
                {
                    dst[d] = dst[d - o];
                }
                dL -= len;
            }

            return(dL == 0);
        }
        public static int Compress(SnappyByteBuffer dstBuf, SnappyByteBuffer srcBuf)
        {
            var src = srcBuf.Buffer;
            var dst = dstBuf.Buffer;
            var s   = srcBuf.Offset;
            var d   = dstBuf.Offset;
            var sL  = srcBuf.Length;
            var dL  = dstBuf.Length;

            if (dL < 5)
            {
                return(-1);
            }
            EmitLength(dst, ref d, ref dL, sL);
            if (sL <= 4)
            {
                if (!EmitLiteral(dst, ref d, ref dL, src, s, sL))
                {
                    return(-1);
                }
                return(d - dstBuf.Offset);
            }

            var shift     = 32 - 8;
            var tableSize = 1 << 8;

            while (tableSize < 1 << 14 && tableSize < sL)
            {
                shift--;
                tableSize *= 2;
            }

            var table = new int[tableSize];

            for (int i = 0; i < tableSize; i++)
            {
                table[i] = -1;
            }

            var lit = s;

            while (sL > 3)
            {
                var v = src[s] | ((uint)src[s + 1]) << 8 | ((uint)src[s + 2]) << 16 | ((uint)src[s + 3]) << 24;
nextfast:
                var h = (v * 0x1e35a7bd) >> shift;
                var t = table[h];
                table[h] = s;
                if (t < 0 || s - t >= MaxOffset || !Equal4(src, t, s))
                {
                    s++;
                    sL--;
                    if (sL > 3)
                    {
                        v = (v >> 8) | ((uint)src[s + 3]) << 24;
                        goto nextfast;
                    }
                    break;
                }

                if (lit != s)
                {
                    if (!EmitLiteral(dst, ref d, ref dL, src, lit, s - lit))
                    {
                        return(-1);
                    }
                }

                var s0 = s;
                s  += 4;
                sL -= 4;
                t  += 4;
                while (sL > 0 && src[s] == src[t])
                {
                    s++;
                    sL--;
                    t++;
                }

                if (!EmitCopy(dst, ref d, ref dL, s - t, s - s0))
                {
                    return(-1);
                }
                lit = s;
            }

            s += sL;
            if (lit != s)
            {
                if (!EmitLiteral(dst, ref d, ref dL, src, lit, s - lit))
                {
                    return(-1);
                }
            }

            return(d - dstBuf.Offset);
        }