Check-in [f1a8d5baa9]
Overview
SHA1:f1a8d5baa914eb4073c9ff4da03ea5e893854cde
Date: 2015-01-01 15:12:44
User: spaskalev
Comment:Use a common fibonacci number source for each encoder and decoder. Dropped the two-bytes buffer from the encoder struct.
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | folders | manifest
Tags And Properties
Context
2015-01-01
15:19
[cb736e7ad3] [fibonacci] renamed Writer->Encoder, Reader->Decoder. [mtf] moved package mtf to encoding\mtf (user: spaskalev, tags: trunk)
15:12
[f1a8d5baa9] Use a common fibonacci number source for each encoder and decoder. Dropped the two-bytes buffer from the encoder struct. (user: spaskalev, tags: trunk)
14:11
[4b9f9bff39] Initial implementation and test of fibonacci.Reader(io.Reader) io.Reader that decodes bytes encoded from fibonacci.Writer(..). CC at 97.5% (user: spaskalev, tags: trunk)
Changes

Modified src/0dev.org/encoding/fibonacci/fib.go from [665b1e0b43] to [5685c81b13].

    12     12   package fibonacci
    13     13   
    14     14   import (
    15     15   	"io"
    16     16   )
    17     17   
    18     18   type Numbers []uint64
           19  +
           20  +var (
           21  +	// Used for encoding and decoding byte values
           22  +	bytesCodec = New(14)
           23  +)
    19     24   
    20     25   // Returns a slice with fibonacci numbers up to the given length
    21     26   func New(size int) Numbers {
    22     27   	var fibs Numbers = make(Numbers, size)
    23     28   	copy(fibs, []uint64{1, 1})
    24     29   	for i := 2; i < size; i++ {
    25     30   		fibs[i] = fibs[i-1] + fibs[i-2]
................................................................................
    72     77   		length++
    73     78   	}
    74     79   	return result + f[length] - 1, length + 1
    75     80   }
    76     81   
    77     82   func Writer(target io.Writer) io.Writer {
    78     83   	var enc encoder
    79         -	enc.Numbers = New(14)
    80     84   	enc.target = target
    81         -	enc.buffer = enc.backing[:0:len(enc.backing)]
    82     85   	return &enc
    83     86   }
    84     87   
    85     88   type encoder struct {
    86         -	Numbers
    87     89   	target    io.Writer
    88         -	backing   [2]byte
    89         -	buffer    []byte
    90     90   	remaining byte
    91     91   	length    byte
    92     92   }
    93     93   
    94     94   func (e *encoder) Write(input []byte) (int, error) {
    95     95   	var (
    96     96   		total int
    97     97   		err   error
    98     98   	)
    99     99   
   100    100   	// Flush on a nil slice
   101    101   	if input == nil {
   102         -		e.backing[0] = byte(e.remaining)
   103         -		_, err = e.target.Write(e.buffer[:1])
          102  +		_, err = e.target.Write([]byte{byte(e.remaining)})
   104    103   		return 0, err
   105    104   	}
   106    105   
   107    106   	for _, currentByte := range input {
   108    107   		// Get the fibonacci code and bit length for the current byte
   109         -		enc, len := e.Code(uint64(currentByte))
          108  +		enc, len := bytesCodec.Code(uint64(currentByte))
   110    109   
   111    110   		// Add current bits to higher positions
   112    111   		e.remaining |= byte(enc << e.length)
   113    112   
   114    113   		// maximum length of added bits to e.remaining
   115    114   		added := 8 - e.length
   116    115   
................................................................................
   126    125   
   127    126   			continue
   128    127   		}
   129    128   
   130    129   		// Clearing e.length is not necessary as it will be overwritten later
   131    130   
   132    131   		// Stage the complete byte for writing
   133         -		e.buffer = append(e.buffer, byte(e.remaining))
          132  +		buffer := []byte{byte(e.remaining)}
   134    133   
   135    134   		// Stage every full byte from the encoded value for writing
   136    135   		for enc > 128 {
   137         -			e.buffer = append(e.buffer, byte(enc))
          136  +			buffer = append(buffer, byte(enc))
   138    137   			enc >>= 8
   139    138   			len -= 8
   140    139   		}
   141    140   
   142    141   		// Store the remaining bits
   143    142   		e.remaining, e.length = byte(enc), len
   144    143   
   145    144   		// Write the staged bytes
   146         -		_, err = e.target.Write(e.buffer)
          145  +		_, err = e.target.Write(buffer)
   147    146   
   148    147   		// Abort write on error
   149    148   		if err != nil {
   150    149   			break
   151    150   		}
   152    151   
   153    152   		// Account for the processed input byte
   154    153   		total++
   155         -
   156         -		// Clear the buffer
   157         -		e.buffer = e.buffer[:0]
   158    154   	}
   159    155   	return total, err
   160    156   }
   161    157   
   162    158   func Reader(source io.Reader) io.Reader {
   163    159   	var dec decoder
   164         -	dec.Numbers = New(16)
   165    160   	dec.source = source
   166    161   	return &dec
   167    162   }
   168    163   
   169    164   type decoder struct {
   170         -	Numbers
   171    165   	source io.Reader
   172    166   	buffer uint64
   173    167   	at     byte
   174    168   }
   175    169   
   176    170   func (d *decoder) Read(output []byte) (int, error) {
   177    171   	var (
................................................................................
   178    172   		total int
   179    173   		err   error
   180    174   	)
   181    175   
   182    176   start:
   183    177   	// While we have suitable buffered data and enough output space
   184    178   	for (len(output) > 0) && ((d.buffer & (d.buffer >> 1)) > 0) {
   185         -		val, len := d.Decode(d.buffer)
          179  +		val, len := bytesCodec.Decode(d.buffer)
   186    180   
   187    181   		// Store the decoded byte
   188    182   		output[0] = byte(val)
   189    183   
   190    184   		// Advance the internal and output buffers
   191    185   		output = output[1:]
   192    186   		d.buffer >>= len
................................................................................
   210    204   	// Read data and transfer to the internal buffer
   211    205   	count, err := d.source.Read(output[:free])
   212    206   	for _, v := range output[:count] {
   213    207   		d.buffer |= uint64(v) << d.at
   214    208   		d.at += 8
   215    209   	}
   216    210   
          211  +	// To ensure a tail call :)
   217    212   	goto start
   218    213   }