Index: src/0dev.org/bits/bits.go ================================================================== --- src/0dev.org/bits/bits.go +++ src/0dev.org/bits/bits.go @@ -3,11 +3,11 @@ import ( "strconv" ) -var hamming = [256]byte{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, +var hamming = [256]int{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, @@ -22,11 +22,11 @@ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, } // Returns the number of raised bits in the given byte -func Hamming(b byte) byte { +func Hamming(b byte) int { return hamming[b] } var reversed = [256]byte{ 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240, Index: src/0dev.org/bits/bits_test.go ================================================================== --- src/0dev.org/bits/bits_test.go +++ src/0dev.org/bits/bits_test.go @@ -5,11 +5,11 @@ "testing" ) func TestHamming(t *testing.T) { for i := 0; i < 256; i++ { - b, result := i, byte(0) + b, result := i, 0 for b > 0 { if (b & 1) > 0 { result++ } b = b >> 1 Index: src/0dev.org/predictor/predictor.go ================================================================== --- src/0dev.org/predictor/predictor.go +++ src/0dev.org/predictor/predictor.go @@ -84,74 +84,73 @@ // Returns an io.Reader implementation that wraps the provided io.Reader // and decompresses data according to the predictor algorithm func Decompressor(reader io.Reader) io.Reader { var dcmp decompressor dcmp.source = reader - dcmp.input = make([]byte, 8) return iou.SizedReader(&dcmp, 8) } type decompressor struct { context source io.Reader - input []byte } // Note: this method does not implement the full io.Reader's Read() semantics func (ctx *decompressor) Read(output []byte) (int, error) { var ( - err error - flags, predicted byte - rc, total, copied int + err error + buffer []byte = make([]byte, 8) + flags byte + predicted, rc, total, copied int ) // Read the next prediction header readHeader: - rc, err = ctx.source.Read(ctx.input[:1]) + rc, err = ctx.source.Read(buffer[:1]) // Fail on error unless it is EOF if err != nil && err != io.EOF { return total, err } else if rc == 0 { return total, err } // Copy the prediction header and calculate the number of subsequent bytes to read - flags = ctx.input[0] + flags = buffer[0] predicted = bits.Hamming(flags) // Read the non-predicted bytes and place them in the end of the buffer - rc, err = ctx.source.Read(ctx.input[predicted:]) + rc, err = ctx.source.Read(buffer[predicted:]) retryData: - if rc < int(8-predicted) && err == nil { + if (rc < (8 - predicted)) && err == nil { // Retry the read if we have fewer bytes than what the prediction header indicates var r int - r, err = ctx.source.Read(ctx.input[int(predicted)+rc:]) + r, err = ctx.source.Read(buffer[predicted+rc:]) rc += r goto retryData } // Continue on any error, try to decompress and return it along the result // rc now contains the amount of actual bytes in this cycle (usually 8) - rc += int(predicted) + rc += predicted // Walk the buffer, filling in the predicted blanks, // relocating read bytes and and updating the guess table for i, a := 0, predicted; i < rc; i++ { if (flags & (1 << uint(i))) > 0 { // Guess succeeded, fill in from the table - ctx.input[i] = ctx.table[ctx.hash] + buffer[i] = ctx.table[ctx.hash] } else { // Relocate a read byte and advance the read byte index - ctx.input[i], a = ctx.input[a], a+1 + buffer[i], a = buffer[a], a+1 // Guess failed, update the table - ctx.table[ctx.hash] = ctx.input[i] + ctx.table[ctx.hash] = buffer[i] } // Update the hash - ctx.update(ctx.input[i]) + ctx.update(buffer[i]) } // Copy the decompressed data to the output and accumulate the count - copied = copy(output, ctx.input[:rc]) + copied = copy(output, buffer[:rc]) total += copied // Loop for another pass if there is available space in the output output = output[copied:] if len(output) > 0 && err == nil {