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