Ejemplo n.º 1
0
        private static byte *LZ4_getPosition <TTableType>(byte *p, LZ4_stream_t_internal *ctx, byte *srcBase)
            where TTableType : ITableTypeDirective
        {
            int h = LZ4_hashPosition <TTableType>(p);

            return(LZ4_getPositionOnHash <TTableType>(h, ctx, srcBase));
        }
Ejemplo n.º 2
0
        private static void LZ4_putPosition <TTableType>(byte *p, LZ4_stream_t_internal *ctx, byte *srcBase)
            where TTableType : ITableTypeDirective
        {
            int h = LZ4_hashPosition <TTableType>(p);

            LZ4_putPositionOnHash <TTableType>(p, h, ctx, srcBase);
        }
Ejemplo n.º 3
0
 private static byte *LZ4_getPositionOnHash(uint h, LZ4_stream_t_internal *ctx, TableType tableType, byte *srcBase)
 {
     if (tableType == TableType.ByU32)
     {
         return(srcBase + ctx->hashTable[h]);
     }
     else
     {
         return(srcBase + ((ushort *)ctx->hashTable)[h]);
     }
 }
Ejemplo n.º 4
0
 private static void LZ4_putPositionOnHash(byte *p, uint h, LZ4_stream_t_internal *ctx, TableType tableType, byte *srcBase)
 {
     if (tableType == TableType.ByU32)
     {
         ctx->hashTable[h] = (uint)(p - srcBase);
     }
     else
     {
         ((ushort *)ctx->hashTable)[h] = (ushort)(p - srcBase);
     }
 }
Ejemplo n.º 5
0
        private static byte *LZ4_getPositionOnHash <TTableType>(int h, LZ4_stream_t_internal *ctx, byte *srcBase)
            where TTableType : ITableTypeDirective
        {
            if (typeof(TTableType) == typeof(ByU32))
            {
                return(srcBase + ctx->hashTable[h]);
            }
            else if (typeof(TTableType) == typeof(ByU16))
            {
                return(srcBase + ((ushort *)ctx->hashTable)[h]);
            }

            ThrowException(new NotSupportedException("TTableType directive is not supported."));
            return(default(byte *));
        }
Ejemplo n.º 6
0
 private static void LZ4_putPositionOnHash <TTableType>(byte *p, int h, LZ4_stream_t_internal *ctx, byte *srcBase)
     where TTableType : ITableTypeDirective
 {
     if (typeof(TTableType) == typeof(ByU32))
     {
         ctx->hashTable[h] = (int)(p - srcBase);
     }
     else if (typeof(TTableType) == typeof(ByU16))
     {
         ((ushort *)ctx->hashTable)[h] = (ushort)(p - srcBase);
     }
     else
     {
         ThrowException(new NotSupportedException("TTableType directive is not supported."));
     }
 }
