github.com/core-coin/go-core/v2@v2.1.9/rlp/raw.go (about)

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