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; }
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; }
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); }
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); }