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.
22package binary
23
24import (
25	"errors"
26	"io"
27	"math"
28	"reflect"
29	"slices"
30	"sync"
31)
32
33var errBufferTooSmall = errors.New("buffer too small")
34
35// A ByteOrder specifies how to convert byte slices into
36// 16-, 32-, or 64-bit unsigned integers.
37//
38// It is implemented by [LittleEndian], [BigEndian], and [NativeEndian].
39type ByteOrder interface {
40	Uint16([]byte) uint16
41	Uint32([]byte) uint32
42	Uint64([]byte) uint64
43	PutUint16([]byte, uint16)
44	PutUint32([]byte, uint32)
45	PutUint64([]byte, uint64)
46	String() string
47}
48
49// AppendByteOrder specifies how to append 16-, 32-, or 64-bit unsigned integers
50// into a byte slice.
51//
52// It is implemented by [LittleEndian], [BigEndian], and [NativeEndian].
53type AppendByteOrder interface {
54	AppendUint16([]byte, uint16) []byte
55	AppendUint32([]byte, uint32) []byte
56	AppendUint64([]byte, uint64) []byte
57	String() string
58}
59
60// LittleEndian is the little-endian implementation of [ByteOrder] and [AppendByteOrder].
61var LittleEndian littleEndian
62
63// BigEndian is the big-endian implementation of [ByteOrder] and [AppendByteOrder].
64var BigEndian bigEndian
65
66type littleEndian struct{}
67
68func (littleEndian) Uint16(b []byte) uint16 {
69	_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
70	return uint16(b[0]) | uint16(b[1])<<8
71}
72
73func (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
79func (littleEndian) AppendUint16(b []byte, v uint16) []byte {
80	return append(b,
81		byte(v),
82		byte(v>>8),
83	)
84}
85
86func (littleEndian) Uint32(b []byte) uint32 {
87	_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
88	return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
89}
90
91func (littleEndian) PutUint32(b []byte, v uint32) {
92	_ = b[3] // early bounds check to guarantee safety of writes below
93	b[0] = byte(v)
94	b[1] = byte(v >> 8)
95	b[2] = byte(v >> 16)
96	b[3] = byte(v >> 24)
97}
98
99func (littleEndian) AppendUint32(b []byte, v uint32) []byte {
100	return append(b,
101		byte(v),
102		byte(v>>8),
103		byte(v>>16),
104		byte(v>>24),
105	)
106}
107
108func (littleEndian) Uint64(b []byte) uint64 {
109	_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
110	return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
111		uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
112}
113
114func (littleEndian) PutUint64(b []byte, v uint64) {
115	_ = b[7] // early bounds check to guarantee safety of writes below
116	b[0] = byte(v)
117	b[1] = byte(v >> 8)
118	b[2] = byte(v >> 16)
119	b[3] = byte(v >> 24)
120	b[4] = byte(v >> 32)
121	b[5] = byte(v >> 40)
122	b[6] = byte(v >> 48)
123	b[7] = byte(v >> 56)
124}
125
126func (littleEndian) AppendUint64(b []byte, v uint64) []byte {
127	return append(b,
128		byte(v),
129		byte(v>>8),
130		byte(v>>16),
131		byte(v>>24),
132		byte(v>>32),
133		byte(v>>40),
134		byte(v>>48),
135		byte(v>>56),
136	)
137}
138
139func (littleEndian) String() string { return "LittleEndian" }
140
141func (littleEndian) GoString() string { return "binary.LittleEndian" }
142
143type bigEndian struct{}
144
145func (bigEndian) Uint16(b []byte) uint16 {
146	_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
147	return uint16(b[1]) | uint16(b[0])<<8
148}
149
150func (bigEndian) PutUint16(b []byte, v uint16) {
151	_ = b[1] // early bounds check to guarantee safety of writes below
152	b[0] = byte(v >> 8)
153	b[1] = byte(v)
154}
155
156func (bigEndian) AppendUint16(b []byte, v uint16) []byte {
157	return append(b,
158		byte(v>>8),
159		byte(v),
160	)
161}
162
163func (bigEndian) Uint32(b []byte) uint32 {
164	_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
165	return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
166}
167
168func (bigEndian) PutUint32(b []byte, v uint32) {
169	_ = b[3] // early bounds check to guarantee safety of writes below
170	b[0] = byte(v >> 24)
171	b[1] = byte(v >> 16)
172	b[2] = byte(v >> 8)
173	b[3] = byte(v)
174}
175
176func (bigEndian) AppendUint32(b []byte, v uint32) []byte {
177	return append(b,
178		byte(v>>24),
179		byte(v>>16),
180		byte(v>>8),
181		byte(v),
182	)
183}
184
185func (bigEndian) Uint64(b []byte) uint64 {
186	_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
187	return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
188		uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
189}
190
191func (bigEndian) PutUint64(b []byte, v uint64) {
192	_ = b[7] // early bounds check to guarantee safety of writes below
193	b[0] = byte(v >> 56)
194	b[1] = byte(v >> 48)
195	b[2] = byte(v >> 40)
196	b[3] = byte(v >> 32)
197	b[4] = byte(v >> 24)
198	b[5] = byte(v >> 16)
199	b[6] = byte(v >> 8)
200	b[7] = byte(v)
201}
202
203func (bigEndian) AppendUint64(b []byte, v uint64) []byte {
204	return append(b,
205		byte(v>>56),
206		byte(v>>48),
207		byte(v>>40),
208		byte(v>>32),
209		byte(v>>24),
210		byte(v>>16),
211		byte(v>>8),
212		byte(v),
213	)
214}
215
216func (bigEndian) String() string { return "BigEndian" }
217
218func (bigEndian) GoString() string { return "binary.BigEndian" }
219
220func (nativeEndian) String() string { return "NativeEndian" }
221
222func (nativeEndian) GoString() string { return "binary.NativeEndian" }
223
224// Read reads structured binary data from r into data.
225// Data must be a pointer to a fixed-size value or a slice
226// of fixed-size values.
227// Bytes read from r are decoded using the specified byte order
228// and written to successive fields of the data.
229// When decoding boolean values, a zero byte is decoded as false, and
230// any other non-zero byte is decoded as true.
231// When reading into structs, the field data for fields with
232// blank (_) field names is skipped; i.e., blank field names
233// may be used for padding.
234// When reading into a struct, all non-blank fields must be exported
235// or Read may panic.
236//
237// The error is [io.EOF] only if no bytes were read.
238// If an [io.EOF] happens after reading some but not all the bytes,
239// Read returns [io.ErrUnexpectedEOF].
240func Read(r io.Reader, order ByteOrder, data any) error {
241	// Fast path for basic types and slices.
242	if n, _ := intDataSize(data); n != 0 {
243		bs := make([]byte, n)
244		if _, err := io.ReadFull(r, bs); err != nil {
245			return err
246		}
247
248		if decodeFast(bs, order, data) {
249			return nil
250		}
251	}
252
253	// Fallback to reflect-based decoding.
254	v := reflect.ValueOf(data)
255	size := -1
256	switch v.Kind() {
257	case reflect.Pointer:
258		v = v.Elem()
259		size = dataSize(v)
260	case reflect.Slice:
261		size = dataSize(v)
262	}
263	if size < 0 {
264		return errors.New("binary.Read: invalid type " + reflect.TypeOf(data).String())
265	}
266
267	d := &decoder{order: order, buf: make([]byte, size)}
268	if _, err := io.ReadFull(r, d.buf); err != nil {
269		return err
270	}
271	d.value(v)
272	return nil
273}
274
275// Decode decodes binary data from buf into data according to
276// the given byte order.
277// It returns an error if buf is too small, otherwise the number of
278// bytes consumed from buf.
279func Decode(buf []byte, order ByteOrder, data any) (int, error) {
280	if n, _ := intDataSize(data); n != 0 {
281		if len(buf) < n {
282			return 0, errBufferTooSmall
283		}
284
285		if decodeFast(buf, order, data) {
286			return n, nil
287		}
288	}
289
290	// Fallback to reflect-based decoding.
291	v := reflect.ValueOf(data)
292	size := -1
293	switch v.Kind() {
294	case reflect.Pointer:
295		v = v.Elem()
296		size = dataSize(v)
297	case reflect.Slice:
298		size = dataSize(v)
299	}
300	if size < 0 {
301		return 0, errors.New("binary.Decode: invalid type " + reflect.TypeOf(data).String())
302	}
303
304	if len(buf) < size {
305		return 0, errBufferTooSmall
306	}
307	d := &decoder{order: order, buf: buf[:size]}
308	d.value(v)
309	return size, nil
310}
311
312func decodeFast(bs []byte, order ByteOrder, data any) bool {
313	switch data := data.(type) {
314	case *bool:
315		*data = bs[0] != 0
316	case *int8:
317		*data = int8(bs[0])
318	case *uint8:
319		*data = bs[0]
320	case *int16:
321		*data = int16(order.Uint16(bs))
322	case *uint16:
323		*data = order.Uint16(bs)
324	case *int32:
325		*data = int32(order.Uint32(bs))
326	case *uint32:
327		*data = order.Uint32(bs)
328	case *int64:
329		*data = int64(order.Uint64(bs))
330	case *uint64:
331		*data = order.Uint64(bs)
332	case *float32:
333		*data = math.Float32frombits(order.Uint32(bs))
334	case *float64:
335		*data = math.Float64frombits(order.Uint64(bs))
336	case []bool:
337		for i, x := range bs { // Easier to loop over the input for 8-bit values.
338			data[i] = x != 0
339		}
340	case []int8:
341		for i, x := range bs {
342			data[i] = int8(x)
343		}
344	case []uint8:
345		copy(data, bs)
346	case []int16:
347		for i := range data {
348			data[i] = int16(order.Uint16(bs[2*i:]))
349		}
350	case []uint16:
351		for i := range data {
352			data[i] = order.Uint16(bs[2*i:])
353		}
354	case []int32:
355		for i := range data {
356			data[i] = int32(order.Uint32(bs[4*i:]))
357		}
358	case []uint32:
359		for i := range data {
360			data[i] = order.Uint32(bs[4*i:])
361		}
362	case []int64:
363		for i := range data {
364			data[i] = int64(order.Uint64(bs[8*i:]))
365		}
366	case []uint64:
367		for i := range data {
368			data[i] = order.Uint64(bs[8*i:])
369		}
370	case []float32:
371		for i := range data {
372			data[i] = math.Float32frombits(order.Uint32(bs[4*i:]))
373		}
374	case []float64:
375		for i := range data {
376			data[i] = math.Float64frombits(order.Uint64(bs[8*i:]))
377		}
378	default:
379		return false
380	}
381	return true
382}
383
384// Write writes the binary representation of data into w.
385// Data must be a fixed-size value or a slice of fixed-size
386// values, or a pointer to such data.
387// Boolean values encode as one byte: 1 for true, and 0 for false.
388// Bytes written to w are encoded using the specified byte order
389// and read from successive fields of the data.
390// When writing structs, zero values are written for fields
391// with blank (_) field names.
392func Write(w io.Writer, order ByteOrder, data any) error {
393	// Fast path for basic types and slices.
394	if n, bs := intDataSize(data); n != 0 {
395		if bs == nil {
396			bs = make([]byte, n)
397			encodeFast(bs, order, data)
398		}
399
400		_, err := w.Write(bs)
401		return err
402	}
403
404	// Fallback to reflect-based encoding.
405	v := reflect.Indirect(reflect.ValueOf(data))
406	size := dataSize(v)
407	if size < 0 {
408		return errors.New("binary.Write: some values are not fixed-sized in type " + reflect.TypeOf(data).String())
409	}
410
411	buf := make([]byte, size)
412	e := &encoder{order: order, buf: buf}
413	e.value(v)
414	_, err := w.Write(buf)
415	return err
416}
417
418// Encode encodes the binary representation of data into buf according to
419// the given byte order.
420// It returns an error if buf is too small, otherwise the number of
421// bytes written into buf.
422func Encode(buf []byte, order ByteOrder, data any) (int, error) {
423	// Fast path for basic types and slices.
424	if n, _ := intDataSize(data); n != 0 {
425		if len(buf) < n {
426			return 0, errBufferTooSmall
427		}
428
429		encodeFast(buf, order, data)
430		return n, nil
431	}
432
433	// Fallback to reflect-based encoding.
434	v := reflect.Indirect(reflect.ValueOf(data))
435	size := dataSize(v)
436	if size < 0 {
437		return 0, errors.New("binary.Encode: some values are not fixed-sized in type " + reflect.TypeOf(data).String())
438	}
439
440	if len(buf) < size {
441		return 0, errBufferTooSmall
442	}
443	e := &encoder{order: order, buf: buf}
444	e.value(v)
445	return size, nil
446}
447
448// Append appends the binary representation of data to buf.
449// buf may be nil, in which case a new buffer will be allocated.
450// See [Write] on which data are acceptable.
451// It returns the (possibily extended) buffer containing data or an error.
452func Append(buf []byte, order ByteOrder, data any) ([]byte, error) {
453	// Fast path for basic types and slices.
454	if n, _ := intDataSize(data); n != 0 {
455		buf, pos := ensure(buf, n)
456		encodeFast(pos, order, data)
457		return buf, nil
458	}
459
460	// Fallback to reflect-based encoding.
461	v := reflect.Indirect(reflect.ValueOf(data))
462	size := dataSize(v)
463	if size < 0 {
464		return nil, errors.New("binary.Append: some values are not fixed-sized in type " + reflect.TypeOf(data).String())
465	}
466
467	buf, pos := ensure(buf, size)
468	e := &encoder{order: order, buf: pos}
469	e.value(v)
470	return buf, nil
471}
472
473func encodeFast(bs []byte, order ByteOrder, data any) {
474	switch v := data.(type) {
475	case *bool:
476		if *v {
477			bs[0] = 1
478		} else {
479			bs[0] = 0
480		}
481	case bool:
482		if v {
483			bs[0] = 1
484		} else {
485			bs[0] = 0
486		}
487	case []bool:
488		for i, x := range v {
489			if x {
490				bs[i] = 1
491			} else {
492				bs[i] = 0
493			}
494		}
495	case *int8:
496		bs[0] = byte(*v)
497	case int8:
498		bs[0] = byte(v)
499	case []int8:
500		for i, x := range v {
501			bs[i] = byte(x)
502		}
503	case *uint8:
504		bs[0] = *v
505	case uint8:
506		bs[0] = v
507	case []uint8:
508		copy(bs, v)
509	case *int16:
510		order.PutUint16(bs, uint16(*v))
511	case int16:
512		order.PutUint16(bs, uint16(v))
513	case []int16:
514		for i, x := range v {
515			order.PutUint16(bs[2*i:], uint16(x))
516		}
517	case *uint16:
518		order.PutUint16(bs, *v)
519	case uint16:
520		order.PutUint16(bs, v)
521	case []uint16:
522		for i, x := range v {
523			order.PutUint16(bs[2*i:], x)
524		}
525	case *int32:
526		order.PutUint32(bs, uint32(*v))
527	case int32:
528		order.PutUint32(bs, uint32(v))
529	case []int32:
530		for i, x := range v {
531			order.PutUint32(bs[4*i:], uint32(x))
532		}
533	case *uint32:
534		order.PutUint32(bs, *v)
535	case uint32:
536		order.PutUint32(bs, v)
537	case []uint32:
538		for i, x := range v {
539			order.PutUint32(bs[4*i:], x)
540		}
541	case *int64:
542		order.PutUint64(bs, uint64(*v))
543	case int64:
544		order.PutUint64(bs, uint64(v))
545	case []int64:
546		for i, x := range v {
547			order.PutUint64(bs[8*i:], uint64(x))
548		}
549	case *uint64:
550		order.PutUint64(bs, *v)
551	case uint64:
552		order.PutUint64(bs, v)
553	case []uint64:
554		for i, x := range v {
555			order.PutUint64(bs[8*i:], x)
556		}
557	case *float32:
558		order.PutUint32(bs, math.Float32bits(*v))
559	case float32:
560		order.PutUint32(bs, math.Float32bits(v))
561	case []float32:
562		for i, x := range v {
563			order.PutUint32(bs[4*i:], math.Float32bits(x))
564		}
565	case *float64:
566		order.PutUint64(bs, math.Float64bits(*v))
567	case float64:
568		order.PutUint64(bs, math.Float64bits(v))
569	case []float64:
570		for i, x := range v {
571			order.PutUint64(bs[8*i:], math.Float64bits(x))
572		}
573	}
574}
575
576// Size returns how many bytes [Write] would generate to encode the value v, which
577// must be a fixed-size value or a slice of fixed-size values, or a pointer to such data.
578// If v is neither of these, Size returns -1.
579func Size(v any) int {
580	switch data := v.(type) {
581	case bool, int8, uint8:
582		return 1
583	case *bool:
584		if data == nil {
585			return -1
586		}
587		return 1
588	case *int8:
589		if data == nil {
590			return -1
591		}
592		return 1
593	case *uint8:
594		if data == nil {
595			return -1
596		}
597		return 1
598	case []bool:
599		return len(data)
600	case []int8:
601		return len(data)
602	case []uint8:
603		return len(data)
604	case int16, uint16:
605		return 2
606	case *int16:
607		if data == nil {
608			return -1
609		}
610		return 2
611	case *uint16:
612		if data == nil {
613			return -1
614		}
615		return 2
616	case []int16:
617		return 2 * len(data)
618	case []uint16:
619		return 2 * len(data)
620	case int32, uint32:
621		return 4
622	case *int32:
623		if data == nil {
624			return -1
625		}
626		return 4
627	case *uint32:
628		if data == nil {
629			return -1
630		}
631		return 4
632	case []int32:
633		return 4 * len(data)
634	case []uint32:
635		return 4 * len(data)
636	case int64, uint64:
637		return 8
638	case *int64:
639		if data == nil {
640			return -1
641		}
642		return 8
643	case *uint64:
644		if data == nil {
645			return -1
646		}
647		return 8
648	case []int64:
649		return 8 * len(data)
650	case []uint64:
651		return 8 * len(data)
652	case float32:
653		return 4
654	case *float32:
655		if data == nil {
656			return -1
657		}
658		return 4
659	case float64:
660		return 8
661	case *float64:
662		if data == nil {
663			return -1
664		}
665		return 8
666	case []float32:
667		return 4 * len(data)
668	case []float64:
669		return 8 * len(data)
670	}
671	return dataSize(reflect.Indirect(reflect.ValueOf(v)))
672}
673
674var structSize sync.Map // map[reflect.Type]int
675
676// dataSize returns the number of bytes the actual data represented by v occupies in memory.
677// For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice
678// it returns the length of the slice times the element size and does not count the memory
679// occupied by the header. If the type of v is not acceptable, dataSize returns -1.
680func dataSize(v reflect.Value) int {
681	switch v.Kind() {
682	case reflect.Slice, reflect.Array:
683		t := v.Type().Elem()
684		if size, ok := structSize.Load(t); ok {
685			return size.(int) * v.Len()
686		}
687
688		size := sizeof(t)
689		if size >= 0 {
690			if t.Kind() == reflect.Struct {
691				structSize.Store(t, size)
692			}
693			return size * v.Len()
694		}
695
696	case reflect.Struct:
697		t := v.Type()
698		if size, ok := structSize.Load(t); ok {
699			return size.(int)
700		}
701		size := sizeof(t)
702		structSize.Store(t, size)
703		return size
704
705	default:
706		if v.IsValid() {
707			return sizeof(v.Type())
708		}
709	}
710
711	return -1
712}
713
714// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable.
715func sizeof(t reflect.Type) int {
716	switch t.Kind() {
717	case reflect.Array:
718		if s := sizeof(t.Elem()); s >= 0 {
719			return s * t.Len()
720		}
721
722	case reflect.Struct:
723		sum := 0
724		for i, n := 0, t.NumField(); i < n; i++ {
725			s := sizeof(t.Field(i).Type)
726			if s < 0 {
727				return -1
728			}
729			sum += s
730		}
731		return sum
732
733	case reflect.Bool,
734		reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
735		reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
736		reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
737		return int(t.Size())
738	}
739
740	return -1
741}
742
743type coder struct {
744	order  ByteOrder
745	buf    []byte
746	offset int
747}
748
749type decoder coder
750type encoder coder
751
752func (d *decoder) bool() bool {
753	x := d.buf[d.offset]
754	d.offset++
755	return x != 0
756}
757
758func (e *encoder) bool(x bool) {
759	if x {
760		e.buf[e.offset] = 1
761	} else {
762		e.buf[e.offset] = 0
763	}
764	e.offset++
765}
766
767func (d *decoder) uint8() uint8 {
768	x := d.buf[d.offset]
769	d.offset++
770	return x
771}
772
773func (e *encoder) uint8(x uint8) {
774	e.buf[e.offset] = x
775	e.offset++
776}
777
778func (d *decoder) uint16() uint16 {
779	x := d.order.Uint16(d.buf[d.offset : d.offset+2])
780	d.offset += 2
781	return x
782}
783
784func (e *encoder) uint16(x uint16) {
785	e.order.PutUint16(e.buf[e.offset:e.offset+2], x)
786	e.offset += 2
787}
788
789func (d *decoder) uint32() uint32 {
790	x := d.order.Uint32(d.buf[d.offset : d.offset+4])
791	d.offset += 4
792	return x
793}
794
795func (e *encoder) uint32(x uint32) {
796	e.order.PutUint32(e.buf[e.offset:e.offset+4], x)
797	e.offset += 4
798}
799
800func (d *decoder) uint64() uint64 {
801	x := d.order.Uint64(d.buf[d.offset : d.offset+8])
802	d.offset += 8
803	return x
804}
805
806func (e *encoder) uint64(x uint64) {
807	e.order.PutUint64(e.buf[e.offset:e.offset+8], x)
808	e.offset += 8
809}
810
811func (d *decoder) int8() int8 { return int8(d.uint8()) }
812
813func (e *encoder) int8(x int8) { e.uint8(uint8(x)) }
814
815func (d *decoder) int16() int16 { return int16(d.uint16()) }
816
817func (e *encoder) int16(x int16) { e.uint16(uint16(x)) }
818
819func (d *decoder) int32() int32 { return int32(d.uint32()) }
820
821func (e *encoder) int32(x int32) { e.uint32(uint32(x)) }
822
823func (d *decoder) int64() int64 { return int64(d.uint64()) }
824
825func (e *encoder) int64(x int64) { e.uint64(uint64(x)) }
826
827func (d *decoder) value(v reflect.Value) {
828	switch v.Kind() {
829	case reflect.Array:
830		l := v.Len()
831		for i := 0; i < l; i++ {
832			d.value(v.Index(i))
833		}
834
835	case reflect.Struct:
836		t := v.Type()
837		l := v.NumField()
838		for i := 0; i < l; i++ {
839			// Note: Calling v.CanSet() below is an optimization.
840			// It would be sufficient to check the field name,
841			// but creating the StructField info for each field is
842			// costly (run "go test -bench=ReadStruct" and compare
843			// results when making changes to this code).
844			if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
845				d.value(v)
846			} else {
847				d.skip(v)
848			}
849		}
850
851	case reflect.Slice:
852		l := v.Len()
853		for i := 0; i < l; i++ {
854			d.value(v.Index(i))
855		}
856
857	case reflect.Bool:
858		v.SetBool(d.bool())
859
860	case reflect.Int8:
861		v.SetInt(int64(d.int8()))
862	case reflect.Int16:
863		v.SetInt(int64(d.int16()))
864	case reflect.Int32:
865		v.SetInt(int64(d.int32()))
866	case reflect.Int64:
867		v.SetInt(d.int64())
868
869	case reflect.Uint8:
870		v.SetUint(uint64(d.uint8()))
871	case reflect.Uint16:
872		v.SetUint(uint64(d.uint16()))
873	case reflect.Uint32:
874		v.SetUint(uint64(d.uint32()))
875	case reflect.Uint64:
876		v.SetUint(d.uint64())
877
878	case reflect.Float32:
879		v.SetFloat(float64(math.Float32frombits(d.uint32())))
880	case reflect.Float64:
881		v.SetFloat(math.Float64frombits(d.uint64()))
882
883	case reflect.Complex64:
884		v.SetComplex(complex(
885			float64(math.Float32frombits(d.uint32())),
886			float64(math.Float32frombits(d.uint32())),
887		))
888	case reflect.Complex128:
889		v.SetComplex(complex(
890			math.Float64frombits(d.uint64()),
891			math.Float64frombits(d.uint64()),
892		))
893	}
894}
895
896func (e *encoder) value(v reflect.Value) {
897	switch v.Kind() {
898	case reflect.Array:
899		l := v.Len()
900		for i := 0; i < l; i++ {
901			e.value(v.Index(i))
902		}
903
904	case reflect.Struct:
905		t := v.Type()
906		l := v.NumField()
907		for i := 0; i < l; i++ {
908			// see comment for corresponding code in decoder.value()
909			if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
910				e.value(v)
911			} else {
912				e.skip(v)
913			}
914		}
915
916	case reflect.Slice:
917		l := v.Len()
918		for i := 0; i < l; i++ {
919			e.value(v.Index(i))
920		}
921
922	case reflect.Bool:
923		e.bool(v.Bool())
924
925	case reflect.Int8:
926		e.int8(int8(v.Int()))
927	case reflect.Int16:
928		e.int16(int16(v.Int()))
929	case reflect.Int32:
930		e.int32(int32(v.Int()))
931	case reflect.Int64:
932		e.int64(v.Int())
933
934	case reflect.Uint8:
935		e.uint8(uint8(v.Uint()))
936	case reflect.Uint16:
937		e.uint16(uint16(v.Uint()))
938	case reflect.Uint32:
939		e.uint32(uint32(v.Uint()))
940	case reflect.Uint64:
941		e.uint64(v.Uint())
942
943	case reflect.Float32:
944		e.uint32(math.Float32bits(float32(v.Float())))
945	case reflect.Float64:
946		e.uint64(math.Float64bits(v.Float()))
947
948	case reflect.Complex64:
949		x := v.Complex()
950		e.uint32(math.Float32bits(float32(real(x))))
951		e.uint32(math.Float32bits(float32(imag(x))))
952	case reflect.Complex128:
953		x := v.Complex()
954		e.uint64(math.Float64bits(real(x)))
955		e.uint64(math.Float64bits(imag(x)))
956	}
957}
958
959func (d *decoder) skip(v reflect.Value) {
960	d.offset += dataSize(v)
961}
962
963func (e *encoder) skip(v reflect.Value) {
964	n := dataSize(v)
965	clear(e.buf[e.offset : e.offset+n])
966	e.offset += n
967}
968
969// intDataSize returns the size of the data required to represent the data when encoded,
970// and optionally a byte slice containing the encoded data if no conversion is necessary.
971// It returns zero, nil if the type cannot be implemented by the fast path in Read or Write.
972func intDataSize(data any) (int, []byte) {
973	switch data := data.(type) {
974	case bool, int8, uint8, *bool, *int8, *uint8:
975		return 1, nil
976	case []bool:
977		return len(data), nil
978	case []int8:
979		return len(data), nil
980	case []uint8:
981		return len(data), data
982	case int16, uint16, *int16, *uint16:
983		return 2, nil
984	case []int16:
985		return 2 * len(data), nil
986	case []uint16:
987		return 2 * len(data), nil
988	case int32, uint32, *int32, *uint32:
989		return 4, nil
990	case []int32:
991		return 4 * len(data), nil
992	case []uint32:
993		return 4 * len(data), nil
994	case int64, uint64, *int64, *uint64:
995		return 8, nil
996	case []int64:
997		return 8 * len(data), nil
998	case []uint64:
999		return 8 * len(data), nil
1000	case float32, *float32:
1001		return 4, nil
1002	case float64, *float64:
1003		return 8, nil
1004	case []float32:
1005		return 4 * len(data), nil
1006	case []float64:
1007		return 8 * len(data), nil
1008	}
1009	return 0, nil
1010}
1011
1012// ensure grows buf to length len(buf) + n and returns the grown buffer
1013// and a slice starting at the original length of buf (that is, buf2[len(buf):]).
1014func ensure(buf []byte, n int) (buf2, pos []byte) {
1015	l := len(buf)
1016	buf = slices.Grow(buf, n)[:l+n]
1017	return buf, buf[l:]
1018}
1019