private void DecompressAllTags() { Pointer ip = _ip; // We could have put this refill fragment only at the beginning of the loop. // However, duplicating it at the end of each branch gives the compiler more // scope to optimize the <ip_limit_ - ip> expression based on the local // context, which overall increases speed. Func <bool> maybeRefill = () => { if (_ipLimit - ip < 5) { _ip = ip; if (!RefillTag()) { return(false); } ip = _ip; } return(true); }; if (!maybeRefill()) { return; } for (; ;) { byte c = ip[0]; ip = ip + 1; if ((c & 0x3) == CompressorTag.Literal) { int literalLength = ((c >> 2) + 1); if (_output.TryFastAppend(ip, _ipLimit - ip, literalLength)) { Debug.Assert(literalLength < 61); ip += literalLength; if (!maybeRefill()) { return; } continue; } if (literalLength >= 61) { int longLiteral = literalLength - 60; literalLength = (int)((ip.ToUInt32() & Wordmask[longLiteral]) + 1); ip += longLiteral; } int avail = _ipLimit - ip; while (avail < literalLength) { if (!_output.Append(ip, avail)) { return; } literalLength -= avail; Skip(_peeked); int n; ip = Peek(out n); avail = n; _peeked = avail; if (avail == 0) { return; // Premature end of input } _ipLimit = ip + avail; } if (!_output.Append(ip, literalLength)) { return; } ip += literalLength; if (!maybeRefill()) { return; } } else { int entry = CharTable[c]; int trailer = (int)(ip.ToUInt32() & Wordmask[entry >> 11]); int length = entry & 0xff; ip += entry >> 11; // copy_offset/256 is encoded in bits 8..10. By just fetching // those bits, we get copy_offset (since the bit-field starts at // bit 8). int copyOffset = entry & 0x700; if (!_output.AppendFromSelf(copyOffset + trailer, length)) { return; } if (!maybeRefill()) { return; } } } }
private void Skip(int peeked) { _ip += peeked; }