Ejemplo n.º 7
0
        private static int LZ4_compress_generic <TLimited, TTableType, TDictionaryType, TDictionaryIssue>(LZ4_stream_t_internal *dictPtr, byte *source, byte *dest, int inputSize, int maxOutputSize, int acceleration)
            where TLimited : ILimitedOutputDirective
            where TTableType : ITableTypeDirective
            where TDictionaryType : IDictionaryTypeDirective
            where TDictionaryIssue : IDictionaryIssueDirective
        {
            LZ4_stream_t_internal *ctx = dictPtr;

            byte *op     = dest;
            byte *ip     = source;
            byte *anchor = source;

            byte *dictionary  = ctx->dictionary;
            byte *dictEnd     = dictionary + ctx->dictSize;
            byte *lowRefLimit = ip - ctx->dictSize;

            long dictDelta = (long)dictEnd - (long)source;

            byte *iend       = ip + inputSize;
            byte *mflimit    = iend - MFLIMIT;
            byte *matchlimit = iend - LASTLITERALS;

            byte *olimit = op + maxOutputSize;

            // Init conditions
            if (inputSize > LZ4_MAX_INPUT_SIZE)
            {
                return(0);                                  // Unsupported input size, too large (or negative)
            }
            byte * @base;
            byte * lowLimit;

            if (typeof(TDictionaryType) == typeof(NoDict))
            {
                @base    = source;
                lowLimit = source;
            }
            else if (typeof(TDictionaryType) == typeof(WithPrefix64K))
            {
                @base    = source - ctx->currentOffset;
                lowLimit = source - ctx->dictSize;
            }
            else if (typeof(TDictionaryType) == typeof(UsingExtDict))
            {
                @base    = source - ctx->currentOffset;
                lowLimit = source;
            }
            else
            {
                throw new NotSupportedException("Unsupported IDictionaryTypeDirective.");
            }

            if ((typeof(TTableType) == typeof(ByU16)) && (inputSize >= LZ4_64Klimit)) // Size too large (not within 64K limit)
            {
                return(0);
            }

            if (inputSize < LZ4_minLength) // Input too small, no compression (all literals)
            {
                goto _last_literals;
            }

            // First Byte
            LZ4_putPosition <TTableType>(ip, ctx, @base);
            ip++;
            int forwardH = LZ4_hashPosition <TTableType>(ip);

            // Main Loop
            long refDelta = 0;

            for (;;)
            {
                byte *match;
                {
                    byte *forwardIp = ip;

                    int step          = 1;
                    int searchMatchNb = acceleration << LZ4_skipTrigger;

                    do
                    {
                        int h = forwardH;
                        ip         = forwardIp;
                        forwardIp += step;
                        step       = (searchMatchNb++ >> LZ4_skipTrigger);

                        if (forwardIp > mflimit)
                        {
                            goto _last_literals;
                        }

                        match = LZ4_getPositionOnHash <TTableType>(h, ctx, @base);
                        if (typeof(TDictionaryType) == typeof(UsingExtDict))
                        {
                            if (match < source)
                            {
                                refDelta = dictDelta;
                                lowLimit = dictionary;
                            }
                            else
                            {
                                refDelta = 0;
                                lowLimit = source;
                            }
                        }

                        if (typeof(TTableType) == typeof(ByU16))
                        {
                            ulong value = *((ulong *)forwardIp) * prime5bytes >> (40 - ByU16HashLog);
                            forwardH = (int)(value & ByU16HashMask);
                            ((ushort *)ctx->hashTable)[h] = (ushort)(ip - @base);
                        }
                        else if (typeof(TTableType) == typeof(ByU32))
                        {
                            ulong value = (*((ulong *)forwardIp) * prime5bytes >> (40 - ByU32HashLog));
                            forwardH          = (int)(value & ByU32HashMask);
                            ctx->hashTable[h] = (int)(ip - @base);
                        }
                        else
                        {
                            throw new NotSupportedException("TTableType directive is not supported.");
                        }
                    }while (((typeof(TDictionaryType) == typeof(DictSmall)) ? (match < lowRefLimit) : false) ||
                            ((typeof(TTableType) == typeof(ByU16)) ? false : (match + MAX_DISTANCE < ip)) ||
                            (*(uint *)(match + refDelta) != *((uint *)ip)));
                }

                // Catch up
                while ((ip > anchor) && (match + refDelta > lowLimit) && (ip[-1] == match[refDelta - 1]))
                {
                    ip--;
                    match--;
                }


                // Encode Literal length
                byte *token;
                {
                    int litLength = (int)(ip - anchor);
                    token = op++;

                    if ((typeof(TLimited) == typeof(LimitedOutput)) && (op + litLength + (2 + 1 + LASTLITERALS) + (litLength / 255) > olimit))
                    {
                        return(0);   /* Check output limit */
                    }
                    if (litLength >= RUN_MASK)
                    {
                        int len   = litLength - RUN_MASK;
                        *   token = RUN_MASK << ML_BITS;

                        for (; len >= 255; len -= 255)
                        {
                            *op++ = 255;
                        }

                        *op++ = (byte)len;
                    }
                    else
                    {
                        *token = (byte)(litLength << ML_BITS);
                    }

                    /* Copy Literals */
                    WildCopy(op, anchor, (op + litLength));
                    op += litLength;
                }

_next_match:

                // Encode Offset
                *((ushort *)op) = (ushort)(ip - match);
                op += sizeof(ushort);

                // Encode MatchLength
                {
                    int matchLength;

                    if ((typeof(TDictionaryType) == typeof(UsingExtDict)) && (lowLimit == dictionary))
                    {
                        match += refDelta;

                        byte *limit = ip + (dictEnd - match);
                        if (limit > matchlimit)
                        {
                            limit = matchlimit;
                        }
                        matchLength = LZ4_count(ip + MINMATCH, match + MINMATCH, limit);
                        ip         += MINMATCH + matchLength;
                        if (ip == limit)
                        {
                            int more = LZ4_count(ip, source, matchlimit);
                            matchLength += more;
                            ip          += more;
                        }
                    }
                    else
                    {
                        matchLength = LZ4_count(ip + MINMATCH, match + MINMATCH, matchlimit);
                        ip         += MINMATCH + matchLength;
                    }

                    if ((typeof(TLimited) == typeof(LimitedOutput)) && ((op + (1 + LASTLITERALS) + (matchLength >> 8)) > olimit))
                    {
                        return(0);    /* Check output limit */
                    }
                    if (matchLength >= ML_MASK)
                    {
                        *token += ML_MASK;
                        matchLength -= ML_MASK;

                        for (; matchLength >= 510; matchLength -= 510)
                        {
                            *(ushort *)op = (255 << 8 | 255);
                            op           += sizeof(ushort);
                        }

                        if (matchLength >= 255)
                        {
                            matchLength -= 255;
                            *op++ = 255;
                        }

                        *op++ = (byte)matchLength;
                    }
                    else
                    {
                        *token += (byte)(matchLength);
                    }
                }


                anchor = ip;

                // Test end of chunk
                if (ip > mflimit)
                {
                    break;
                }

                // Fill table
                LZ4_putPosition <TTableType>(ip - 2, ctx, @base);

                /* Test next position */
                match = LZ4_getPosition <TTableType>(ip, ctx, @base);
                if (typeof(TDictionaryType) == typeof(UsingExtDict))
                {
                    if (match < source)
                    {
                        refDelta = dictDelta;
                        lowLimit = dictionary;
                    }
                    else
                    {
                        refDelta = 0;
                        lowLimit = source;
                    }
                }

                LZ4_putPosition <TTableType>(ip, ctx, @base);
                if (((typeof(TDictionaryType) == typeof(DictSmall)) ? (match >= lowRefLimit) : true) && (match + MAX_DISTANCE >= ip) && (*(uint *)(match + refDelta) == *(uint *)(ip)))
                {
                    token = op++; *token = 0;
                    goto _next_match;
                }

                /* Prepare next loop */
                forwardH = LZ4_hashPosition <TTableType>(++ip);
            }

_last_literals:

            /* Encode Last Literals */
            {
                int lastRun = (int)(iend - anchor);
                if ((typeof(TLimited) == typeof(LimitedOutput)) && ((op - dest) + lastRun + 1 + ((lastRun + 255 - RUN_MASK) / 255) > maxOutputSize))
                {
                    return(0);   // Check output limit;
                }
                if (lastRun >= RUN_MASK)
                {
                    int accumulator = lastRun - RUN_MASK;
                    *   op++        = RUN_MASK << ML_BITS;

                    for (; accumulator >= 255; accumulator -= 255)
                    {
                        *op++ = 255;
                    }

                    *op++ = (byte)accumulator;
                }
                else
                {
                    *op++ = (byte)(lastRun << ML_BITS);
                }

                Unsafe.CopyBlock(op, anchor, (uint)lastRun);
                op += lastRun;
            }

            return((int)(op - dest));
        }
