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 }