Index: src/0dev.org/encoding/fibonacci/fib.go ================================================================== --- src/0dev.org/encoding/fibonacci/fib.go +++ src/0dev.org/encoding/fibonacci/fib.go @@ -14,10 +14,15 @@ import ( "io" ) type Numbers []uint64 + +var ( + // Used for encoding and decoding byte values + bytesCodec = New(14) +) // Returns a slice with fibonacci numbers up to the given length func New(size int) Numbers { var fibs Numbers = make(Numbers, size) copy(fibs, []uint64{1, 1}) @@ -74,21 +79,16 @@ return result + f[length] - 1, length + 1 } func Writer(target io.Writer) io.Writer { var enc encoder - enc.Numbers = New(14) enc.target = target - enc.buffer = enc.backing[:0:len(enc.backing)] return &enc } type encoder struct { - Numbers target io.Writer - backing [2]byte - buffer []byte remaining byte length byte } func (e *encoder) Write(input []byte) (int, error) { @@ -97,18 +97,17 @@ err error ) // Flush on a nil slice if input == nil { - e.backing[0] = byte(e.remaining) - _, err = e.target.Write(e.buffer[:1]) + _, err = e.target.Write([]byte{byte(e.remaining)}) return 0, err } for _, currentByte := range input { // Get the fibonacci code and bit length for the current byte - enc, len := e.Code(uint64(currentByte)) + enc, len := bytesCodec.Code(uint64(currentByte)) // Add current bits to higher positions e.remaining |= byte(enc << e.length) // maximum length of added bits to e.remaining @@ -128,48 +127,43 @@ } // Clearing e.length is not necessary as it will be overwritten later // Stage the complete byte for writing - e.buffer = append(e.buffer, byte(e.remaining)) + buffer := []byte{byte(e.remaining)} // Stage every full byte from the encoded value for writing for enc > 128 { - e.buffer = append(e.buffer, byte(enc)) + buffer = append(buffer, byte(enc)) enc >>= 8 len -= 8 } // Store the remaining bits e.remaining, e.length = byte(enc), len // Write the staged bytes - _, err = e.target.Write(e.buffer) + _, err = e.target.Write(buffer) // Abort write on error if err != nil { break } // Account for the processed input byte total++ - - // Clear the buffer - e.buffer = e.buffer[:0] } return total, err } func Reader(source io.Reader) io.Reader { var dec decoder - dec.Numbers = New(16) dec.source = source return &dec } type decoder struct { - Numbers source io.Reader buffer uint64 at byte } @@ -180,11 +174,11 @@ ) start: // While we have suitable buffered data and enough output space for (len(output) > 0) && ((d.buffer & (d.buffer >> 1)) > 0) { - val, len := d.Decode(d.buffer) + val, len := bytesCodec.Decode(d.buffer) // Store the decoded byte output[0] = byte(val) // Advance the internal and output buffers @@ -212,7 +206,8 @@ for _, v := range output[:count] { d.buffer |= uint64(v) << d.at d.at += 8 } + // To ensure a tail call :) goto start }