1 // Copyright 2009 The Go 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 binary implements simple translation between numbers and byte
6 // sequences and encoding and decoding of varints.
7 //
8 // Numbers are translated by reading and writing fixed-size values.
9 // A fixed-size value is either a fixed-size arithmetic
10 // type (bool, int8, uint8, int16, float32, complex64, ...)
11 // or an array or struct containing only fixed-size values.
12 //
13 // The varint functions encode and decode single integer values using
14 // a variable-length encoding; smaller values require fewer bytes.
15 // For a specification, see
16 // https://developers.google.com/protocol-buffers/docs/encoding.
17 //
18 // This package favors simplicity over efficiency. Clients that require
19 // high-performance serialization, especially for large data structures,
20 // should look at more advanced solutions such as the [encoding/gob]
21 // package or [google.golang.org/protobuf] for protocol buffers.
22 package binary
23 24 import (
25 "errors"
26 "io"
27 "math"
28 "slices"
29 )
30 31 var errBufferTooSmall = errors.New("buffer too small")
32 33 // A ByteOrder specifies how to convert byte slices into
34 // 16-, 32-, or 64-bit unsigned integers.
35 //
36 // It is implemented by [LittleEndian], [BigEndian], and [NativeEndian].
37 type ByteOrder interface {
38 Uint16([]byte) uint16
39 Uint32([]byte) uint32
40 Uint64([]byte) uint64
41 PutUint16([]byte, uint16)
42 PutUint32([]byte, uint32)
43 PutUint64([]byte, uint64)
44 String() string
45 }
46 47 // AppendByteOrder specifies how to append 16-, 32-, or 64-bit unsigned integers
48 // into a byte slice.
49 //
50 // It is implemented by [LittleEndian], [BigEndian], and [NativeEndian].
51 type AppendByteOrder interface {
52 AppendUint16([]byte, uint16) []byte
53 AppendUint32([]byte, uint32) []byte
54 AppendUint64([]byte, uint64) []byte
55 String() string
56 }
57 58 // LittleEndian is the little-endian implementation of [ByteOrder] and [AppendByteOrder].
59 var LittleEndian littleEndian
60 61 // BigEndian is the big-endian implementation of [ByteOrder] and [AppendByteOrder].
62 var BigEndian bigEndian
63 64 type littleEndian struct{}
65 66 // Uint16 returns the uint16 representation of b[0:2].
67 func (littleEndian) Uint16(b []byte) uint16 {
68 _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
69 return uint16(b[0]) | uint16(b[1])<<8
70 }
71 72 // PutUint16 stores v into b[0:2].
73 func (littleEndian) PutUint16(b []byte, v uint16) {
74 _ = b[1] // early bounds check to guarantee safety of writes below
75 b[0] = byte(v)
76 b[1] = byte(v >> 8)
77 }
78 79 // AppendUint16 appends the bytes of v to b and returns the appended slice.
80 func (littleEndian) AppendUint16(b []byte, v uint16) []byte {
81 return append(b,
82 byte(v),
83 byte(v>>8),
84 )
85 }
86 87 // Uint32 returns the uint32 representation of b[0:4].
88 func (littleEndian) Uint32(b []byte) uint32 {
89 _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
90 return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
91 }
92 93 // PutUint32 stores v into b[0:4].
94 func (littleEndian) PutUint32(b []byte, v uint32) {
95 _ = b[3] // early bounds check to guarantee safety of writes below
96 b[0] = byte(v)
97 b[1] = byte(v >> 8)
98 b[2] = byte(v >> 16)
99 b[3] = byte(v >> 24)
100 }
101 102 // AppendUint32 appends the bytes of v to b and returns the appended slice.
103 func (littleEndian) AppendUint32(b []byte, v uint32) []byte {
104 return append(b,
105 byte(v),
106 byte(v>>8),
107 byte(v>>16),
108 byte(v>>24),
109 )
110 }
111 112 // Uint64 returns the uint64 representation of b[0:8].
113 func (littleEndian) Uint64(b []byte) uint64 {
114 _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
115 return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
116 uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
117 }
118 119 // PutUint64 stores v into b[0:8].
120 func (littleEndian) PutUint64(b []byte, v uint64) {
121 _ = b[7] // early bounds check to guarantee safety of writes below
122 b[0] = byte(v)
123 b[1] = byte(v >> 8)
124 b[2] = byte(v >> 16)
125 b[3] = byte(v >> 24)
126 b[4] = byte(v >> 32)
127 b[5] = byte(v >> 40)
128 b[6] = byte(v >> 48)
129 b[7] = byte(v >> 56)
130 }
131 132 // AppendUint64 appends the bytes of v to b and returns the appended slice.
133 func (littleEndian) AppendUint64(b []byte, v uint64) []byte {
134 return append(b,
135 byte(v),
136 byte(v>>8),
137 byte(v>>16),
138 byte(v>>24),
139 byte(v>>32),
140 byte(v>>40),
141 byte(v>>48),
142 byte(v>>56),
143 )
144 }
145 146 func (littleEndian) String() string { return "LittleEndian" }
147 148 func (littleEndian) GoString() []byte { return "binary.LittleEndian" }
149 150 type bigEndian struct{}
151 152 // Uint16 returns the uint16 representation of b[0:2].
153 func (bigEndian) Uint16(b []byte) uint16 {
154 _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
155 return uint16(b[1]) | uint16(b[0])<<8
156 }
157 158 // PutUint16 stores v into b[0:2].
159 func (bigEndian) PutUint16(b []byte, v uint16) {
160 _ = b[1] // early bounds check to guarantee safety of writes below
161 b[0] = byte(v >> 8)
162 b[1] = byte(v)
163 }
164 165 // AppendUint16 appends the bytes of v to b and returns the appended slice.
166 func (bigEndian) AppendUint16(b []byte, v uint16) []byte {
167 return append(b,
168 byte(v>>8),
169 byte(v),
170 )
171 }
172 173 // Uint32 returns the uint32 representation of b[0:4].
174 func (bigEndian) Uint32(b []byte) uint32 {
175 _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
176 return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
177 }
178 179 // PutUint32 stores v into b[0:4].
180 func (bigEndian) PutUint32(b []byte, v uint32) {
181 _ = b[3] // early bounds check to guarantee safety of writes below
182 b[0] = byte(v >> 24)
183 b[1] = byte(v >> 16)
184 b[2] = byte(v >> 8)
185 b[3] = byte(v)
186 }
187 188 // AppendUint32 appends the bytes of v to b and returns the appended slice.
189 func (bigEndian) AppendUint32(b []byte, v uint32) []byte {
190 return append(b,
191 byte(v>>24),
192 byte(v>>16),
193 byte(v>>8),
194 byte(v),
195 )
196 }
197 198 // Uint64 returns the uint64 representation of b[0:8].
199 func (bigEndian) Uint64(b []byte) uint64 {
200 _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
201 return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
202 uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
203 }
204 205 // PutUint64 stores v into b[0:8].
206 func (bigEndian) PutUint64(b []byte, v uint64) {
207 _ = b[7] // early bounds check to guarantee safety of writes below
208 b[0] = byte(v >> 56)
209 b[1] = byte(v >> 48)
210 b[2] = byte(v >> 40)
211 b[3] = byte(v >> 32)
212 b[4] = byte(v >> 24)
213 b[5] = byte(v >> 16)
214 b[6] = byte(v >> 8)
215 b[7] = byte(v)
216 }
217 218 // AppendUint64 appends the bytes of v to b and returns the appended slice.
219 func (bigEndian) AppendUint64(b []byte, v uint64) []byte {
220 return append(b,
221 byte(v>>56),
222 byte(v>>48),
223 byte(v>>40),
224 byte(v>>32),
225 byte(v>>24),
226 byte(v>>16),
227 byte(v>>8),
228 byte(v),
229 )
230 }
231 232 func (bigEndian) String() string { return "BigEndian" }
233 234 func (bigEndian) GoString() []byte { return "binary.BigEndian" }
235 236 func (nativeEndian) String() string { return "NativeEndian" }
237 238 func (nativeEndian) GoString() []byte { return "binary.NativeEndian" }
239 240 // Read reads structured binary data from r into data.
241 // Data must be a pointer to a fixed-size value or a slice
242 // of fixed-size values.
243 // Bytes read from r are decoded using the specified byte order
244 // and written to successive fields of the data.
245 // When decoding boolean values, a zero byte is decoded as false, and
246 // any other non-zero byte is decoded as true.
247 // When reading into structs, the field data for fields with
248 // blank (_) field names is skipped; i.e., blank field names
249 // may be used for padding.
250 // When reading into a struct, all non-blank fields must be exported
251 // or Read may panic.
252 //
253 // The error is [io.EOF] only if no bytes were read.
254 // If an [io.EOF] happens after reading some but not all the bytes,
255 // Read returns [io.ErrUnexpectedEOF].
256 func Read(r io.Reader, order ByteOrder, data any) error {
257 n, _ := intDataSize(data)
258 if n == 0 {
259 return errors.New("binary.Read: unsupported type (struct/array encoding removed)")
260 }
261 bs := []byte{:n}
262 if _, err := io.ReadFull(r, bs); err != nil {
263 return err
264 }
265 decodeFast(bs, order, data)
266 return nil
267 }
268 269 // Decode decodes binary data from buf into data according to
270 // the given byte order.
271 // It returns an error if buf is too small, otherwise the number of
272 // bytes consumed from buf.
273 func Decode(buf []byte, order ByteOrder, data any) (int, error) {
274 n, _ := intDataSize(data)
275 if n == 0 {
276 return 0, errors.New("binary.Decode: unsupported type (struct/array encoding removed)")
277 }
278 if len(buf) < n {
279 return 0, errBufferTooSmall
280 }
281 decodeFast(buf, order, data)
282 return n, nil
283 }
284 285 func decodeFast(bs []byte, order ByteOrder, data any) bool {
286 switch data := data.(type) {
287 case *bool:
288 *data = bs[0] != 0
289 case *int8:
290 *data = int8(bs[0])
291 case *uint8:
292 *data = bs[0]
293 case *int16:
294 *data = int16(order.Uint16(bs))
295 case *uint16:
296 *data = order.Uint16(bs)
297 case *int32:
298 *data = int32(order.Uint32(bs))
299 case *uint32:
300 *data = order.Uint32(bs)
301 case *int64:
302 *data = int64(order.Uint64(bs))
303 case *uint64:
304 *data = order.Uint64(bs)
305 case *float32:
306 *data = math.Float32frombits(order.Uint32(bs))
307 case *float64:
308 *data = math.Float64frombits(order.Uint64(bs))
309 case []bool:
310 for i, x := range bs { // Easier to loop over the input for 8-bit values.
311 data[i] = x != 0
312 }
313 case []int8:
314 for i, x := range bs {
315 data[i] = int8(x)
316 }
317 case []uint8:
318 copy(data, bs)
319 case []int16:
320 for i := range data {
321 data[i] = int16(order.Uint16(bs[2*i:]))
322 }
323 case []uint16:
324 for i := range data {
325 data[i] = order.Uint16(bs[2*i:])
326 }
327 case []int32:
328 for i := range data {
329 data[i] = int32(order.Uint32(bs[4*i:]))
330 }
331 case []uint32:
332 for i := range data {
333 data[i] = order.Uint32(bs[4*i:])
334 }
335 case []int64:
336 for i := range data {
337 data[i] = int64(order.Uint64(bs[8*i:]))
338 }
339 case []uint64:
340 for i := range data {
341 data[i] = order.Uint64(bs[8*i:])
342 }
343 case []float32:
344 for i := range data {
345 data[i] = math.Float32frombits(order.Uint32(bs[4*i:]))
346 }
347 case []float64:
348 for i := range data {
349 data[i] = math.Float64frombits(order.Uint64(bs[8*i:]))
350 }
351 default:
352 return false
353 }
354 return true
355 }
356 357 // Write writes the binary representation of data into w.
358 // Data must be a fixed-size value or a slice of fixed-size
359 // values, or a pointer to such data.
360 // Boolean values encode as one byte: 1 for true, and 0 for false.
361 // Bytes written to w are encoded using the specified byte order
362 // and read from successive fields of the data.
363 // When writing structs, zero values are written for fields
364 // with blank (_) field names.
365 func Write(w io.Writer, order ByteOrder, data any) error {
366 n, bs := intDataSize(data)
367 if n == 0 {
368 return errors.New("binary.Write: unsupported type (struct/array encoding removed)")
369 }
370 if bs == nil {
371 bs = []byte{:n}
372 encodeFast(bs, order, data)
373 }
374 _, err := w.Write(bs)
375 return err
376 }
377 378 // Encode encodes the binary representation of data into buf according to
379 // the given byte order.
380 // It returns an error if buf is too small, otherwise the number of
381 // bytes written into buf.
382 func Encode(buf []byte, order ByteOrder, data any) (int, error) {
383 n, _ := intDataSize(data)
384 if n == 0 {
385 return 0, errors.New("binary.Encode: unsupported type (struct/array encoding removed)")
386 }
387 if len(buf) < n {
388 return 0, errBufferTooSmall
389 }
390 encodeFast(buf, order, data)
391 return n, nil
392 }
393 394 // Append appends the binary representation of data to buf.
395 // buf may be nil, in which case a new buffer will be allocated.
396 // See [Write] on which data are acceptable.
397 // It returns the (possibly extended) buffer containing data or an error.
398 func Append(buf []byte, order ByteOrder, data any) ([]byte, error) {
399 n, _ := intDataSize(data)
400 if n == 0 {
401 return nil, errors.New("binary.Append: unsupported type (struct/array encoding removed)")
402 }
403 buf, pos := ensure(buf, n)
404 encodeFast(pos, order, data)
405 return buf, nil
406 }
407 408 func encodeFast(bs []byte, order ByteOrder, data any) {
409 switch v := data.(type) {
410 case *bool:
411 if *v {
412 bs[0] = 1
413 } else {
414 bs[0] = 0
415 }
416 case bool:
417 if v {
418 bs[0] = 1
419 } else {
420 bs[0] = 0
421 }
422 case []bool:
423 for i, x := range v {
424 if x {
425 bs[i] = 1
426 } else {
427 bs[i] = 0
428 }
429 }
430 case *int8:
431 bs[0] = byte(*v)
432 case int8:
433 bs[0] = byte(v)
434 case []int8:
435 for i, x := range v {
436 bs[i] = byte(x)
437 }
438 case *uint8:
439 bs[0] = *v
440 case uint8:
441 bs[0] = v
442 case []uint8:
443 copy(bs, v)
444 case *int16:
445 order.PutUint16(bs, uint16(*v))
446 case int16:
447 order.PutUint16(bs, uint16(v))
448 case []int16:
449 for i, x := range v {
450 order.PutUint16(bs[2*i:], uint16(x))
451 }
452 case *uint16:
453 order.PutUint16(bs, *v)
454 case uint16:
455 order.PutUint16(bs, v)
456 case []uint16:
457 for i, x := range v {
458 order.PutUint16(bs[2*i:], x)
459 }
460 case *int32:
461 order.PutUint32(bs, uint32(*v))
462 case int32:
463 order.PutUint32(bs, uint32(v))
464 case []int32:
465 for i, x := range v {
466 order.PutUint32(bs[4*i:], uint32(x))
467 }
468 case *uint32:
469 order.PutUint32(bs, *v)
470 case uint32:
471 order.PutUint32(bs, v)
472 case []uint32:
473 for i, x := range v {
474 order.PutUint32(bs[4*i:], x)
475 }
476 case *int64:
477 order.PutUint64(bs, uint64(*v))
478 case int64:
479 order.PutUint64(bs, uint64(v))
480 case []int64:
481 for i, x := range v {
482 order.PutUint64(bs[8*i:], uint64(x))
483 }
484 case *uint64:
485 order.PutUint64(bs, *v)
486 case uint64:
487 order.PutUint64(bs, v)
488 case []uint64:
489 for i, x := range v {
490 order.PutUint64(bs[8*i:], x)
491 }
492 case *float32:
493 order.PutUint32(bs, math.Float32bits(*v))
494 case float32:
495 order.PutUint32(bs, math.Float32bits(v))
496 case []float32:
497 for i, x := range v {
498 order.PutUint32(bs[4*i:], math.Float32bits(x))
499 }
500 case *float64:
501 order.PutUint64(bs, math.Float64bits(*v))
502 case float64:
503 order.PutUint64(bs, math.Float64bits(v))
504 case []float64:
505 for i, x := range v {
506 order.PutUint64(bs[8*i:], math.Float64bits(x))
507 }
508 }
509 }
510 511 // Size returns how many bytes [Write] would generate to encode the value v, which
512 // must be a fixed-size value or a slice of fixed-size values, or a pointer to such data.
513 // If v is neither of these, Size returns -1.
514 func Size(v any) int {
515 switch data := v.(type) {
516 case bool, int8, uint8:
517 return 1
518 case *bool:
519 if data == nil {
520 return -1
521 }
522 return 1
523 case *int8:
524 if data == nil {
525 return -1
526 }
527 return 1
528 case *uint8:
529 if data == nil {
530 return -1
531 }
532 return 1
533 case []bool:
534 return len(data)
535 case []int8:
536 return len(data)
537 case []uint8:
538 return len(data)
539 case int16, uint16:
540 return 2
541 case *int16:
542 if data == nil {
543 return -1
544 }
545 return 2
546 case *uint16:
547 if data == nil {
548 return -1
549 }
550 return 2
551 case []int16:
552 return 2 * len(data)
553 case []uint16:
554 return 2 * len(data)
555 case int32, uint32:
556 return 4
557 case *int32:
558 if data == nil {
559 return -1
560 }
561 return 4
562 case *uint32:
563 if data == nil {
564 return -1
565 }
566 return 4
567 case []int32:
568 return 4 * len(data)
569 case []uint32:
570 return 4 * len(data)
571 case int64, uint64:
572 return 8
573 case *int64:
574 if data == nil {
575 return -1
576 }
577 return 8
578 case *uint64:
579 if data == nil {
580 return -1
581 }
582 return 8
583 case []int64:
584 return 8 * len(data)
585 case []uint64:
586 return 8 * len(data)
587 case float32:
588 return 4
589 case *float32:
590 if data == nil {
591 return -1
592 }
593 return 4
594 case float64:
595 return 8
596 case *float64:
597 if data == nil {
598 return -1
599 }
600 return 8
601 case []float32:
602 return 4 * len(data)
603 case []float64:
604 return 8 * len(data)
605 }
606 return -1
607 }
608 609 type coder struct {
610 order ByteOrder
611 buf []byte
612 offset int
613 }
614 615 type decoder coder
616 type encoder coder
617 618 func (d *decoder) bool() bool {
619 x := d.buf[d.offset]
620 d.offset++
621 return x != 0
622 }
623 624 func (e *encoder) bool(x bool) {
625 if x {
626 e.buf[e.offset] = 1
627 } else {
628 e.buf[e.offset] = 0
629 }
630 e.offset++
631 }
632 633 func (d *decoder) uint8() uint8 {
634 x := d.buf[d.offset]
635 d.offset++
636 return x
637 }
638 639 func (e *encoder) uint8(x uint8) {
640 e.buf[e.offset] = x
641 e.offset++
642 }
643 644 func (d *decoder) uint16() uint16 {
645 x := d.order.Uint16(d.buf[d.offset : d.offset+2])
646 d.offset += 2
647 return x
648 }
649 650 func (e *encoder) uint16(x uint16) {
651 e.order.PutUint16(e.buf[e.offset:e.offset+2], x)
652 e.offset += 2
653 }
654 655 func (d *decoder) uint32() uint32 {
656 x := d.order.Uint32(d.buf[d.offset : d.offset+4])
657 d.offset += 4
658 return x
659 }
660 661 func (e *encoder) uint32(x uint32) {
662 e.order.PutUint32(e.buf[e.offset:e.offset+4], x)
663 e.offset += 4
664 }
665 666 func (d *decoder) uint64() uint64 {
667 x := d.order.Uint64(d.buf[d.offset : d.offset+8])
668 d.offset += 8
669 return x
670 }
671 672 func (e *encoder) uint64(x uint64) {
673 e.order.PutUint64(e.buf[e.offset:e.offset+8], x)
674 e.offset += 8
675 }
676 677 func (d *decoder) int8() int8 { return int8(d.uint8()) }
678 679 func (e *encoder) int8(x int8) { e.uint8(uint8(x)) }
680 681 func (d *decoder) int16() int16 { return int16(d.uint16()) }
682 683 func (e *encoder) int16(x int16) { e.uint16(uint16(x)) }
684 685 func (d *decoder) int32() int32 { return int32(d.uint32()) }
686 687 func (e *encoder) int32(x int32) { e.uint32(uint32(x)) }
688 689 func (d *decoder) int64() int64 { return int64(d.uint64()) }
690 691 func (e *encoder) int64(x int64) { e.uint64(uint64(x)) }
692 693 // intDataSize returns the size of the data required to represent the data when encoded,
694 // and optionally a byte slice containing the encoded data if no conversion is necessary.
695 // It returns zero, nil if the type cannot be implemented by the fast path in Read or Write.
696 func intDataSize(data any) (int, []byte) {
697 switch data := data.(type) {
698 case bool, int8, uint8, *bool, *int8, *uint8:
699 return 1, nil
700 case []bool:
701 return len(data), nil
702 case []int8:
703 return len(data), nil
704 case []uint8:
705 return len(data), data
706 case int16, uint16, *int16, *uint16:
707 return 2, nil
708 case []int16:
709 return 2 * len(data), nil
710 case []uint16:
711 return 2 * len(data), nil
712 case int32, uint32, *int32, *uint32:
713 return 4, nil
714 case []int32:
715 return 4 * len(data), nil
716 case []uint32:
717 return 4 * len(data), nil
718 case int64, uint64, *int64, *uint64:
719 return 8, nil
720 case []int64:
721 return 8 * len(data), nil
722 case []uint64:
723 return 8 * len(data), nil
724 case float32, *float32:
725 return 4, nil
726 case float64, *float64:
727 return 8, nil
728 case []float32:
729 return 4 * len(data), nil
730 case []float64:
731 return 8 * len(data), nil
732 }
733 return 0, nil
734 }
735 736 // ensure grows buf to length len(buf) + n and returns the grown buffer
737 // and a slice starting at the original length of buf (that is, buf2[len(buf):]).
738 func ensure(buf []byte, n int) (buf2, pos []byte) {
739 l := len(buf)
740 buf = slices.Grow(buf, n)[:l+n]
741 return buf, buf[l:]
742 }
743