github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/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 func (nativeEndian) String() string { return "NativeEndian" } 214 215 func (nativeEndian) GoString() string { return "binary.NativeEndian" } 216 217 // Read reads structured binary data from r into data. 218 // Data must be a pointer to a fixed-size value or a slice 219 // of fixed-size values. 220 // Bytes read from r are decoded using the specified byte order 221 // and written to successive fields of the data. 222 // When decoding boolean values, a zero byte is decoded as false, and 223 // any other non-zero byte is decoded as true. 224 // When reading into structs, the field data for fields with 225 // blank (_) field names is skipped; i.e., blank field names 226 // may be used for padding. 227 // When reading into a struct, all non-blank fields must be exported 228 // or Read may panic. 229 // 230 // The error is EOF only if no bytes were read. 231 // If an EOF happens after reading some but not all the bytes, 232 // Read returns ErrUnexpectedEOF. 233 func Read(r io.Reader, order ByteOrder, data any) error { 234 // Fast path for basic types and slices. 235 if n := intDataSize(data); n != 0 { 236 bs := make([]byte, n) 237 if _, err := io.ReadFull(r, bs); err != nil { 238 return err 239 } 240 switch data := data.(type) { 241 case *bool: 242 *data = bs[0] != 0 243 case *int8: 244 *data = int8(bs[0]) 245 case *uint8: 246 *data = bs[0] 247 case *int16: 248 *data = int16(order.Uint16(bs)) 249 case *uint16: 250 *data = order.Uint16(bs) 251 case *int32: 252 *data = int32(order.Uint32(bs)) 253 case *uint32: 254 *data = order.Uint32(bs) 255 case *int64: 256 *data = int64(order.Uint64(bs)) 257 case *uint64: 258 *data = order.Uint64(bs) 259 case *float32: 260 *data = math.Float32frombits(order.Uint32(bs)) 261 case *float64: 262 *data = math.Float64frombits(order.Uint64(bs)) 263 case []bool: 264 for i, x := range bs { // Easier to loop over the input for 8-bit values. 265 data[i] = x != 0 266 } 267 case []int8: 268 for i, x := range bs { 269 data[i] = int8(x) 270 } 271 case []uint8: 272 copy(data, bs) 273 case []int16: 274 for i := range data { 275 data[i] = int16(order.Uint16(bs[2*i:])) 276 } 277 case []uint16: 278 for i := range data { 279 data[i] = order.Uint16(bs[2*i:]) 280 } 281 case []int32: 282 for i := range data { 283 data[i] = int32(order.Uint32(bs[4*i:])) 284 } 285 case []uint32: 286 for i := range data { 287 data[i] = order.Uint32(bs[4*i:]) 288 } 289 case []int64: 290 for i := range data { 291 data[i] = int64(order.Uint64(bs[8*i:])) 292 } 293 case []uint64: 294 for i := range data { 295 data[i] = order.Uint64(bs[8*i:]) 296 } 297 case []float32: 298 for i := range data { 299 data[i] = math.Float32frombits(order.Uint32(bs[4*i:])) 300 } 301 case []float64: 302 for i := range data { 303 data[i] = math.Float64frombits(order.Uint64(bs[8*i:])) 304 } 305 default: 306 n = 0 // fast path doesn't apply 307 } 308 if n != 0 { 309 return nil 310 } 311 } 312 313 // Fallback to reflect-based decoding. 314 v := reflect.ValueOf(data) 315 size := -1 316 switch v.Kind() { 317 case reflect.Pointer: 318 v = v.Elem() 319 size = dataSize(v) 320 case reflect.Slice: 321 size = dataSize(v) 322 } 323 if size < 0 { 324 return errors.New("binary.Read: invalid type " + reflect.TypeOf(data).String()) 325 } 326 d := &decoder{order: order, buf: make([]byte, size)} 327 if _, err := io.ReadFull(r, d.buf); err != nil { 328 return err 329 } 330 d.value(v) 331 return nil 332 } 333 334 // Write writes the binary representation of data into w. 335 // Data must be a fixed-size value or a slice of fixed-size 336 // values, or a pointer to such data. 337 // Boolean values encode as one byte: 1 for true, and 0 for false. 338 // Bytes written to w are encoded using the specified byte order 339 // and read from successive fields of the data. 340 // When writing structs, zero values are written for fields 341 // with blank (_) field names. 342 func Write(w io.Writer, order ByteOrder, data any) error { 343 // Fast path for basic types and slices. 344 if n := intDataSize(data); n != 0 { 345 bs := make([]byte, n) 346 switch v := data.(type) { 347 case *bool: 348 if *v { 349 bs[0] = 1 350 } else { 351 bs[0] = 0 352 } 353 case bool: 354 if v { 355 bs[0] = 1 356 } else { 357 bs[0] = 0 358 } 359 case []bool: 360 for i, x := range v { 361 if x { 362 bs[i] = 1 363 } else { 364 bs[i] = 0 365 } 366 } 367 case *int8: 368 bs[0] = byte(*v) 369 case int8: 370 bs[0] = byte(v) 371 case []int8: 372 for i, x := range v { 373 bs[i] = byte(x) 374 } 375 case *uint8: 376 bs[0] = *v 377 case uint8: 378 bs[0] = v 379 case []uint8: 380 bs = v 381 case *int16: 382 order.PutUint16(bs, uint16(*v)) 383 case int16: 384 order.PutUint16(bs, uint16(v)) 385 case []int16: 386 for i, x := range v { 387 order.PutUint16(bs[2*i:], uint16(x)) 388 } 389 case *uint16: 390 order.PutUint16(bs, *v) 391 case uint16: 392 order.PutUint16(bs, v) 393 case []uint16: 394 for i, x := range v { 395 order.PutUint16(bs[2*i:], x) 396 } 397 case *int32: 398 order.PutUint32(bs, uint32(*v)) 399 case int32: 400 order.PutUint32(bs, uint32(v)) 401 case []int32: 402 for i, x := range v { 403 order.PutUint32(bs[4*i:], uint32(x)) 404 } 405 case *uint32: 406 order.PutUint32(bs, *v) 407 case uint32: 408 order.PutUint32(bs, v) 409 case []uint32: 410 for i, x := range v { 411 order.PutUint32(bs[4*i:], x) 412 } 413 case *int64: 414 order.PutUint64(bs, uint64(*v)) 415 case int64: 416 order.PutUint64(bs, uint64(v)) 417 case []int64: 418 for i, x := range v { 419 order.PutUint64(bs[8*i:], uint64(x)) 420 } 421 case *uint64: 422 order.PutUint64(bs, *v) 423 case uint64: 424 order.PutUint64(bs, v) 425 case []uint64: 426 for i, x := range v { 427 order.PutUint64(bs[8*i:], x) 428 } 429 case *float32: 430 order.PutUint32(bs, math.Float32bits(*v)) 431 case float32: 432 order.PutUint32(bs, math.Float32bits(v)) 433 case []float32: 434 for i, x := range v { 435 order.PutUint32(bs[4*i:], math.Float32bits(x)) 436 } 437 case *float64: 438 order.PutUint64(bs, math.Float64bits(*v)) 439 case float64: 440 order.PutUint64(bs, math.Float64bits(v)) 441 case []float64: 442 for i, x := range v { 443 order.PutUint64(bs[8*i:], math.Float64bits(x)) 444 } 445 } 446 _, err := w.Write(bs) 447 return err 448 } 449 450 // Fallback to reflect-based encoding. 451 v := reflect.Indirect(reflect.ValueOf(data)) 452 size := dataSize(v) 453 if size < 0 { 454 return errors.New("binary.Write: some values are not fixed-sized in type " + reflect.TypeOf(data).String()) 455 } 456 buf := make([]byte, size) 457 e := &encoder{order: order, buf: buf} 458 e.value(v) 459 _, err := w.Write(buf) 460 return err 461 } 462 463 // Size returns how many bytes Write would generate to encode the value v, which 464 // must be a fixed-size value or a slice of fixed-size values, or a pointer to such data. 465 // If v is neither of these, Size returns -1. 466 func Size(v any) int { 467 return dataSize(reflect.Indirect(reflect.ValueOf(v))) 468 } 469 470 var structSize sync.Map // map[reflect.Type]int 471 472 // dataSize returns the number of bytes the actual data represented by v occupies in memory. 473 // For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice 474 // it returns the length of the slice times the element size and does not count the memory 475 // occupied by the header. If the type of v is not acceptable, dataSize returns -1. 476 func dataSize(v reflect.Value) int { 477 switch v.Kind() { 478 case reflect.Slice: 479 if s := sizeof(v.Type().Elem()); s >= 0 { 480 return s * v.Len() 481 } 482 return -1 483 484 case reflect.Struct: 485 t := v.Type() 486 if size, ok := structSize.Load(t); ok { 487 return size.(int) 488 } 489 size := sizeof(t) 490 structSize.Store(t, size) 491 return size 492 493 default: 494 return sizeof(v.Type()) 495 } 496 } 497 498 // sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable. 499 func sizeof(t reflect.Type) int { 500 switch t.Kind() { 501 case reflect.Array: 502 if s := sizeof(t.Elem()); s >= 0 { 503 return s * t.Len() 504 } 505 506 case reflect.Struct: 507 sum := 0 508 for i, n := 0, t.NumField(); i < n; i++ { 509 s := sizeof(t.Field(i).Type) 510 if s < 0 { 511 return -1 512 } 513 sum += s 514 } 515 return sum 516 517 case reflect.Bool, 518 reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, 519 reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 520 reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: 521 return int(t.Size()) 522 } 523 524 return -1 525 } 526 527 type coder struct { 528 order ByteOrder 529 buf []byte 530 offset int 531 } 532 533 type decoder coder 534 type encoder coder 535 536 func (d *decoder) bool() bool { 537 x := d.buf[d.offset] 538 d.offset++ 539 return x != 0 540 } 541 542 func (e *encoder) bool(x bool) { 543 if x { 544 e.buf[e.offset] = 1 545 } else { 546 e.buf[e.offset] = 0 547 } 548 e.offset++ 549 } 550 551 func (d *decoder) uint8() uint8 { 552 x := d.buf[d.offset] 553 d.offset++ 554 return x 555 } 556 557 func (e *encoder) uint8(x uint8) { 558 e.buf[e.offset] = x 559 e.offset++ 560 } 561 562 func (d *decoder) uint16() uint16 { 563 x := d.order.Uint16(d.buf[d.offset : d.offset+2]) 564 d.offset += 2 565 return x 566 } 567 568 func (e *encoder) uint16(x uint16) { 569 e.order.PutUint16(e.buf[e.offset:e.offset+2], x) 570 e.offset += 2 571 } 572 573 func (d *decoder) uint32() uint32 { 574 x := d.order.Uint32(d.buf[d.offset : d.offset+4]) 575 d.offset += 4 576 return x 577 } 578 579 func (e *encoder) uint32(x uint32) { 580 e.order.PutUint32(e.buf[e.offset:e.offset+4], x) 581 e.offset += 4 582 } 583 584 func (d *decoder) uint64() uint64 { 585 x := d.order.Uint64(d.buf[d.offset : d.offset+8]) 586 d.offset += 8 587 return x 588 } 589 590 func (e *encoder) uint64(x uint64) { 591 e.order.PutUint64(e.buf[e.offset:e.offset+8], x) 592 e.offset += 8 593 } 594 595 func (d *decoder) int8() int8 { return int8(d.uint8()) } 596 597 func (e *encoder) int8(x int8) { e.uint8(uint8(x)) } 598 599 func (d *decoder) int16() int16 { return int16(d.uint16()) } 600 601 func (e *encoder) int16(x int16) { e.uint16(uint16(x)) } 602 603 func (d *decoder) int32() int32 { return int32(d.uint32()) } 604 605 func (e *encoder) int32(x int32) { e.uint32(uint32(x)) } 606 607 func (d *decoder) int64() int64 { return int64(d.uint64()) } 608 609 func (e *encoder) int64(x int64) { e.uint64(uint64(x)) } 610 611 func (d *decoder) value(v reflect.Value) { 612 switch v.Kind() { 613 case reflect.Array: 614 l := v.Len() 615 for i := 0; i < l; i++ { 616 d.value(v.Index(i)) 617 } 618 619 case reflect.Struct: 620 t := v.Type() 621 l := v.NumField() 622 for i := 0; i < l; i++ { 623 // Note: Calling v.CanSet() below is an optimization. 624 // It would be sufficient to check the field name, 625 // but creating the StructField info for each field is 626 // costly (run "go test -bench=ReadStruct" and compare 627 // results when making changes to this code). 628 if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" { 629 d.value(v) 630 } else { 631 d.skip(v) 632 } 633 } 634 635 case reflect.Slice: 636 l := v.Len() 637 for i := 0; i < l; i++ { 638 d.value(v.Index(i)) 639 } 640 641 case reflect.Bool: 642 v.SetBool(d.bool()) 643 644 case reflect.Int8: 645 v.SetInt(int64(d.int8())) 646 case reflect.Int16: 647 v.SetInt(int64(d.int16())) 648 case reflect.Int32: 649 v.SetInt(int64(d.int32())) 650 case reflect.Int64: 651 v.SetInt(d.int64()) 652 653 case reflect.Uint8: 654 v.SetUint(uint64(d.uint8())) 655 case reflect.Uint16: 656 v.SetUint(uint64(d.uint16())) 657 case reflect.Uint32: 658 v.SetUint(uint64(d.uint32())) 659 case reflect.Uint64: 660 v.SetUint(d.uint64()) 661 662 case reflect.Float32: 663 v.SetFloat(float64(math.Float32frombits(d.uint32()))) 664 case reflect.Float64: 665 v.SetFloat(math.Float64frombits(d.uint64())) 666 667 case reflect.Complex64: 668 v.SetComplex(complex( 669 float64(math.Float32frombits(d.uint32())), 670 float64(math.Float32frombits(d.uint32())), 671 )) 672 case reflect.Complex128: 673 v.SetComplex(complex( 674 math.Float64frombits(d.uint64()), 675 math.Float64frombits(d.uint64()), 676 )) 677 } 678 } 679 680 func (e *encoder) value(v reflect.Value) { 681 switch v.Kind() { 682 case reflect.Array: 683 l := v.Len() 684 for i := 0; i < l; i++ { 685 e.value(v.Index(i)) 686 } 687 688 case reflect.Struct: 689 t := v.Type() 690 l := v.NumField() 691 for i := 0; i < l; i++ { 692 // see comment for corresponding code in decoder.value() 693 if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" { 694 e.value(v) 695 } else { 696 e.skip(v) 697 } 698 } 699 700 case reflect.Slice: 701 l := v.Len() 702 for i := 0; i < l; i++ { 703 e.value(v.Index(i)) 704 } 705 706 case reflect.Bool: 707 e.bool(v.Bool()) 708 709 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 710 switch v.Type().Kind() { 711 case reflect.Int8: 712 e.int8(int8(v.Int())) 713 case reflect.Int16: 714 e.int16(int16(v.Int())) 715 case reflect.Int32: 716 e.int32(int32(v.Int())) 717 case reflect.Int64: 718 e.int64(v.Int()) 719 } 720 721 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 722 switch v.Type().Kind() { 723 case reflect.Uint8: 724 e.uint8(uint8(v.Uint())) 725 case reflect.Uint16: 726 e.uint16(uint16(v.Uint())) 727 case reflect.Uint32: 728 e.uint32(uint32(v.Uint())) 729 case reflect.Uint64: 730 e.uint64(v.Uint()) 731 } 732 733 case reflect.Float32, reflect.Float64: 734 switch v.Type().Kind() { 735 case reflect.Float32: 736 e.uint32(math.Float32bits(float32(v.Float()))) 737 case reflect.Float64: 738 e.uint64(math.Float64bits(v.Float())) 739 } 740 741 case reflect.Complex64, reflect.Complex128: 742 switch v.Type().Kind() { 743 case reflect.Complex64: 744 x := v.Complex() 745 e.uint32(math.Float32bits(float32(real(x)))) 746 e.uint32(math.Float32bits(float32(imag(x)))) 747 case reflect.Complex128: 748 x := v.Complex() 749 e.uint64(math.Float64bits(real(x))) 750 e.uint64(math.Float64bits(imag(x))) 751 } 752 } 753 } 754 755 func (d *decoder) skip(v reflect.Value) { 756 d.offset += dataSize(v) 757 } 758 759 func (e *encoder) skip(v reflect.Value) { 760 n := dataSize(v) 761 zero := e.buf[e.offset : e.offset+n] 762 for i := range zero { 763 zero[i] = 0 764 } 765 e.offset += n 766 } 767 768 // intDataSize returns the size of the data required to represent the data when encoded. 769 // It returns zero if the type cannot be implemented by the fast path in Read or Write. 770 func intDataSize(data any) int { 771 switch data := data.(type) { 772 case bool, int8, uint8, *bool, *int8, *uint8: 773 return 1 774 case []bool: 775 return len(data) 776 case []int8: 777 return len(data) 778 case []uint8: 779 return len(data) 780 case int16, uint16, *int16, *uint16: 781 return 2 782 case []int16: 783 return 2 * len(data) 784 case []uint16: 785 return 2 * len(data) 786 case int32, uint32, *int32, *uint32: 787 return 4 788 case []int32: 789 return 4 * len(data) 790 case []uint32: 791 return 4 * len(data) 792 case int64, uint64, *int64, *uint64: 793 return 8 794 case []int64: 795 return 8 * len(data) 796 case []uint64: 797 return 8 * len(data) 798 case float32, *float32: 799 return 4 800 case float64, *float64: 801 return 8 802 case []float32: 803 return 4 * len(data) 804 case []float64: 805 return 8 * len(data) 806 } 807 return 0 808 }