/// <inheritdoc /> public int Encode(byte *target, int length, bool allowCopy) { ThrowIfDisposed(); var sourceLength = _inputPointer - _inputIndex; if (sourceLength <= 0) { return(0); } var encoded = EncodeBlock(_inputBuffer + _inputIndex, sourceLength, target, length); if (encoded <= 0) { throw new InvalidOperationException( "Failed to encode chunk. Target buffer too small."); } if (allowCopy && encoded >= sourceLength) { Mem.Move(target, _inputBuffer + _inputIndex, sourceLength); encoded = -sourceLength; } Commit(); return(encoded); }
/// <inheritdoc /> public int Inject(byte *source, int length) { if (length <= 0) { return(0); } if (length > Math.Max(_blockSize, Mem.K64)) { throw new InvalidOperationException(); } if (_outputIndex + length < _outputLength) { Mem.Move(_outputBuffer + _outputIndex, source, length); _outputIndex = ApplyDict(_outputIndex + length); } else if (length >= Mem.K64) { Mem.Move(_outputBuffer, source, length); _outputIndex = ApplyDict(length); } else { var tailSize = Math.Min(Mem.K64 - length, _outputIndex); Mem.Move(_outputBuffer, _outputBuffer + _outputIndex - tailSize, tailSize); Mem.Move(_outputBuffer + tailSize, source, length); _outputIndex = ApplyDict(tailSize + length); } return(length); }
private int CopyDict(int index) { var dictStart = Math.Max(index - Mem.K64, 0); var dictSize = index - dictStart; Mem.Move(_outputBuffer, _outputBuffer + dictStart, dictSize); LZ4_xx.LZ4_setStreamDecode(_context, _outputBuffer, dictSize); return(dictSize); }
/// <inheritdoc /> public void Drain(byte *target, int offset, int length) { offset = _outputIndex + offset; // NOTE: negative value if (offset < 0 || length < 0 || offset + length > _outputIndex) { throw new InvalidOperationException(); } Mem.Move(target, _outputBuffer + offset, length); }
/// <inheritdoc /> public int Inject(byte *source, int length) { ThrowIfDisposed(); if (length <= 0) { return(_outputIndex = 0); } if (length > _outputLength) { throw new InvalidOperationException(); } Mem.Move(_outputBuffer, source, length); _outputIndex = length; return(length); }
public static int LZ4_saveDict(LZ4_stream_t *dict, byte *safeBuffer, int dictSize) { var previousDictEnd = dict->dictionary + dict->dictSize; if ((uint)dictSize > 64 * KB) { dictSize = 64 * KB; } if ((uint)dictSize > dict->dictSize) { dictSize = (int)dict->dictSize; } Mem.Move(safeBuffer, previousDictEnd - dictSize, dictSize); dict->dictionary = safeBuffer; dict->dictSize = (uint)dictSize; return(dictSize); }
/// <inheritdoc /> public int Topup(byte *source, int length) { ThrowIfDisposed(); if (length == 0) { return(0); } var spaceLeft = _inputIndex + _blockSize - _inputPointer; if (spaceLeft <= 0) { return(0); } var chunk = Math.Min(spaceLeft, length); Mem.Move(_inputBuffer + _inputPointer, source, chunk); _inputPointer += chunk; return(chunk); }
public static int LZ4_decompress_generic( byte *src, byte *dst, int srcSize, int outputSize, endCondition_directive endOnInput, earlyEnd_directive partialDecoding, int targetOutputSize, dict_directive dict, byte *lowPrefix, byte *dictStart, int dictSize) { var ip = src; var iend = ip + srcSize; var op = dst; var oend = op + outputSize; var oexit = op + targetOutputSize; var dictEnd = dictStart + dictSize; var safeDecode = endOnInput == endCondition_directive.endOnInputSize; var checkOffset = safeDecode && dictSize < 64 * KB; if (partialDecoding != earlyEnd_directive.full && oexit > oend - MFLIMIT) { oexit = oend - MFLIMIT; } if (endOnInput == endCondition_directive.endOnInputSize && outputSize == 0) { return(srcSize == 1 && *ip == 0 ? 0 : -1); } if (endOnInput != endCondition_directive.endOnInputSize && outputSize == 0) { return(*ip == 0 ? 1 : -1); } for (; ;) { int length; uint token = *ip++; if (ip + 14 + 2 <= iend && op + 14 + 18 <= oend && token < 15 << ML_BITS && (token & ML_MASK) != 15) { var ll = (int)(token >> ML_BITS); int off = Mem.Peek16(ip + ll); var matchPtr = op + ll - off; if (off >= 18 && matchPtr >= lowPrefix) { var ml = (int)((token & ML_MASK) + MINMATCH); Mem.Copy16(op, ip); op += ll; ip += ll + 2; Mem.Copy18(op, matchPtr); op += ml; continue; } } if ((length = (int)(token >> ML_BITS)) == RUN_MASK) { uint s; do { s = *ip++; length += (int)s; }while ( (endOnInput != endCondition_directive.endOnInputSize || ip < iend - RUN_MASK) && s == 255); if (safeDecode && op + length < op) { goto _output_error; } if (safeDecode && ip + length < ip) { goto _output_error; } } var cpy = op + length; if (endOnInput == endCondition_directive.endOnInputSize && ( cpy > (partialDecoding == earlyEnd_directive.partial ? oexit : oend - MFLIMIT) || ip + length > iend - (2 + 1 + LASTLITERALS) ) || endOnInput != endCondition_directive.endOnInputSize && cpy > oend - WILDCOPYLENGTH) { if (partialDecoding == earlyEnd_directive.partial) { if (cpy > oend) { goto _output_error; } if (endOnInput == endCondition_directive.endOnInputSize && ip + length > iend) { goto _output_error; } } else { if (endOnInput != endCondition_directive.endOnInputSize && cpy != oend) { goto _output_error; } if (endOnInput == endCondition_directive.endOnInputSize && (ip + length != iend || cpy > oend)) { goto _output_error; } } Mem.Copy(op, ip, length); ip += length; op += length; break; } Mem.WildCopy(op, ip, cpy); ip += length; op = cpy; int offset = Mem.Peek16(ip); ip += 2; var match = op - offset; if (checkOffset && match + dictSize < lowPrefix) { goto _output_error; } Mem.Poke32(op, (uint)offset); length = (int)(token & ML_MASK); if (length == ML_MASK) { uint s; do { s = *ip++; if ((endOnInput == endCondition_directive.endOnInputSize) && (ip > iend - LASTLITERALS)) { goto _output_error; } length += (int)s; }while (s == 255); if (safeDecode && op + length < op) { goto _output_error; } } length += MINMATCH; if (dict == dict_directive.usingExtDict && match < lowPrefix) { if (op + length > oend - LASTLITERALS) { goto _output_error; } if (length <= lowPrefix - match) { Mem.Move(op, dictEnd - (lowPrefix - match), length); op += length; } else { var copySize = (int)(lowPrefix - match); var restSize = length - copySize; Mem.Copy(op, dictEnd - copySize, copySize); op += copySize; if (restSize > (int)(op - lowPrefix)) { var endOfMatch = op + restSize; var copyFrom = lowPrefix; while (op < endOfMatch) { *op++ = *copyFrom++; } } else { Mem.Copy(op, lowPrefix, restSize); op += restSize; } } continue; } cpy = op + length; if (offset < 8) { op[0] = match[0]; op[1] = match[1]; op[2] = match[2]; op[3] = match[3]; match += inc32table[offset]; Mem.Copy(op + 4, match, 4); match -= dec64table[offset]; } else { Mem.Copy8(op, match); match += 8; } op += 8; if (cpy > oend - 12) { var oCopyLimit = oend - (WILDCOPYLENGTH - 1); if (cpy > oend - LASTLITERALS) { goto _output_error; } if (op < oCopyLimit) { Mem.WildCopy(op, match, oCopyLimit); match += oCopyLimit - op; op = oCopyLimit; } while (op < cpy) { *op++ = *match++; } } else { Mem.Copy8(op, match); if (length > 16) { Mem.WildCopy(op + 8, match + 8, cpy); } } op = cpy; /* correction */ } /* end of decoding */ if (endOnInput == endCondition_directive.endOnInputSize) { return((int)(op - dst)); /* Nb of output bytes decoded */ } return((int)(ip - src)); /* Nb of input bytes read */ /* Overflow error detected */ _output_error: return((int)-(ip - src) - 1); }