Exemplo n.º 1
0
        public void ResetStartPosition()
        {
            if (StartPosition == Constants.FixedSizeTree.PageHeaderSize)
            {
                return;
            }

            // we need to move it back, then add the new item
            UnmanagedMemory.Move(Pointer + Constants.FixedSizeTree.PageHeaderSize,
                                 Pointer + StartPosition,
                                 NumberOfEntries * (IsLeaf ? _entrySize : FixedSizeTree.BranchEntrySize));

            StartPosition = Constants.FixedSizeTree.PageHeaderSize;
        }
Exemplo n.º 2
0
        private void UnlikelyEnsureSingleChunk(out byte *ptr, out int size)
        {
            // we are using multiple segments, but the current one can fit all
            // the required memory
            if (_head.Allocation.SizeInBytes - _head.Used > SizeInBytes)
            {
                CopyTo(_head.Address + _head.Used);
                // we need to fit in the beginning of the chunk, so we must move it backward.
                UnmanagedMemory.Move(_head.Address, _head.Address + _head.Used, SizeInBytes);

                ptr        = _head.Address;
                size       = SizeInBytes;
                _head.Used = SizeInBytes;
                // Ensure we are thought of as a single chunk
                _head.Previous = null;
                return;
            }

            var totalSize = SizeInBytes;

            // We might need to allocate, but we don't want to allocate the usual power of 2 * 3
            // because we know _exactly_ what we need
            using (_context.AvoidOverAllocation())
            {
                // If we are here, then we have multiple chunks, we can't
                // allow a growth of the last chunk, since we'll by copying over it
                // so we force a whole new chunk
                AllocateNextSegment(totalSize, false);
            }

            // Go back in time to before we had the last chunk
            var realHead = _head;

            _head = realHead.Previous;

            // Copy all of the data structure into the new chunk's memory
            CopyTo(realHead.Address);
            realHead.Used = totalSize;
            realHead.AccumulatedSizeInBytes = totalSize;

            // Back to the future!
            _head = realHead;

            // Ensure we are thought of as a single chunk
            _head.Previous = null;

            ptr  = _head.Address;
            size = _head.Used;
        }
Exemplo n.º 3
0
        public void RemoveEntry(int pos)
        {
            System.Diagnostics.Debug.Assert(pos >= 0 && pos < NumberOfEntries);
            NumberOfEntries--;

            var size = (ushort)_entrySize;

            if (pos == 0)
            {
                // optimized, just move the start position
                StartPosition += size;
                return;
            }
            // have to move the memory
            UnmanagedMemory.Move(Pointer + StartPosition + (pos * size),
                                 Pointer + StartPosition + ((pos + 1) * size),
                                 (NumberOfEntries - pos) * size);
        }
