github.com/TrenchBoot/u-root@v6.0.1-0.20200623220532-550e36da3258+incompatible/pkg/uio/buffer.go (about)

     1  // Copyright 2018 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package uio
     6  
     7  import (
     8  	"encoding/binary"
     9  	"fmt"
    10  
    11  	"github.com/u-root/u-root/pkg/ubinary"
    12  )
    13  
    14  // Marshaler is the interface implemented by an object that can marshal itself
    15  // into binary form.
    16  //
    17  // Marshal appends data to the buffer b.
    18  type Marshaler interface {
    19  	Marshal(l *Lexer)
    20  }
    21  
    22  // Unmarshaler is the interface implemented by an object that can unmarshal a
    23  // binary representation of itself.
    24  //
    25  // Unmarshal Consumes data from the buffer b.
    26  type Unmarshaler interface {
    27  	Unmarshal(l *Lexer) error
    28  }
    29  
    30  // ToBytes marshals m in the given byte order.
    31  func ToBytes(m Marshaler, order binary.ByteOrder) []byte {
    32  	l := NewLexer(NewBuffer(nil), order)
    33  	m.Marshal(l)
    34  	return l.Data()
    35  }
    36  
    37  // FromBytes unmarshals b into obj in the given byte order.
    38  func FromBytes(obj Unmarshaler, b []byte, order binary.ByteOrder) error {
    39  	l := NewLexer(NewBuffer(b), order)
    40  	return obj.Unmarshal(l)
    41  }
    42  
    43  // ToBigEndian marshals m to big endian byte order.
    44  func ToBigEndian(m Marshaler) []byte {
    45  	l := NewBigEndianBuffer(nil)
    46  	m.Marshal(l)
    47  	return l.Data()
    48  }
    49  
    50  // FromBigEndian unmarshals b into obj in big endian byte order.
    51  func FromBigEndian(obj Unmarshaler, b []byte) error {
    52  	l := NewBigEndianBuffer(b)
    53  	return obj.Unmarshal(l)
    54  }
    55  
    56  // ToLittleEndian marshals m to little endian byte order.
    57  func ToLittleEndian(m Marshaler) []byte {
    58  	l := NewLittleEndianBuffer(nil)
    59  	m.Marshal(l)
    60  	return l.Data()
    61  }
    62  
    63  // FromLittleEndian unmarshals b into obj in little endian byte order.
    64  func FromLittleEndian(obj Unmarshaler, b []byte) error {
    65  	l := NewLittleEndianBuffer(b)
    66  	return obj.Unmarshal(l)
    67  }
    68  
    69  // Buffer implements functions to manipulate byte slices in a zero-copy way.
    70  type Buffer struct {
    71  	// data is the underlying data.
    72  	data []byte
    73  
    74  	// byteCount keeps track of how many bytes have been consumed for
    75  	// debugging.
    76  	byteCount int
    77  }
    78  
    79  // NewBuffer Consumes b for marshaling or unmarshaling in the given byte order.
    80  func NewBuffer(b []byte) *Buffer {
    81  	return &Buffer{data: b}
    82  }
    83  
    84  // Preallocate increases the capacity of the buffer by n bytes.
    85  func (b *Buffer) Preallocate(n int) {
    86  	b.data = append(b.data, make([]byte, 0, n)...)
    87  }
    88  
    89  // WriteN appends n bytes to the Buffer and returns a slice pointing to the
    90  // newly appended bytes.
    91  func (b *Buffer) WriteN(n int) []byte {
    92  	b.data = append(b.data, make([]byte, n)...)
    93  	return b.data[len(b.data)-n:]
    94  }
    95  
    96  // ReadN consumes n bytes from the Buffer. It returns nil, false if there
    97  // aren't enough bytes left.
    98  func (b *Buffer) ReadN(n int) ([]byte, error) {
    99  	if !b.Has(n) {
   100  		return nil, fmt.Errorf("buffer too short at position %d: have %d bytes, want %d bytes", b.byteCount, b.Len(), n)
   101  	}
   102  	rval := b.data[:n]
   103  	b.data = b.data[n:]
   104  	b.byteCount += n
   105  	return rval, nil
   106  }
   107  
   108  // Data is unConsumed data remaining in the Buffer.
   109  func (b *Buffer) Data() []byte {
   110  	return b.data
   111  }
   112  
   113  // Has returns true if n bytes are available.
   114  func (b *Buffer) Has(n int) bool {
   115  	return len(b.data) >= n
   116  }
   117  
   118  // Len returns the length of the remaining bytes.
   119  func (b *Buffer) Len() int {
   120  	return len(b.data)
   121  }
   122  
   123  // Cap returns the available capacity.
   124  func (b *Buffer) Cap() int {
   125  	return cap(b.data)
   126  }
   127  
   128  // Lexer is a convenient encoder/decoder for buffers.
   129  //
   130  // Use:
   131  //
   132  //   func (s *something) Unmarshal(l *Lexer) {
   133  //     s.Foo = l.Read8()
   134  //     s.Bar = l.Read8()
   135  //     s.Baz = l.Read16()
   136  //     return l.Error()
   137  //   }
   138  type Lexer struct {
   139  	*Buffer
   140  
   141  	// order is the byte order to write in / read in.
   142  	order binary.ByteOrder
   143  
   144  	// err
   145  	err error
   146  }
   147  
   148  // NewLexer returns a new coder for buffers.
   149  func NewLexer(b *Buffer, order binary.ByteOrder) *Lexer {
   150  	return &Lexer{
   151  		Buffer: b,
   152  		order:  order,
   153  	}
   154  }
   155  
   156  // NewLittleEndianBuffer returns a new little endian coder for a new buffer.
   157  func NewLittleEndianBuffer(b []byte) *Lexer {
   158  	return &Lexer{
   159  		Buffer: NewBuffer(b),
   160  		order:  binary.LittleEndian,
   161  	}
   162  }
   163  
   164  // NewBigEndianBuffer returns a new big endian coder for a new buffer.
   165  func NewBigEndianBuffer(b []byte) *Lexer {
   166  	return &Lexer{
   167  		Buffer: NewBuffer(b),
   168  		order:  binary.BigEndian,
   169  	}
   170  }
   171  
   172  // NewNativeEndianBuffer returns a new native endian coder for a new buffer.
   173  func NewNativeEndianBuffer(b []byte) *Lexer {
   174  	return &Lexer{
   175  		Buffer: NewBuffer(b),
   176  		order:  ubinary.NativeEndian,
   177  	}
   178  }
   179  
   180  func (l *Lexer) setError(err error) {
   181  	if l.err == nil {
   182  		l.err = err
   183  	}
   184  }
   185  
   186  // Consume returns a slice of the next n bytes from the buffer.
   187  //
   188  // Consume gives direct access to the underlying data.
   189  func (l *Lexer) Consume(n int) []byte {
   190  	v, err := l.Buffer.ReadN(n)
   191  	if err != nil {
   192  		l.setError(err)
   193  		return nil
   194  	}
   195  	return v
   196  }
   197  
   198  func (l *Lexer) append(n int) []byte {
   199  	return l.Buffer.WriteN(n)
   200  }
   201  
   202  // Error returns an error if an error occurred reading from the buffer.
   203  func (l *Lexer) Error() error {
   204  	return l.err
   205  }
   206  
   207  // FinError returns an error if an error occurred or if there is more data left
   208  // to read in the buffer.
   209  func (l *Lexer) FinError() error {
   210  	if l.err != nil {
   211  		return l.err
   212  	}
   213  	if l.Buffer.Len() > 0 {
   214  		return fmt.Errorf("buffer contains more bytes than it should")
   215  	}
   216  	return nil
   217  }
   218  
   219  // Read8 reads a byte from the Buffer.
   220  //
   221  // If an error occurred, Error() will return a non-nil error.
   222  func (l *Lexer) Read8() uint8 {
   223  	v := l.Consume(1)
   224  	if v == nil {
   225  		return 0
   226  	}
   227  	return uint8(v[0])
   228  }
   229  
   230  // Read16 reads a 16-bit value from the Buffer.
   231  //
   232  // If an error occurred, Error() will return a non-nil error.
   233  func (l *Lexer) Read16() uint16 {
   234  	v := l.Consume(2)
   235  	if v == nil {
   236  		return 0
   237  	}
   238  	return l.order.Uint16(v)
   239  }
   240  
   241  // Read32 reads a 32-bit value from the Buffer.
   242  //
   243  // If an error occurred, Error() will return a non-nil error.
   244  func (l *Lexer) Read32() uint32 {
   245  	v := l.Consume(4)
   246  	if v == nil {
   247  		return 0
   248  	}
   249  	return l.order.Uint32(v)
   250  }
   251  
   252  // Read64 reads a 64-bit value from the Buffer.
   253  //
   254  // If an error occurred, Error() will return a non-nil error.
   255  func (l *Lexer) Read64() uint64 {
   256  	v := l.Consume(8)
   257  	if v == nil {
   258  		return 0
   259  	}
   260  	return l.order.Uint64(v)
   261  }
   262  
   263  // CopyN returns a copy of the next n bytes.
   264  //
   265  // If an error occurred, Error() will return a non-nil error.
   266  func (l *Lexer) CopyN(n int) []byte {
   267  	v := l.Consume(n)
   268  	if v == nil {
   269  		return nil
   270  	}
   271  
   272  	p := make([]byte, n)
   273  	m := copy(p, v)
   274  	return p[:m]
   275  }
   276  
   277  // ReadAll Consumes and returns a copy of all remaining bytes in the Buffer.
   278  //
   279  // If an error occurred, Error() will return a non-nil error.
   280  func (l *Lexer) ReadAll() []byte {
   281  	return l.CopyN(l.Len())
   282  }
   283  
   284  // ReadBytes reads exactly len(p) values from the Buffer.
   285  //
   286  // If an error occurred, Error() will return a non-nil error.
   287  func (l *Lexer) ReadBytes(p []byte) {
   288  	copy(p, l.Consume(len(p)))
   289  }
   290  
   291  // Read implements io.Reader.Read.
   292  func (l *Lexer) Read(p []byte) (int, error) {
   293  	v := l.Consume(len(p))
   294  	if v == nil {
   295  		return 0, l.Error()
   296  	}
   297  	return copy(p, v), nil
   298  }
   299  
   300  // ReadData reads the binary representation of data from the buffer.
   301  //
   302  // See binary.Read.
   303  //
   304  // If an error occurred, Error() will return a non-nil error.
   305  func (l *Lexer) ReadData(data interface{}) {
   306  	l.setError(binary.Read(l, l.order, data))
   307  }
   308  
   309  // WriteData writes a binary representation of data to the buffer.
   310  //
   311  // See binary.Write.
   312  //
   313  // If an error occurred, Error() will return a non-nil error.
   314  func (l *Lexer) WriteData(data interface{}) {
   315  	l.setError(binary.Write(l, l.order, data))
   316  }
   317  
   318  // Write8 writes a byte to the Buffer.
   319  //
   320  // If an error occurred, Error() will return a non-nil error.
   321  func (l *Lexer) Write8(v uint8) {
   322  	l.append(1)[0] = byte(v)
   323  }
   324  
   325  // Write16 writes a 16-bit value to the Buffer.
   326  //
   327  // If an error occurred, Error() will return a non-nil error.
   328  func (l *Lexer) Write16(v uint16) {
   329  	l.order.PutUint16(l.append(2), v)
   330  }
   331  
   332  // Write32 writes a 32-bit value to the Buffer.
   333  //
   334  // If an error occurred, Error() will return a non-nil error.
   335  func (l *Lexer) Write32(v uint32) {
   336  	l.order.PutUint32(l.append(4), v)
   337  }
   338  
   339  // Write64 writes a 64-bit value to the Buffer.
   340  //
   341  // If an error occurred, Error() will return a non-nil error.
   342  func (l *Lexer) Write64(v uint64) {
   343  	l.order.PutUint64(l.append(8), v)
   344  }
   345  
   346  // Append returns a newly appended n-size Buffer to write to.
   347  //
   348  // If an error occurred, Error() will return a non-nil error.
   349  func (l *Lexer) Append(n int) []byte {
   350  	return l.append(n)
   351  }
   352  
   353  // WriteBytes writes p to the Buffer.
   354  //
   355  // If an error occurred, Error() will return a non-nil error.
   356  func (l *Lexer) WriteBytes(p []byte) {
   357  	copy(l.append(len(p)), p)
   358  }
   359  
   360  // Write implements io.Writer.Write.
   361  //
   362  // If an error occurred, Error() will return a non-nil error.
   363  func (l *Lexer) Write(p []byte) (int, error) {
   364  	return copy(l.append(len(p)), p), nil
   365  }
   366  
   367  // Align appends bytes to align the length of the buffer to be divisible by n.
   368  func (l *Lexer) Align(n int) {
   369  	pad := ((l.Len() + n - 1) &^ (n - 1)) - l.Len()
   370  	l.Append(pad)
   371  }