Ejemplo n.º 8
0
        private static byte *LZ4_getPosition(byte *p, LZ4_stream_t_internal *ctx, TableType tableType, byte *srcBase)
        {
            uint h = LZ4_hashPosition(p, tableType);

            return(LZ4_getPositionOnHash(h, ctx, tableType, srcBase));
        }
Ejemplo n.º 9
0
        private static void LZ4_putPosition(byte *p, LZ4_stream_t_internal *ctx, TableType tableType, byte *srcBase)
        {
            uint h = LZ4_hashPosition(p, tableType);

            LZ4_putPositionOnHash(p, h, ctx, tableType, srcBase);
        }
Ejemplo n.º 10
0
        private static int LZ4_compress_generic(LZ4_stream_t_internal *dictPtr, byte *source, byte *dest, int inputSize, int maxOutputSize, LimitedOutput outputLimited, TableType tableType, DictionaryType dict, DictionaryIssue dictIssue, int acceleration)
        {
            byte *ip          = source;
            byte *lowRefLimit = ip - dictPtr->dictSize;
            byte *dictionary  = dictPtr->dictionary;
            byte *dictEnd     = dictionary + dictPtr->dictSize;

            long dictDelta = (long)dictEnd - (long)source;

            byte *anchor     = source;
            byte *iend       = ip + inputSize;
            byte *mflimit    = iend - MFLIMIT;
            byte *matchlimit = iend - LASTLITERALS;

            byte *op     = (byte *)dest;
            byte *olimit = op + maxOutputSize;

            uint forwardH;
            long refDelta = 0;

            // Init conditions
            if (inputSize > LZ4_MAX_INPUT_SIZE)
            {
                return(0);                                  // Unsupported input size, too large (or negative)
            }
            byte * @base;
            byte * lowLimit;

            switch (dict)
            {
            default:
            case DictionaryType.NoDict:
                @base    = source;
                lowLimit = source;
                break;

            case DictionaryType.WithPrefix64K:
                @base    = source - dictPtr->currentOffset;
                lowLimit = source - dictPtr->dictSize;
                break;

            case DictionaryType.UsingExtDict:
                @base    = source - dictPtr->currentOffset;
                lowLimit = source;
                break;
            }

            if ((tableType == TableType.ByU16) && (inputSize >= LZ4_64Klimit)) // Size too large (not within 64K limit)
            {
                return(0);
            }

            if (inputSize < LZ4_minLength) // Input too small, no compression (all literals)
            {
                goto _last_literals;
            }

            // First Byte
            LZ4_putPosition(ip, dictPtr, tableType, @base);
            ip++;
            forwardH = LZ4_hashPosition(ip, tableType);

            // Main Loop

            for (;;)
            {
                byte *match;
                {
                    byte *forwardIp = ip;

                    int step          = 1;
                    int searchMatchNb = acceleration << LZ4_skipTrigger;

                    do
                    {
                        uint h = forwardH;
                        ip         = forwardIp;
                        forwardIp += step;
                        step       = (searchMatchNb++ >> LZ4_skipTrigger);

                        if (forwardIp > mflimit)
                        {
                            goto _last_literals;
                        }

                        match = LZ4_getPositionOnHash(h, dictPtr, tableType, @base);
                        if (dict == DictionaryType.UsingExtDict)
                        {
                            if (match < source)
                            {
                                refDelta = dictDelta;
                                lowLimit = dictionary;
                            }
                            else
                            {
                                refDelta = 0;
                                lowLimit = source;
                            }
                        }

                        forwardH = LZ4_hashPosition(forwardIp, tableType);
                        LZ4_putPositionOnHash(ip, h, dictPtr, tableType, @base);
                    }while (((dictIssue == DictionaryIssue.DictSmall) ? (match < lowRefLimit) : false) ||
                            ((tableType == TableType.ByU16) ? false : (match + MAX_DISTANCE < ip)) ||
                            (*(uint *)(match + refDelta) != *((uint *)ip)));
                }

                // Catch up
                while ((ip > anchor) && (match + refDelta > lowLimit) && (ip[-1] == match[refDelta - 1]))
                {
                    ip--;
                    match--;
                }


                // Encode Literal length
                byte *token;
                {
                    int litLength = (int)(ip - anchor);
                    token = op++;

                    if ((outputLimited == LimitedOutput.LimitedOutput) && (op + litLength + (2 + 1 + LASTLITERALS) + (litLength / 255) > olimit))
                    {
                        return(0);   /* Check output limit */
                    }
                    if (litLength >= RUN_MASK)
                    {
                        int len   = litLength - RUN_MASK;
                        *   token = RUN_MASK << ML_BITS;

                        for (; len >= 255; len -= 255)
                        {
                            *op++ = 255;
                        }

                        *op++ = (byte)len;
                    }
                    else
                    {
                        *token = (byte)(litLength << ML_BITS);
                    }

                    /* Copy Literals */
                    WildCopy(op, anchor, op + litLength);
                    op += litLength;
                }

_next_match:

                // Encode Offset
                *((ushort *)op) = (ushort)(ip - match);
                op += sizeof(ushort);

                // Encode MatchLength
                {
                    int matchLength;

                    if ((dict == DictionaryType.UsingExtDict) && (lowLimit == dictionary))
                    {
                        match += refDelta;

                        byte *limit = ip + (dictEnd - match);
                        if (limit > matchlimit)
                        {
                            limit = matchlimit;
                        }
                        matchLength = LZ4_count(ip + MINMATCH, match + MINMATCH, limit);
                        ip         += MINMATCH + matchLength;
                        if (ip == limit)
                        {
                            int more = LZ4_count(ip, source, matchlimit);
                            matchLength += more;
                            ip          += more;
                        }
                    }
                    else
                    {
                        matchLength = LZ4_count(ip + MINMATCH, match + MINMATCH, matchlimit);
                        ip         += MINMATCH + matchLength;
                    }

                    if ((outputLimited == LimitedOutput.LimitedOutput) && ((op + (1 + LASTLITERALS) + (matchLength >> 8)) > olimit))
                    {
                        return(0);    /* Check output limit */
                    }
                    if (matchLength >= ML_MASK)
                    {
                        *token += ML_MASK;
                        matchLength -= ML_MASK;

                        for (; matchLength >= 510; matchLength -= 510)
                        {
                            *op++ = 255;
                            *op++ = 255;
                        }

                        if (matchLength >= 255)
                        {
                            matchLength -= 255;
                            *op++ = 255;
                        }

                        *op++ = (byte)matchLength;
                    }
                    else
                    {
                        *token += (byte)(matchLength);
                    }
                }


                anchor = ip;

                // Test end of chunk
                if (ip > mflimit)
                {
                    break;
                }

                // Fill table
                LZ4_putPosition(ip - 2, dictPtr, tableType, @base);

                /* Test next position */
                match = LZ4_getPosition(ip, dictPtr, tableType, @base);
                if (dict == DictionaryType.UsingExtDict)
                {
                    if (match < source)
                    {
                        refDelta = dictDelta;
                        lowLimit = dictionary;
                    }
                    else
                    {
                        refDelta = 0;
                        lowLimit = source;
                    }
                }

                LZ4_putPosition(ip, dictPtr, tableType, @base);
                if (((dictIssue == DictionaryIssue.DictSmall) ? (match >= lowRefLimit) : true) && (match + MAX_DISTANCE >= ip) && (*(uint *)(match + refDelta) == *(uint *)(ip)))
                {
                    token = op++; *token = 0;
                    goto _next_match;
                }

                /* Prepare next loop */
                forwardH = LZ4_hashPosition(++ip, tableType);
            }

_last_literals:

            /* Encode Last Literals */
            {
                int lastRun = (int)(iend - anchor);
                if ((outputLimited == LimitedOutput.LimitedOutput) && ((op - dest) + lastRun + 1 + ((lastRun + 255 - RUN_MASK) / 255) > maxOutputSize))
                {
                    return(0);   // Check output limit;
                }
                if (lastRun >= RUN_MASK)
                {
                    int accumulator = lastRun - RUN_MASK;
                    *   op++        = RUN_MASK << ML_BITS;

                    for (; accumulator >= 255; accumulator -= 255)
                    {
                        *op++ = 255;
                    }

                    *op++ = (byte)accumulator;
                }
                else
                {
                    *op++ = (byte)(lastRun << ML_BITS);
                }

                Unsafe.CopyBlock(op, anchor, (uint)lastRun);
                op += lastRun;
            }

            return((int)(op - dest));
        }