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