Black Lives Matter. Support the Equal Justice Initiative.

Source file src/encoding/binary/binary.go

Documentation: encoding/binary

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

View as plain text