github.com/amazechain/amc@v0.1.3/internal/avm/rlp/raw.go (about)

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