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