github.com/Evolution404/simcore@v1.0.0/rlp/encode.go (about)

     1  // Copyright 2014 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package rlp
    18  
    19  import (
    20  	"fmt"
    21  	"io"
    22  	"math/big"
    23  	"reflect"
    24  	"sync"
    25  )
    26  
    27  var (
    28  	// Common encoded values.
    29  	// These are useful when implementing EncodeRLP.
    30  	EmptyString = []byte{0x80}
    31  	EmptyList   = []byte{0xC0}
    32  )
    33  
    34  // Encoder is implemented by types that require custom
    35  // encoding rules or want to encode private fields.
    36  // 实现了EncodeRLP方法的对象将优先调用该方法进行RLP编码
    37  type Encoder interface {
    38  	// EncodeRLP should write the RLP encoding of its receiver to w.
    39  	// If the implementation is a pointer method, it may also be
    40  	// called for nil pointers.
    41  	//
    42  	// Implementations should generate valid RLP. The data written is
    43  	// not verified at the moment, but a future version might. It is
    44  	// recommended to write only a single value but writing multiple
    45  	// values or no value at all is also permitted.
    46  	EncodeRLP(io.Writer) error
    47  }
    48  
    49  // Encode writes the RLP encoding of val to w. Note that Encode may
    50  // perform many small writes in some cases. Consider making w
    51  // buffered.
    52  //
    53  // Please see package-level documentation of encoding rules.
    54  func Encode(w io.Writer, val interface{}) error {
    55  	if outer, ok := w.(*encbuf); ok {
    56  		// Encode was called by some type's EncodeRLP.
    57  		// Avoid copying by writing to the outer encbuf directly.
    58  		return outer.encode(val)
    59  	}
    60  	eb := encbufPool.Get().(*encbuf)
    61  	defer encbufPool.Put(eb)
    62  	eb.reset()
    63  	if err := eb.encode(val); err != nil {
    64  		return err
    65  	}
    66  	return eb.toWriter(w)
    67  }
    68  
    69  // EncodeToBytes returns the RLP encoding of val.
    70  // Please see package-level documentation for the encoding rules.
    71  func EncodeToBytes(val interface{}) ([]byte, error) {
    72  	eb := encbufPool.Get().(*encbuf)
    73  	defer encbufPool.Put(eb)
    74  	eb.reset()
    75  	if err := eb.encode(val); err != nil {
    76  		return nil, err
    77  	}
    78  	return eb.toBytes(), nil
    79  }
    80  
    81  // EncodeToReader returns a reader from which the RLP encoding of val
    82  // can be read. The returned size is the total size of the encoded
    83  // data.
    84  //
    85  // Please see the documentation of Encode for the encoding rules.
    86  func EncodeToReader(val interface{}) (size int, r io.Reader, err error) {
    87  	eb := encbufPool.Get().(*encbuf)
    88  	eb.reset()
    89  	if err := eb.encode(val); err != nil {
    90  		return 0, nil, err
    91  	}
    92  	return eb.size(), &encReader{buf: eb}, nil
    93  }
    94  
    95  type listhead struct {
    96  	offset int // index of this header in string data
    97  	size   int // total size of encoded data (including list headers)
    98  }
    99  
   100  // encode writes head to the given buffer, which must be at least
   101  // 9 bytes long. It returns the encoded bytes.
   102  func (head *listhead) encode(buf []byte) []byte {
   103  	return buf[:puthead(buf, 0xC0, 0xF7, uint64(head.size))]
   104  }
   105  
   106  // headsize returns the size of a list or string header
   107  // for a value of the given size.
   108  func headsize(size uint64) int {
   109  	if size < 56 {
   110  		return 1
   111  	}
   112  	return 1 + intsize(size)
   113  }
   114  
   115  // puthead writes a list or string header to buf.
   116  // buf must be at least 9 bytes long.
   117  func puthead(buf []byte, smalltag, largetag byte, size uint64) int {
   118  	if size < 56 {
   119  		buf[0] = smalltag + byte(size)
   120  		return 1
   121  	}
   122  	sizesize := putint(buf[1:], size)
   123  	buf[0] = largetag + byte(sizesize)
   124  	return sizesize + 1
   125  }
   126  
   127  type encbuf struct {
   128  	str     []byte     // string data, contains everything except list headers
   129  	lheads  []listhead // all list headers
   130  	lhsize  int        // sum of sizes of all encoded list headers
   131  	sizebuf [9]byte    // auxiliary buffer for uint encoding
   132  }
   133  
   134  // encbufs are pooled.
   135  var encbufPool = sync.Pool{
   136  	New: func() interface{} { return new(encbuf) },
   137  }
   138  
   139  func (w *encbuf) reset() {
   140  	w.lhsize = 0
   141  	w.str = w.str[:0]
   142  	w.lheads = w.lheads[:0]
   143  }
   144  
   145  // encbuf implements io.Writer so it can be passed it into EncodeRLP.
   146  func (w *encbuf) Write(b []byte) (int, error) {
   147  	w.str = append(w.str, b...)
   148  	return len(b), nil
   149  }
   150  
   151  func (w *encbuf) encode(val interface{}) error {
   152  	rval := reflect.ValueOf(val)
   153  	writer, err := cachedWriter(rval.Type())
   154  	if err != nil {
   155  		return err
   156  	}
   157  	return writer(rval, w)
   158  }
   159  
   160  func (w *encbuf) encodeStringHeader(size int) {
   161  	if size < 56 {
   162  		w.str = append(w.str, 0x80+byte(size))
   163  	} else {
   164  		sizesize := putint(w.sizebuf[1:], uint64(size))
   165  		w.sizebuf[0] = 0xB7 + byte(sizesize)
   166  		w.str = append(w.str, w.sizebuf[:sizesize+1]...)
   167  	}
   168  }
   169  
   170  func (w *encbuf) encodeString(b []byte) {
   171  	if len(b) == 1 && b[0] <= 0x7F {
   172  		// fits single byte, no string header
   173  		w.str = append(w.str, b[0])
   174  	} else {
   175  		w.encodeStringHeader(len(b))
   176  		w.str = append(w.str, b...)
   177  	}
   178  }
   179  
   180  func (w *encbuf) encodeUint(i uint64) {
   181  	if i == 0 {
   182  		w.str = append(w.str, 0x80)
   183  	} else if i < 128 {
   184  		// fits single byte
   185  		w.str = append(w.str, byte(i))
   186  	} else {
   187  		s := putint(w.sizebuf[1:], i)
   188  		w.sizebuf[0] = 0x80 + byte(s)
   189  		w.str = append(w.str, w.sizebuf[:s+1]...)
   190  	}
   191  }
   192  
   193  // list adds a new list header to the header stack. It returns the index
   194  // of the header. The caller must call listEnd with this index after encoding
   195  // the content of the list.
   196  func (w *encbuf) list() int {
   197  	w.lheads = append(w.lheads, listhead{offset: len(w.str), size: w.lhsize})
   198  	return len(w.lheads) - 1
   199  }
   200  
   201  func (w *encbuf) listEnd(index int) {
   202  	lh := &w.lheads[index]
   203  	lh.size = w.size() - lh.offset - lh.size
   204  	if lh.size < 56 {
   205  		w.lhsize++ // length encoded into kind tag
   206  	} else {
   207  		w.lhsize += 1 + intsize(uint64(lh.size))
   208  	}
   209  }
   210  
   211  func (w *encbuf) size() int {
   212  	return len(w.str) + w.lhsize
   213  }
   214  
   215  func (w *encbuf) toBytes() []byte {
   216  	out := make([]byte, w.size())
   217  	strpos := 0
   218  	pos := 0
   219  	for _, head := range w.lheads {
   220  		// write string data before header
   221  		n := copy(out[pos:], w.str[strpos:head.offset])
   222  		pos += n
   223  		strpos += n
   224  		// write the header
   225  		enc := head.encode(out[pos:])
   226  		pos += len(enc)
   227  	}
   228  	// copy string data after the last list header
   229  	copy(out[pos:], w.str[strpos:])
   230  	return out
   231  }
   232  
   233  func (w *encbuf) toWriter(out io.Writer) (err error) {
   234  	strpos := 0
   235  	for _, head := range w.lheads {
   236  		// write string data before header
   237  		if head.offset-strpos > 0 {
   238  			n, err := out.Write(w.str[strpos:head.offset])
   239  			strpos += n
   240  			if err != nil {
   241  				return err
   242  			}
   243  		}
   244  		// write the header
   245  		enc := head.encode(w.sizebuf[:])
   246  		if _, err = out.Write(enc); err != nil {
   247  			return err
   248  		}
   249  	}
   250  	if strpos < len(w.str) {
   251  		// write string data after the last list header
   252  		_, err = out.Write(w.str[strpos:])
   253  	}
   254  	return err
   255  }
   256  
   257  // encReader is the io.Reader returned by EncodeToReader.
   258  // It releases its encbuf at EOF.
   259  type encReader struct {
   260  	buf    *encbuf // the buffer we're reading from. this is nil when we're at EOF.
   261  	lhpos  int     // index of list header that we're reading
   262  	strpos int     // current position in string buffer
   263  	piece  []byte  // next piece to be read
   264  }
   265  
   266  func (r *encReader) Read(b []byte) (n int, err error) {
   267  	for {
   268  		if r.piece = r.next(); r.piece == nil {
   269  			// Put the encode buffer back into the pool at EOF when it
   270  			// is first encountered. Subsequent calls still return EOF
   271  			// as the error but the buffer is no longer valid.
   272  			if r.buf != nil {
   273  				encbufPool.Put(r.buf)
   274  				r.buf = nil
   275  			}
   276  			return n, io.EOF
   277  		}
   278  		nn := copy(b[n:], r.piece)
   279  		n += nn
   280  		if nn < len(r.piece) {
   281  			// piece didn't fit, see you next time.
   282  			r.piece = r.piece[nn:]
   283  			return n, nil
   284  		}
   285  		r.piece = nil
   286  	}
   287  }
   288  
   289  // next returns the next piece of data to be read.
   290  // it returns nil at EOF.
   291  func (r *encReader) next() []byte {
   292  	switch {
   293  	case r.buf == nil:
   294  		return nil
   295  
   296  	case r.piece != nil:
   297  		// There is still data available for reading.
   298  		return r.piece
   299  
   300  	case r.lhpos < len(r.buf.lheads):
   301  		// We're before the last list header.
   302  		head := r.buf.lheads[r.lhpos]
   303  		sizebefore := head.offset - r.strpos
   304  		if sizebefore > 0 {
   305  			// String data before header.
   306  			p := r.buf.str[r.strpos:head.offset]
   307  			r.strpos += sizebefore
   308  			return p
   309  		}
   310  		r.lhpos++
   311  		return head.encode(r.buf.sizebuf[:])
   312  
   313  	case r.strpos < len(r.buf.str):
   314  		// String data at the end, after all list headers.
   315  		p := r.buf.str[r.strpos:]
   316  		r.strpos = len(r.buf.str)
   317  		return p
   318  
   319  	default:
   320  		return nil
   321  	}
   322  }
   323  
   324  var encoderInterface = reflect.TypeOf(new(Encoder)).Elem()
   325  
   326  // makeWriter creates a writer function for the given type.
   327  func makeWriter(typ reflect.Type, ts tags) (writer, error) {
   328  	kind := typ.Kind()
   329  	switch {
   330  	case typ == rawValueType:
   331  		return writeRawValue, nil
   332  	case typ.AssignableTo(reflect.PtrTo(bigInt)):
   333  		return writeBigIntPtr, nil
   334  	case typ.AssignableTo(bigInt):
   335  		return writeBigIntNoPtr, nil
   336  	case kind == reflect.Ptr:
   337  		return makePtrWriter(typ, ts)
   338  	case reflect.PtrTo(typ).Implements(encoderInterface):
   339  		return makeEncoderWriter(typ), nil
   340  	case isUint(kind):
   341  		return writeUint, nil
   342  	case kind == reflect.Bool:
   343  		return writeBool, nil
   344  	case kind == reflect.String:
   345  		return writeString, nil
   346  	case kind == reflect.Slice && isByte(typ.Elem()):
   347  		return writeBytes, nil
   348  	case kind == reflect.Array && isByte(typ.Elem()):
   349  		return makeByteArrayWriter(typ), nil
   350  	case kind == reflect.Slice || kind == reflect.Array:
   351  		return makeSliceWriter(typ, ts)
   352  	case kind == reflect.Struct:
   353  		return makeStructWriter(typ)
   354  	case kind == reflect.Interface:
   355  		return writeInterface, nil
   356  	default:
   357  		return nil, fmt.Errorf("rlp: type %v is not RLP-serializable", typ)
   358  	}
   359  }
   360  
   361  func writeRawValue(val reflect.Value, w *encbuf) error {
   362  	w.str = append(w.str, val.Bytes()...)
   363  	return nil
   364  }
   365  
   366  func writeUint(val reflect.Value, w *encbuf) error {
   367  	w.encodeUint(val.Uint())
   368  	return nil
   369  }
   370  
   371  func writeBool(val reflect.Value, w *encbuf) error {
   372  	if val.Bool() {
   373  		w.str = append(w.str, 0x01)
   374  	} else {
   375  		w.str = append(w.str, 0x80)
   376  	}
   377  	return nil
   378  }
   379  
   380  func writeBigIntPtr(val reflect.Value, w *encbuf) error {
   381  	ptr := val.Interface().(*big.Int)
   382  	if ptr == nil {
   383  		w.str = append(w.str, 0x80)
   384  		return nil
   385  	}
   386  	return writeBigInt(ptr, w)
   387  }
   388  
   389  func writeBigIntNoPtr(val reflect.Value, w *encbuf) error {
   390  	i := val.Interface().(big.Int)
   391  	return writeBigInt(&i, w)
   392  }
   393  
   394  // wordBytes is the number of bytes in a big.Word
   395  const wordBytes = (32 << (uint64(^big.Word(0)) >> 63)) / 8
   396  
   397  func writeBigInt(i *big.Int, w *encbuf) error {
   398  	if i.Sign() == -1 {
   399  		return fmt.Errorf("rlp: cannot encode negative *big.Int")
   400  	}
   401  	bitlen := i.BitLen()
   402  	if bitlen <= 64 {
   403  		w.encodeUint(i.Uint64())
   404  		return nil
   405  	}
   406  	// Integer is larger than 64 bits, encode from i.Bits().
   407  	// The minimal byte length is bitlen rounded up to the next
   408  	// multiple of 8, divided by 8.
   409  	length := ((bitlen + 7) & -8) >> 3
   410  	w.encodeStringHeader(length)
   411  	w.str = append(w.str, make([]byte, length)...)
   412  	index := length
   413  	buf := w.str[len(w.str)-length:]
   414  	for _, d := range i.Bits() {
   415  		for j := 0; j < wordBytes && index > 0; j++ {
   416  			index--
   417  			buf[index] = byte(d)
   418  			d >>= 8
   419  		}
   420  	}
   421  	return nil
   422  }
   423  
   424  func writeBytes(val reflect.Value, w *encbuf) error {
   425  	w.encodeString(val.Bytes())
   426  	return nil
   427  }
   428  
   429  func makeByteArrayWriter(typ reflect.Type) writer {
   430  	switch typ.Len() {
   431  	case 0:
   432  		return writeLengthZeroByteArray
   433  	case 1:
   434  		return writeLengthOneByteArray
   435  	default:
   436  		length := typ.Len()
   437  		return func(val reflect.Value, w *encbuf) error {
   438  			if !val.CanAddr() {
   439  				// Getting the byte slice of val requires it to be addressable. Make it
   440  				// addressable by copying.
   441  				copy := reflect.New(val.Type()).Elem()
   442  				copy.Set(val)
   443  				val = copy
   444  			}
   445  			slice := byteArrayBytes(val, length)
   446  			w.encodeStringHeader(len(slice))
   447  			w.str = append(w.str, slice...)
   448  			return nil
   449  		}
   450  	}
   451  }
   452  
   453  func writeLengthZeroByteArray(val reflect.Value, w *encbuf) error {
   454  	w.str = append(w.str, 0x80)
   455  	return nil
   456  }
   457  
   458  func writeLengthOneByteArray(val reflect.Value, w *encbuf) error {
   459  	b := byte(val.Index(0).Uint())
   460  	if b <= 0x7f {
   461  		w.str = append(w.str, b)
   462  	} else {
   463  		w.str = append(w.str, 0x81, b)
   464  	}
   465  	return nil
   466  }
   467  
   468  func writeString(val reflect.Value, w *encbuf) error {
   469  	s := val.String()
   470  	if len(s) == 1 && s[0] <= 0x7f {
   471  		// fits single byte, no string header
   472  		w.str = append(w.str, s[0])
   473  	} else {
   474  		w.encodeStringHeader(len(s))
   475  		w.str = append(w.str, s...)
   476  	}
   477  	return nil
   478  }
   479  
   480  func writeInterface(val reflect.Value, w *encbuf) error {
   481  	if val.IsNil() {
   482  		// Write empty list. This is consistent with the previous RLP
   483  		// encoder that we had and should therefore avoid any
   484  		// problems.
   485  		w.str = append(w.str, 0xC0)
   486  		return nil
   487  	}
   488  	eval := val.Elem()
   489  	writer, err := cachedWriter(eval.Type())
   490  	if err != nil {
   491  		return err
   492  	}
   493  	return writer(eval, w)
   494  }
   495  
   496  func makeSliceWriter(typ reflect.Type, ts tags) (writer, error) {
   497  	etypeinfo := theTC.infoWhileGenerating(typ.Elem(), tags{})
   498  	if etypeinfo.writerErr != nil {
   499  		return nil, etypeinfo.writerErr
   500  	}
   501  
   502  	var wfn writer
   503  	if ts.tail {
   504  		// This is for struct tail slices.
   505  		// w.list is not called for them.
   506  		wfn = func(val reflect.Value, w *encbuf) error {
   507  			vlen := val.Len()
   508  			for i := 0; i < vlen; i++ {
   509  				if err := etypeinfo.writer(val.Index(i), w); err != nil {
   510  					return err
   511  				}
   512  			}
   513  			return nil
   514  		}
   515  	} else {
   516  		// This is for regular slices and arrays.
   517  		wfn = func(val reflect.Value, w *encbuf) error {
   518  			vlen := val.Len()
   519  			if vlen == 0 {
   520  				w.str = append(w.str, 0xC0)
   521  				return nil
   522  			}
   523  			listOffset := w.list()
   524  			for i := 0; i < vlen; i++ {
   525  				if err := etypeinfo.writer(val.Index(i), w); err != nil {
   526  					return err
   527  				}
   528  			}
   529  			w.listEnd(listOffset)
   530  			return nil
   531  		}
   532  	}
   533  	return wfn, nil
   534  }
   535  
   536  func makeStructWriter(typ reflect.Type) (writer, error) {
   537  	fields, err := structFields(typ)
   538  	if err != nil {
   539  		return nil, err
   540  	}
   541  	for _, f := range fields {
   542  		if f.info.writerErr != nil {
   543  			return nil, structFieldError{typ, f.index, f.info.writerErr}
   544  		}
   545  	}
   546  
   547  	var writer writer
   548  	firstOptionalField := firstOptionalField(fields)
   549  	if firstOptionalField == len(fields) {
   550  		// This is the writer function for structs without any optional fields.
   551  		writer = func(val reflect.Value, w *encbuf) error {
   552  			lh := w.list()
   553  			for _, f := range fields {
   554  				if err := f.info.writer(val.Field(f.index), w); err != nil {
   555  					return err
   556  				}
   557  			}
   558  			w.listEnd(lh)
   559  			return nil
   560  		}
   561  	} else {
   562  		// If there are any "optional" fields, the writer needs to perform additional
   563  		// checks to determine the output list length.
   564  		writer = func(val reflect.Value, w *encbuf) error {
   565  			lastField := len(fields) - 1
   566  			for ; lastField >= firstOptionalField; lastField-- {
   567  				if !val.Field(fields[lastField].index).IsZero() {
   568  					break
   569  				}
   570  			}
   571  			lh := w.list()
   572  			for i := 0; i <= lastField; i++ {
   573  				if err := fields[i].info.writer(val.Field(fields[i].index), w); err != nil {
   574  					return err
   575  				}
   576  			}
   577  			w.listEnd(lh)
   578  			return nil
   579  		}
   580  	}
   581  	return writer, nil
   582  }
   583  
   584  // nilEncoding returns the encoded value of a nil pointer.
   585  func nilEncoding(typ reflect.Type, ts tags) uint8 {
   586  	var nilKind Kind
   587  	if ts.nilOK {
   588  		nilKind = ts.nilKind // use struct tag if provided
   589  	} else {
   590  		nilKind = defaultNilKind(typ.Elem())
   591  	}
   592  
   593  	switch nilKind {
   594  	case String:
   595  		return 0x80
   596  	case List:
   597  		return 0xC0
   598  	default:
   599  		panic(fmt.Errorf("rlp: invalid nil kind %d", nilKind))
   600  	}
   601  }
   602  
   603  func makePtrWriter(typ reflect.Type, ts tags) (writer, error) {
   604  	etypeinfo := theTC.infoWhileGenerating(typ.Elem(), tags{})
   605  	if etypeinfo.writerErr != nil {
   606  		return nil, etypeinfo.writerErr
   607  	}
   608  	nilEncoding := nilEncoding(typ, ts)
   609  
   610  	writer := func(val reflect.Value, w *encbuf) error {
   611  		if ev := val.Elem(); ev.IsValid() {
   612  			return etypeinfo.writer(ev, w)
   613  		}
   614  		w.str = append(w.str, nilEncoding)
   615  		return nil
   616  	}
   617  	return writer, nil
   618  }
   619  
   620  func makeEncoderWriter(typ reflect.Type) writer {
   621  	if typ.Implements(encoderInterface) {
   622  		return func(val reflect.Value, w *encbuf) error {
   623  			return val.Interface().(Encoder).EncodeRLP(w)
   624  		}
   625  	}
   626  	w := func(val reflect.Value, w *encbuf) error {
   627  		if !val.CanAddr() {
   628  			// package json simply doesn't call MarshalJSON for this case, but encodes the
   629  			// value as if it didn't implement the interface. We don't want to handle it that
   630  			// way.
   631  			return fmt.Errorf("rlp: unadressable value of type %v, EncodeRLP is pointer method", val.Type())
   632  		}
   633  		return val.Addr().Interface().(Encoder).EncodeRLP(w)
   634  	}
   635  	return w
   636  }
   637  
   638  // putint writes i to the beginning of b in big endian byte
   639  // order, using the least number of bytes needed to represent i.
   640  func putint(b []byte, i uint64) (size int) {
   641  	switch {
   642  	case i < (1 << 8):
   643  		b[0] = byte(i)
   644  		return 1
   645  	case i < (1 << 16):
   646  		b[0] = byte(i >> 8)
   647  		b[1] = byte(i)
   648  		return 2
   649  	case i < (1 << 24):
   650  		b[0] = byte(i >> 16)
   651  		b[1] = byte(i >> 8)
   652  		b[2] = byte(i)
   653  		return 3
   654  	case i < (1 << 32):
   655  		b[0] = byte(i >> 24)
   656  		b[1] = byte(i >> 16)
   657  		b[2] = byte(i >> 8)
   658  		b[3] = byte(i)
   659  		return 4
   660  	case i < (1 << 40):
   661  		b[0] = byte(i >> 32)
   662  		b[1] = byte(i >> 24)
   663  		b[2] = byte(i >> 16)
   664  		b[3] = byte(i >> 8)
   665  		b[4] = byte(i)
   666  		return 5
   667  	case i < (1 << 48):
   668  		b[0] = byte(i >> 40)
   669  		b[1] = byte(i >> 32)
   670  		b[2] = byte(i >> 24)
   671  		b[3] = byte(i >> 16)
   672  		b[4] = byte(i >> 8)
   673  		b[5] = byte(i)
   674  		return 6
   675  	case i < (1 << 56):
   676  		b[0] = byte(i >> 48)
   677  		b[1] = byte(i >> 40)
   678  		b[2] = byte(i >> 32)
   679  		b[3] = byte(i >> 24)
   680  		b[4] = byte(i >> 16)
   681  		b[5] = byte(i >> 8)
   682  		b[6] = byte(i)
   683  		return 7
   684  	default:
   685  		b[0] = byte(i >> 56)
   686  		b[1] = byte(i >> 48)
   687  		b[2] = byte(i >> 40)
   688  		b[3] = byte(i >> 32)
   689  		b[4] = byte(i >> 24)
   690  		b[5] = byte(i >> 16)
   691  		b[6] = byte(i >> 8)
   692  		b[7] = byte(i)
   693  		return 8
   694  	}
   695  }
   696  
   697  // intsize computes the minimum number of bytes required to store i.
   698  func intsize(i uint64) (size int) {
   699  	for size = 1; ; size++ {
   700  		if i >>= 8; i == 0 {
   701  			return size
   702  		}
   703  	}
   704  }