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