github.com/ethereum/go-ethereum@v1.16.1/rlp/raw.go (about)

     1  // Copyright 2015 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  	"io"
    21  	"reflect"
    22  )
    23  
    24  // RawValue represents an encoded RLP value and can be used to delay
    25  // RLP decoding or to precompute an encoding. Note that the decoder does
    26  // not verify whether the content of RawValues is valid RLP.
    27  type RawValue []byte
    28  
    29  var rawValueType = reflect.TypeOf(RawValue{})
    30  
    31  // StringSize returns the encoded size of a string.
    32  func StringSize(s string) uint64 {
    33  	switch n := len(s); n {
    34  	case 0:
    35  		return 1
    36  	case 1:
    37  		if s[0] <= 0x7f {
    38  			return 1
    39  		} else {
    40  			return 2
    41  		}
    42  	default:
    43  		return uint64(headsize(uint64(n)) + n)
    44  	}
    45  }
    46  
    47  // BytesSize returns the encoded size of a byte slice.
    48  func BytesSize(b []byte) uint64 {
    49  	switch n := len(b); n {
    50  	case 0:
    51  		return 1
    52  	case 1:
    53  		if b[0] <= 0x7f {
    54  			return 1
    55  		} else {
    56  			return 2
    57  		}
    58  	default:
    59  		return uint64(headsize(uint64(n)) + n)
    60  	}
    61  }
    62  
    63  // ListSize returns the encoded size of an RLP list with the given
    64  // content size.
    65  func ListSize(contentSize uint64) uint64 {
    66  	return uint64(headsize(contentSize)) + contentSize
    67  }
    68  
    69  // IntSize returns the encoded size of the integer x. Note: The return type of this
    70  // function is 'int' for backwards-compatibility reasons. The result is always positive.
    71  func IntSize(x uint64) int {
    72  	if x < 0x80 {
    73  		return 1
    74  	}
    75  	return 1 + intsize(x)
    76  }
    77  
    78  // Split returns the content of first RLP value and any
    79  // bytes after the value as subslices of b.
    80  func Split(b []byte) (k Kind, content, rest []byte, err error) {
    81  	k, ts, cs, err := readKind(b)
    82  	if err != nil {
    83  		return 0, nil, b, err
    84  	}
    85  	return k, b[ts : ts+cs], b[ts+cs:], nil
    86  }
    87  
    88  // SplitString splits b into the content of an RLP string
    89  // and any remaining bytes after the string.
    90  func SplitString(b []byte) (content, rest []byte, err error) {
    91  	k, content, rest, err := Split(b)
    92  	if err != nil {
    93  		return nil, b, err
    94  	}
    95  	if k == List {
    96  		return nil, b, ErrExpectedString
    97  	}
    98  	return content, rest, nil
    99  }
   100  
   101  // SplitUint64 decodes an integer at the beginning of b.
   102  // It also returns the remaining data after the integer in 'rest'.
   103  func SplitUint64(b []byte) (x uint64, rest []byte, err error) {
   104  	content, rest, err := SplitString(b)
   105  	if err != nil {
   106  		return 0, b, err
   107  	}
   108  	switch n := len(content); n {
   109  	case 0:
   110  		return 0, rest, nil
   111  	case 1:
   112  		if content[0] == 0 {
   113  			return 0, b, ErrCanonInt
   114  		}
   115  		return uint64(content[0]), rest, nil
   116  	default:
   117  		if n > 8 {
   118  			return 0, b, errUintOverflow
   119  		}
   120  
   121  		x, err = readSize(content, byte(n))
   122  		if err != nil {
   123  			return 0, b, ErrCanonInt
   124  		}
   125  		return x, rest, nil
   126  	}
   127  }
   128  
   129  // SplitList splits b into the content of a list and any remaining
   130  // bytes after the list.
   131  func SplitList(b []byte) (content, rest []byte, err error) {
   132  	k, content, rest, err := Split(b)
   133  	if err != nil {
   134  		return nil, b, err
   135  	}
   136  	if k != List {
   137  		return nil, b, ErrExpectedList
   138  	}
   139  	return content, rest, nil
   140  }
   141  
   142  // CountValues counts the number of encoded values in b.
   143  func CountValues(b []byte) (int, error) {
   144  	i := 0
   145  	for ; len(b) > 0; i++ {
   146  		_, tagsize, size, err := readKind(b)
   147  		if err != nil {
   148  			return 0, err
   149  		}
   150  		b = b[tagsize+size:]
   151  	}
   152  	return i, nil
   153  }
   154  
   155  func readKind(buf []byte) (k Kind, tagsize, contentsize uint64, err error) {
   156  	if len(buf) == 0 {
   157  		return 0, 0, 0, io.ErrUnexpectedEOF
   158  	}
   159  	b := buf[0]
   160  	switch {
   161  	case b < 0x80:
   162  		k = Byte
   163  		tagsize = 0
   164  		contentsize = 1
   165  	case b < 0xB8:
   166  		k = String
   167  		tagsize = 1
   168  		contentsize = uint64(b - 0x80)
   169  		// Reject strings that should've been single bytes.
   170  		if contentsize == 1 && len(buf) > 1 && buf[1] < 128 {
   171  			return 0, 0, 0, ErrCanonSize
   172  		}
   173  	case b < 0xC0:
   174  		k = String
   175  		tagsize = uint64(b-0xB7) + 1
   176  		contentsize, err = readSize(buf[1:], b-0xB7)
   177  	case b < 0xF8:
   178  		k = List
   179  		tagsize = 1
   180  		contentsize = uint64(b - 0xC0)
   181  	default:
   182  		k = List
   183  		tagsize = uint64(b-0xF7) + 1
   184  		contentsize, err = readSize(buf[1:], b-0xF7)
   185  	}
   186  	if err != nil {
   187  		return 0, 0, 0, err
   188  	}
   189  	// Reject values larger than the input slice.
   190  	if contentsize > uint64(len(buf))-tagsize {
   191  		return 0, 0, 0, ErrValueTooLarge
   192  	}
   193  	return k, tagsize, contentsize, err
   194  }
   195  
   196  func readSize(b []byte, slen byte) (uint64, error) {
   197  	if int(slen) > len(b) {
   198  		return 0, io.ErrUnexpectedEOF
   199  	}
   200  	var s uint64
   201  	switch slen {
   202  	case 1:
   203  		s = uint64(b[0])
   204  	case 2:
   205  		s = uint64(b[0])<<8 | uint64(b[1])
   206  	case 3:
   207  		s = uint64(b[0])<<16 | uint64(b[1])<<8 | uint64(b[2])
   208  	case 4:
   209  		s = uint64(b[0])<<24 | uint64(b[1])<<16 | uint64(b[2])<<8 | uint64(b[3])
   210  	case 5:
   211  		s = uint64(b[0])<<32 | uint64(b[1])<<24 | uint64(b[2])<<16 | uint64(b[3])<<8 | uint64(b[4])
   212  	case 6:
   213  		s = uint64(b[0])<<40 | uint64(b[1])<<32 | uint64(b[2])<<24 | uint64(b[3])<<16 | uint64(b[4])<<8 | uint64(b[5])
   214  	case 7:
   215  		s = uint64(b[0])<<48 | uint64(b[1])<<40 | uint64(b[2])<<32 | uint64(b[3])<<24 | uint64(b[4])<<16 | uint64(b[5])<<8 | uint64(b[6])
   216  	case 8:
   217  		s = uint64(b[0])<<56 | uint64(b[1])<<48 | uint64(b[2])<<40 | uint64(b[3])<<32 | uint64(b[4])<<24 | uint64(b[5])<<16 | uint64(b[6])<<8 | uint64(b[7])
   218  	}
   219  	// Reject sizes < 56 (shouldn't have separate size) and sizes with
   220  	// leading zero bytes.
   221  	if s < 56 || b[0] == 0 {
   222  		return 0, ErrCanonSize
   223  	}
   224  	return s, nil
   225  }
   226  
   227  // AppendUint64 appends the RLP encoding of i to b, and returns the resulting slice.
   228  func AppendUint64(b []byte, i uint64) []byte {
   229  	if i == 0 {
   230  		return append(b, 0x80)
   231  	} else if i < 128 {
   232  		return append(b, byte(i))
   233  	}
   234  	switch {
   235  	case i < (1 << 8):
   236  		return append(b, 0x81, byte(i))
   237  	case i < (1 << 16):
   238  		return append(b, 0x82,
   239  			byte(i>>8),
   240  			byte(i),
   241  		)
   242  	case i < (1 << 24):
   243  		return append(b, 0x83,
   244  			byte(i>>16),
   245  			byte(i>>8),
   246  			byte(i),
   247  		)
   248  	case i < (1 << 32):
   249  		return append(b, 0x84,
   250  			byte(i>>24),
   251  			byte(i>>16),
   252  			byte(i>>8),
   253  			byte(i),
   254  		)
   255  	case i < (1 << 40):
   256  		return append(b, 0x85,
   257  			byte(i>>32),
   258  			byte(i>>24),
   259  			byte(i>>16),
   260  			byte(i>>8),
   261  			byte(i),
   262  		)
   263  
   264  	case i < (1 << 48):
   265  		return append(b, 0x86,
   266  			byte(i>>40),
   267  			byte(i>>32),
   268  			byte(i>>24),
   269  			byte(i>>16),
   270  			byte(i>>8),
   271  			byte(i),
   272  		)
   273  	case i < (1 << 56):
   274  		return append(b, 0x87,
   275  			byte(i>>48),
   276  			byte(i>>40),
   277  			byte(i>>32),
   278  			byte(i>>24),
   279  			byte(i>>16),
   280  			byte(i>>8),
   281  			byte(i),
   282  		)
   283  
   284  	default:
   285  		return append(b, 0x88,
   286  			byte(i>>56),
   287  			byte(i>>48),
   288  			byte(i>>40),
   289  			byte(i>>32),
   290  			byte(i>>24),
   291  			byte(i>>16),
   292  			byte(i>>8),
   293  			byte(i),
   294  		)
   295  	}
   296  }