@@ -4,18 +4,16 @@ // 1 - 11, 2 - 011, 3 - 0011, 4 - 1011, 5 - 00011 // // Incrementing input by one to allow for zero gives // 0 - 11, 1 - 011, 2 - 0011, 3 - 1011, 4 - 00011 // -// The codes are then reversed so that they are easily stored in uints +// The codes are reversed so that they are easily stored in uints, +// effectively avoiding the need to store the number of leading zeroes // 0 - 11, 1 - 110, 2 - 1100, 3 - 1101, 4 - 11000 -// (so that they are always comparable with each other as there is no need to -// store the leading number of zeroes which are otherwise required) package fibonacci import ( - _ "fmt" "io" ) type Numbers []uint64 @@ -159,50 +157,62 @@ 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 -// } - -// func (d *decoder) Read(output []byte) (int, error) { -// var ( -// total int -// err error -// ) - -// // 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) - -// // Store the decoded byte -// output[0] = byte(val) - -// // Advance the internal and output buffers -// output = output[1:] -// d.buffer >>= len - -// // TODO - decrease d.at as well ? - -// total++ -// } - -// // Termination condition -// if len(output) == 0 { -// return total, nil -// } - -// // count, err := d.source.Read(output) - -// 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 +} + +func (d *decoder) Read(output []byte) (int, error) { + var ( + total int + err error + ) + +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) + + // Store the decoded byte + output[0] = byte(val) + + // Advance the internal and output buffers + output = output[1:] + d.buffer >>= len + d.at -= len + + total++ + } + + // Termination condition + if len(output) == 0 || err != nil { + return total, err + } + + // We need to limit the output's size else we could end up with a lot of small values + // that fit neither in the output slice nor in the internal buffer + free := int((63 ^ d.at) >> 3) + if free > len(output) { + free = len(output) + } + + // Read data and transfer to the internal buffer + count, err := d.source.Read(output[:free]) + for _, v := range output[:count] { + d.buffer |= uint64(v) << d.at + d.at += 8 + } + + goto start +}