internal bool Code(int dictionarySize, OutWindow outWindow, RangeCoder.Decoder rangeDecoder) { int dictionarySizeCheck = Math.Max(dictionarySize, 1); outWindow.CopyPending(); while (outWindow.HasSpace) { uint posState = (uint)outWindow._total & _posStateMask; if (_isMatchDecoders[(_state._index << Base.K_NUM_POS_STATES_BITS_MAX) + posState].Decode(rangeDecoder) == 0) { byte b; byte prevByte = outWindow.GetByte(0); if (!_state.IsCharState()) { b = _literalDecoder.DecodeWithMatchByte(rangeDecoder, (uint)outWindow._total, prevByte, outWindow.GetByte((int)_rep0)); } else { b = _literalDecoder.DecodeNormal(rangeDecoder, (uint)outWindow._total, prevByte); } outWindow.PutByte(b); _state.UpdateChar(); } else { uint len; if (_isRepDecoders[_state._index].Decode(rangeDecoder) == 1) { if (_isRepG0Decoders[_state._index].Decode(rangeDecoder) == 0) { if ( _isRep0LongDecoders[(_state._index << Base.K_NUM_POS_STATES_BITS_MAX) + posState].Decode( rangeDecoder) == 0) { _state.UpdateShortRep(); outWindow.PutByte(outWindow.GetByte((int)_rep0)); continue; } } else { UInt32 distance; if (_isRepG1Decoders[_state._index].Decode(rangeDecoder) == 0) { distance = _rep1; } else { if (_isRepG2Decoders[_state._index].Decode(rangeDecoder) == 0) { distance = _rep2; } else { distance = _rep3; _rep3 = _rep2; } _rep2 = _rep1; } _rep1 = _rep0; _rep0 = distance; } len = _repLenDecoder.Decode(rangeDecoder, posState) + Base.K_MATCH_MIN_LEN; _state.UpdateRep(); } else { _rep3 = _rep2; _rep2 = _rep1; _rep1 = _rep0; len = Base.K_MATCH_MIN_LEN + _lenDecoder.Decode(rangeDecoder, posState); _state.UpdateMatch(); uint posSlot = _posSlotDecoder[Base.GetLenToPosState(len)].Decode(rangeDecoder); if (posSlot >= Base.K_START_POS_MODEL_INDEX) { int numDirectBits = (int)((posSlot >> 1) - 1); _rep0 = ((2 | (posSlot & 1)) << numDirectBits); if (posSlot < Base.K_END_POS_MODEL_INDEX) { _rep0 += BitTreeDecoder.ReverseDecode(_posDecoders, _rep0 - posSlot - 1, rangeDecoder, numDirectBits); } else { _rep0 += (rangeDecoder.DecodeDirectBits( numDirectBits - Base.K_NUM_ALIGN_BITS) << Base.K_NUM_ALIGN_BITS); _rep0 += _posAlignDecoder.ReverseDecode(rangeDecoder); } } else { _rep0 = posSlot; } } if (_rep0 >= outWindow._total || _rep0 >= dictionarySizeCheck) { if (_rep0 == 0xFFFFFFFF) { return(true); } throw new DataErrorException(); } outWindow.CopyBlock((int)_rep0, (int)len); } } return(false); }