Exemplo n.º 4
0
        private static int LZ4_decompress_generic <TEndCondition, TEarlyEnd, TDictionaryType>(byte *source, byte *dest, int inputSize, int outputSize, int targetOutputSize, byte *lowPrefix, byte *dictStart, int dictSize)
            where TEndCondition : IEndConditionDirective
            where TEarlyEnd : IEarlyEndDirective
            where TDictionaryType : IDictionaryTypeDirective
        {
            /* Local Variables */
            byte *ip   = source;
            byte *iend = ip + inputSize;

            byte *op   = dest;
            byte *oend = op + outputSize;

            byte *oexit    = op + targetOutputSize;
            byte *lowLimit = lowPrefix - dictSize;

            byte *dictEnd = dictStart + dictSize;

            bool checkOffset = ((typeof(TEndCondition) == typeof(EndOnInputSize)) && (dictSize < 64 * Constants.Size.Kilobyte));

            // Special Cases
            if ((typeof(TEarlyEnd) == typeof(Partial)) && (oexit > oend - MFLIMIT))
            {
                oexit = oend - MFLIMIT;                                                                                              // targetOutputSize too high => decode everything
            }
            if ((typeof(TEndCondition) == typeof(EndOnInputSize)) && (outputSize == 0))
            {
                return(((inputSize == 1) && (*ip == 0)) ? 0 : -1);  // Empty output buffer
            }
            if ((typeof(TEndCondition) == typeof(EndOnOutputSize)) && (outputSize == 0))
            {
                return(*ip == 0 ? 1 : -1);
            }

            // Main Loop
            while (true)
            {
                int length;

                /* get literal length */
                byte token = *ip++;
                if ((length = (token >> ML_BITS)) == RUN_MASK)
                {
                    byte s;
                    do
                    {
                        s       = *ip++;
                        length += s;
                    }while (((typeof(TEndCondition) == typeof(EndOnInputSize)) ? ip < iend - RUN_MASK : true) && (s == 255));

                    if ((typeof(TEndCondition) == typeof(EndOnInputSize)) && (op + length) < op)
                    {
                        goto _output_error;                                                                            /* overflow detection */
                    }
                    if ((typeof(TEndCondition) == typeof(EndOnInputSize)) && (ip + length) < ip)
                    {
                        goto _output_error;                                                                            /* overflow detection */
                    }
                }

                // copy literals
                byte *cpy = op + length;
                if (((typeof(TEndCondition) == typeof(EndOnInputSize)) && ((cpy > (typeof(TEarlyEnd) == typeof(Partial) ? oexit : oend - MFLIMIT)) || (ip + length > iend - (2 + 1 + LASTLITERALS)))) ||
                    ((typeof(TEndCondition) == typeof(EndOnOutputSize)) && (cpy > oend - COPYLENGTH)))
                {
                    if (typeof(TEarlyEnd) == typeof(Partial))
                    {
                        if (cpy > oend)
                        {
                            goto _output_error;                           /* Error : write attempt beyond end of output buffer */
                        }
                        if ((typeof(TEndCondition) == typeof(EndOnInputSize)) && (ip + length > iend))
                        {
                            goto _output_error;   /* Error : read attempt beyond end of input buffer */
                        }
                    }
                    else
                    {
                        if ((typeof(TEndCondition) == typeof(EndOnOutputSize)) && (cpy != oend))
                        {
                            goto _output_error;       /* Error : block decoding must stop exactly there */
                        }
                        if ((typeof(TEndCondition) == typeof(EndOnInputSize)) && ((ip + length != iend) || (cpy > oend)))
                        {
                            goto _output_error;   /* Error : input must be consumed */
                        }
                    }

                    Unsafe.CopyBlock(op, ip, (uint)length);
                    ip += length;
                    op += length;
                    break;     /* Necessarily EOF, due to parsing restrictions */
                }

                WildCopy(op, ip, cpy);
                ip += length; op = cpy;

                /* get offset */
                byte *match = cpy - *((ushort *)ip); ip += sizeof(ushort);
                if ((checkOffset) && (match < lowLimit))
                {
                    goto _output_error;   /* Error : offset outside destination buffer */
                }
                /* get matchlength */
                if ((length = (token & ML_MASK)) == ML_MASK)
                {
                    byte s;
                    do
                    {
                        if ((typeof(TEndCondition) == typeof(EndOnInputSize)) && (ip > iend - LASTLITERALS))
                        {
                            goto _output_error;
                        }

                        s       = *ip++;
                        length += s;
                    }while (s == 255);

                    if ((typeof(TEndCondition) == typeof(EndOnInputSize)) && (op + length) < op)
                    {
                        goto _output_error;   /* overflow detection */
                    }
                }

                length += MINMATCH;

                /* check external dictionary */
                if ((typeof(TDictionaryType) == typeof(UsingExtDict)) && (match < lowPrefix))
                {
                    if (op + length > oend - LASTLITERALS)
                    {
                        goto _output_error;   /* doesn't respect parsing restriction */
                    }
                    if (length <= (int)(lowPrefix - match))
                    {
                        /* match can be copied as a single segment from external dictionary */
                        match = dictEnd - (lowPrefix - match);
                        UnmanagedMemory.Move(op, match, length);
                        op += length;
                    }
                    else
                    {
                        /* match encompass external dictionary and current segment */
                        int copySize = (int)(lowPrefix - match);
                        Unsafe.CopyBlock(op, dictEnd - copySize, (uint)copySize);
                        op += copySize;

                        copySize = length - copySize;
                        if (copySize > (int)(op - lowPrefix))   /* overlap within current segment */
                        {
                            byte *endOfMatch = op + copySize;
                            byte *copyFrom   = lowPrefix;
                            while (op < endOfMatch)
                            {
                                *op++ = *copyFrom++;
                            }
                        }
                        else
                        {
                            Unsafe.CopyBlock(op, lowPrefix, (uint)copySize);
                            op += copySize;
                        }
                    }
                    continue;
                }

                /* copy repeated sequence */
                cpy = op + length;
                if ((op - match) < 8)
                {
                    int dec64 = dec64table[op - match];
                    op[0] = match[0];
                    op[1] = match[1];
                    op[2] = match[2];
                    op[3] = match[3];

                    match += dec32table[op - match];
                    *((uint *)(op + 4)) = *(uint *)match;
                    op    += 8;
                    match -= dec64;
                }
                else
                {
                    *((ulong *)op) = *(ulong *)match;
                    op            += sizeof(ulong);
                    match         += sizeof(ulong);
                }

                if (cpy > oend - 12)
                {
                    if (cpy > oend - LASTLITERALS)
                    {
                        goto _output_error;    /* Error : last LASTLITERALS bytes must be literals */
                    }
                    if (op < oend - 8)
                    {
                        WildCopy(op, match, (oend - 8));
                        match += (oend - 8) - op;
                        op     = oend - 8;
                    }

                    while (op < cpy)
                    {
                        *op++ = *match++;
                    }
                }
                else
                {
                    WildCopy(op, match, cpy);
                }

                op = cpy;   /* correction */
            }

            /* end of decoding */
            if (typeof(TEndCondition) == typeof(EndOnInputSize))
            {
                return((int)(op - dest));     /* Nb of output bytes decoded */
            }
            else
            {
                return((int)(ip - source));   /* Nb of input bytes read */
            }
            /* Overflow error detected */
_output_error:
            return((int)(-(ip - source)) - 1);
        }