Diff

Differences From Artifact [f2ad12a795]:

To Artifact [cebf1719c8]:


    25     25   	240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
    26     26   }
    27     27   
    28     28   type context struct {
    29     29   	table [256]byte
    30     30   }
    31     31   
    32         -// Returns an MTF encoder over the provided io.Writer
    33         -func Encoder(writer io.Writer) io.Writer {
    34         -	var enc encoder
    35         -	enc.table = initial
    36         -	enc.target = writer
    37         -	return &enc
    38         -}
    39         -
    40         -type encoder struct {
    41         -	context
    42         -	target io.Writer
    43         -}
    44         -
    45         -func (c *encoder) Write(data []byte) (int, error) {
    46         -	var (
    47         -		dataLength int    = len(data)
    48         -		buffer     []byte = make([]byte, dataLength)
    49         -	)
    50         -
    51         -	// io.Write must not modify the passed data in any way
    52         -	// TODO - check sync.Pool or a local free-list for amortizing buffers
    53         -	// TODO - use a buffer with a fixed max size to avoid OOM conditions
    54         -
    55         -	// Loop over the input data
           32  +// Encodes data in place
           33  +func (c *context) encode(data []byte) {
    56     34   	for index, value := range data {
    57     35   
    58     36   		// Shortcut for sequential, equal values
    59     37   		if c.table[0] == value {
    60         -			buffer[index] = 0
           38  +			data[index] = 0
    61     39   			continue
    62     40   		}
    63     41   
    64     42   		// Loop over the MTF table
    65     43   		for j := byte(1); j != 0; j++ {
    66     44   			if c.table[j] == value {
    67     45   				// Output the value
    68         -				buffer[index] = j
           46  +				data[index] = j
    69     47   
    70     48   				// Shift the table
    71     49   				copy(c.table[1:], c.table[:j])
    72     50   
    73     51   				// Restore the value in front and break
    74     52   				c.table[0] = value
    75     53   				break
    76     54   			}
    77     55   		}
    78     56   	}
           57  +}
           58  +
           59  +// Decode data in place
           60  +func (c *context) decode(data []byte) {
           61  +	for index, value := range data {
           62  +		position := value
           63  +
           64  +		// Shortcut for sequential, equal values
           65  +		if position == 0 {
           66  +			data[index] = c.table[0]
           67  +			continue
           68  +		}
           69  +
           70  +		// Output the value
           71  +		data[index] = c.table[position]
           72  +
           73  +		// Shift the table and restore the value in front
           74  +		copy(c.table[1:], c.table[:position])
           75  +		c.table[0] = data[index]
           76  +	}
           77  +}
           78  +
           79  +// Returns an MTF encoder over the provided io.Reader
           80  +func Encoder(reader io.Reader) io.Reader {
           81  +	var enc encoder
           82  +	enc.table = initial
           83  +	enc.source = reader
           84  +	return &enc
           85  +}
           86  +
           87  +type encoder struct {
           88  +	context
           89  +	source io.Reader
           90  +}
           91  +
           92  +// Read and encode data in place
           93  +func (c *encoder) Read(output []byte) (count int, err error) {
           94  +	count, err = c.source.Read(output)
           95  +	c.encode(output[:count])
    79     96   
    80         -	return c.target.Write(buffer)
           97  +	return count, err
    81     98   }
    82     99   
    83         -// Returns an MTF decoder over the provided io.Writer
          100  +// Returns an MTF decoder over the provided io.Reader
    84    101   func Decoder(reader io.Reader) io.Reader {
    85    102   	var dec decoder
    86    103   	dec.table = initial
    87    104   	dec.source = reader
    88    105   	return &dec
    89    106   }
    90    107   
    91    108   type decoder struct {
    92    109   	context
    93    110   	source io.Reader
    94    111   }
    95    112   
    96         -func (c *decoder) Read(output []byte) (int, error) {
    97         -	var (
    98         -		count    int
    99         -		err      error
   100         -		position byte
   101         -	)
   102         -
   103         -	// Read from the source and decode in place
          113  +// Read and decode data in place
          114  +func (c *decoder) Read(output []byte) (count int, err error) {
   104    115   	count, err = c.source.Read(output)
   105         -	for i := 0; i < count; i++ {
   106         -		position = output[i]
   107         -
   108         -		// Shortcut for sequential, equal values
   109         -		if position == 0 {
   110         -			output[i] = c.table[0]
   111         -			continue
   112         -		}
   113         -
   114         -		// Output the value
   115         -		output[i] = c.table[position]
   116         -
   117         -		// Shift the table and restore the value in front
   118         -		copy(c.table[1:], c.table[:position])
   119         -		c.table[0] = output[i]
   120         -	}
          116  +	c.decode(output[:count])
   121    117   
   122    118   	return count, err
   123    119   }