private State YieldTagBit(OutputInfo oi) { if (CanTakeByte(oi)) { if (_match.Length == 0) { AddTagBit(oi, HeatshrinkLiteralMarker); return(State.HsesYieldLiteral); } AddTagBit(oi, HeatshrinkBackrefMarker); _outgoingBits = _match.Pos - 1; _outgoingBitsCount = _windowSize; return(State.HsesYieldBrIndex); } return(State.HsesYieldTagBit); /* output is full, continue */ }
private State FlushBitBuffer(OutputInfo oi) { if (_bitIndex == 0x80) { return(State.HsesDone); } else if (CanTakeByte(oi)) { oi.Buf[oi.OutputSize++] = (byte)_currentByte; return(State.HsesDone); } else { return(State.HsesFlushBits); } }
private State YieldBackRefIndex(OutputInfo oi) { if (CanTakeByte(oi)) { if (push_outgoing_bits(oi) > 0) { return(State.HsesYieldBrIndex); /* continue */ } else { _outgoingBits = _match.Length - 1; _outgoingBitsCount = _lookAhead; return(State.HsesYieldBrLength); /* done */ } } else { return(State.HsesYieldBrIndex); /* continue */ } }
private State YieldBackRefLength(OutputInfo oi) { if (CanTakeByte(oi)) { if (push_outgoing_bits(oi) > 0) { return(State.HsesYieldBrLength); } else { _match.ScanIndex += _match.Length; _match.Length = 0; return(State.HsesSearch); } } else { return(State.HsesYieldBrLength); } }
private int push_outgoing_bits(OutputInfo oi) { int count; byte bits; if (_outgoingBitsCount > 8) { count = 8; bits = (byte)(_outgoingBits >> (_outgoingBitsCount - 8)); } else { count = _outgoingBitsCount; bits = (byte)_outgoingBits; } if (count > 0) { PushBits(count, bits, oi); _outgoingBitsCount -= count; } return(count); }
private void AddTagBit(OutputInfo oi, byte tag) { PushBits(1, tag, oi); }
private bool CanTakeByte(OutputInfo oi) { return(oi.OutputSize < oi.BufSize); }
/// <summary> /// Poll for output from the encoder, copying at most OUT_BUF_SIZE bytes into /// OUT_BUF (setting *OUTPUT_SIZE to the actual amount copied). /// </summary> /// <param name="outBuf"></param> /// <returns></returns> public Result Poll(byte[] outBuf /* size_t *output_size */) { if (outBuf == null) { throw new ArgumentException("outBuf must not be null"); } var outBufSize = outBuf.Length; if (outBufSize == 0) { throw new ArgumentException("outBuf length must not be null"); } var oi = new OutputInfo { Buf = outBuf, BufSize = outBuf.Length, OutputSize = 0 }; while (true) { var inState = _state; switch (inState) { case State.HsesNotFull: return(Result.res(oi.OutputSize, Code.Empty)); case State.HsesFilled: DoIndexing(); _state = State.HsesSearch; break; case State.HsesSearch: _state = StepSearch(); break; case State.HsesYieldTagBit: _state = YieldTagBit(oi); break; case State.HsesYieldLiteral: _state = YieldLiteral(oi); break; case State.HsesYieldBrIndex: _state = YieldBackRefIndex(oi); break; case State.HsesYieldBrLength: _state = YieldBackRefLength(oi); break; case State.HsesSaveBacklog: _state = SaveBacklog(); break; case State.HsesFlushBits: _state = FlushBitBuffer(oi); return(Result.res(oi.OutputSize, Code.Empty)); case State.HsesDone: return(Result.res(oi.OutputSize, Code.Empty)); default: return(Result.res(oi.OutputSize, Code.ErrorMisuse)); } if (_state == inState) { /* Check if output buffer is exhausted. */ if (oi.OutputSize == outBufSize) { return(Result.res(oi.OutputSize, Code.More)); } } } // return new PollRes(output_size, PollRes.Res.EMPTY); }
private void PushByte(OutputInfo oi, byte c) { //log.Debug(" -- pushing byte: 0x%02x ('%c')", c, isPrint(c) ? c : '.'); oi.Buf[oi.OutputSize++] = c; }
/// <summary> /// poll decoded bytes into outBuffer. /// </summary> /// <param name="outBuffer">must not be null</param> /// <returns>count byte were polled</returns> public Result Poll(byte[] outBuffer /*, int offset , size_t *output_size*/) { if (outBuffer == null) { throw new ArgumentException("outbuffer must not be null"); } var outBufSize = outBuffer.Length; var oi = new OutputInfo { Buf = outBuffer, BufSize = outBufSize, OutputSize = 0 }; while (true) { var inState = _state; switch (inState) { case State.HsdsTagBit: _state = TagBit(); break; case State.HsdsYieldLiteral: _state = YieldLiteral(oi); break; case State.HsdsBackrefIndexMsb: _state = BackrefIndexMsb(); break; case State.HsdsBackrefIndexLsb: _state = BackrefIndexLsb(); break; case State.HsdsBackrefCountMsb: _state = BackrefCountMsb(); break; case State.HsdsBackrefCountLsb: _state = BackrefCountLsb(); break; case State.HsdsYieldBackref: _state = YieldBackref(oi); break; default: return(Result.res(Code.ErrorUnknown)); } /* If the current state cannot advance, check if input or output * buffer are exhausted. */ if (_state == inState) { if (oi.OutputSize == outBufSize) { return(Result.res(oi.OutputSize, Code.More)); } return(Result.res(oi.OutputSize, Code.Empty)); } } }