execute will execute the decoded sequence with the provided history. The sequence must be evaluated before being sent.
(seqs []seqVals, hist []byte)
| 117 | // execute will execute the decoded sequence with the provided history. |
| 118 | // The sequence must be evaluated before being sent. |
| 119 | func (s *sequenceDecs) execute(seqs []seqVals, hist []byte) error { |
| 120 | if len(s.dict) == 0 { |
| 121 | return s.executeSimple(seqs, hist) |
| 122 | } |
| 123 | |
| 124 | // Ensure we have enough output size... |
| 125 | if len(s.out)+s.seqSize > cap(s.out) { |
| 126 | addBytes := s.seqSize + len(s.out) |
| 127 | s.out = append(s.out, make([]byte, addBytes)...) |
| 128 | s.out = s.out[:len(s.out)-addBytes] |
| 129 | } |
| 130 | |
| 131 | if debugDecoder { |
| 132 | printf("Execute %d seqs with hist %d, dict %d, literals: %d into %d bytes\n", len(seqs), len(hist), len(s.dict), len(s.literals), s.seqSize) |
| 133 | } |
| 134 | |
| 135 | var t = len(s.out) |
| 136 | out := s.out[:t+s.seqSize] |
| 137 | |
| 138 | for _, seq := range seqs { |
| 139 | // Add literals |
| 140 | copy(out[t:], s.literals[:seq.ll]) |
| 141 | t += seq.ll |
| 142 | s.literals = s.literals[seq.ll:] |
| 143 | |
| 144 | // Copy from dictionary... |
| 145 | if seq.mo > t+len(hist) || seq.mo > s.windowSize { |
| 146 | if len(s.dict) == 0 { |
| 147 | return fmt.Errorf("match offset (%d) bigger than current history (%d)", seq.mo, t+len(hist)) |
| 148 | } |
| 149 | |
| 150 | // we may be in dictionary. |
| 151 | dictO := len(s.dict) - (seq.mo - (t + len(hist))) |
| 152 | if dictO < 0 || dictO >= len(s.dict) { |
| 153 | return fmt.Errorf("match offset (%d) bigger than current history+dict (%d)", seq.mo, t+len(hist)+len(s.dict)) |
| 154 | } |
| 155 | end := dictO + seq.ml |
| 156 | if end > len(s.dict) { |
| 157 | n := len(s.dict) - dictO |
| 158 | copy(out[t:], s.dict[dictO:]) |
| 159 | t += n |
| 160 | seq.ml -= n |
| 161 | } else { |
| 162 | copy(out[t:], s.dict[dictO:end]) |
| 163 | t += end - dictO |
| 164 | continue |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | // Copy from history. |
| 169 | if v := seq.mo - t; v > 0 { |
| 170 | // v is the start position in history from end. |
| 171 | start := len(hist) - v |
| 172 | if seq.ml > v { |
| 173 | // Some goes into current block. |
| 174 | // Copy remainder of history |
| 175 | copy(out[t:], hist[start:]) |
| 176 | t += v |