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