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