github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/utils/cser/read_writer.go (about)

     1  package cser
     2  
     3  import (
     4  	"errors"
     5  	"math/big"
     6  
     7  	"github.com/unicornultrafoundation/go-u2u/utils/bits"
     8  	"github.com/unicornultrafoundation/go-u2u/utils/fast"
     9  )
    10  
    11  var (
    12  	ErrNonCanonicalEncoding = errors.New("non canonical encoding")
    13  	ErrMalformedEncoding    = errors.New("malformed encoding")
    14  	ErrTooLargeAlloc        = errors.New("too large allocation")
    15  )
    16  
    17  const MaxAlloc = 100 * 1024
    18  
    19  type Writer struct {
    20  	BitsW  *bits.Writer
    21  	BytesW *fast.Writer
    22  }
    23  
    24  type Reader struct {
    25  	BitsR  *bits.Reader
    26  	BytesR *fast.Reader
    27  }
    28  
    29  func NewWriter() *Writer {
    30  	bbits := &bits.Array{Bytes: make([]byte, 0, 32)}
    31  	bbytes := make([]byte, 0, 200)
    32  	return &Writer{
    33  		BitsW:  bits.NewWriter(bbits),
    34  		BytesW: fast.NewWriter(bbytes),
    35  	}
    36  }
    37  
    38  func writeUint64Compact(bytesW *fast.Writer, v uint64) {
    39  	for i := 0; ; i++ {
    40  		chunk := v & 0b01111111
    41  		v = v >> 7
    42  		if v == 0 {
    43  			// stop flag
    44  			chunk |= 0b10000000
    45  		}
    46  		bytesW.WriteByte(byte(chunk))
    47  		if v == 0 {
    48  			break
    49  		}
    50  	}
    51  	return
    52  }
    53  
    54  func readUint64Compact(bytesR *fast.Reader) uint64 {
    55  	v := uint64(0)
    56  	stop := false
    57  	for i := 0; !stop; i++ {
    58  		chunk := uint64(bytesR.ReadByte())
    59  		stop = (chunk & 0b10000000) != 0
    60  		word := chunk & 0b01111111
    61  		v |= word << (i * 7)
    62  		// last byte cannot be zero
    63  		if i > 0 && stop && word == 0 {
    64  			panic(ErrNonCanonicalEncoding)
    65  		}
    66  	}
    67  
    68  	return v
    69  }
    70  
    71  func writeUint64BitCompact(bytesW *fast.Writer, v uint64, minSize int) (size int) {
    72  	for size < minSize || v != 0 {
    73  		bytesW.WriteByte(byte(v))
    74  		size++
    75  		v = v >> 8
    76  	}
    77  	return
    78  }
    79  
    80  func readUint64BitCompact(bytesR *fast.Reader, size int) uint64 {
    81  	var (
    82  		v    uint64
    83  		last byte
    84  	)
    85  	buf := bytesR.Read(size)
    86  	for i, b := range buf {
    87  		v |= uint64(b) << uint(8*i)
    88  		last = b
    89  	}
    90  
    91  	if size > 1 && last == 0 {
    92  		panic(ErrNonCanonicalEncoding)
    93  	}
    94  
    95  	return v
    96  }
    97  
    98  func (r *Reader) U8() uint8 {
    99  	return r.BytesR.ReadByte()
   100  }
   101  
   102  func (w *Writer) U8(v uint8) {
   103  	w.BytesW.WriteByte(v)
   104  }
   105  
   106  func (r *Reader) readU64_bits(minSize int, bitsForSize int) uint64 {
   107  	size := r.BitsR.Read(bitsForSize)
   108  	size += uint(minSize)
   109  	return readUint64BitCompact(r.BytesR, int(size))
   110  }
   111  
   112  func (w *Writer) writeU64_bits(minSize int, bitsForSize int, v uint64) {
   113  	size := writeUint64BitCompact(w.BytesW, v, minSize)
   114  	w.BitsW.Write(bitsForSize, uint(size-minSize))
   115  }
   116  
   117  func (r *Reader) U16() uint16 {
   118  	v64 := r.readU64_bits(1, 1)
   119  	return uint16(v64)
   120  }
   121  
   122  func (w *Writer) U16(v uint16) {
   123  	w.writeU64_bits(1, 1, uint64(v))
   124  }
   125  
   126  func (r *Reader) U32() uint32 {
   127  	v64 := r.readU64_bits(1, 2)
   128  	return uint32(v64)
   129  }
   130  
   131  func (w *Writer) U32(v uint32) {
   132  	w.writeU64_bits(1, 2, uint64(v))
   133  }
   134  
   135  func (r *Reader) U64() uint64 {
   136  	return r.readU64_bits(1, 3)
   137  }
   138  
   139  func (w *Writer) U64(v uint64) {
   140  	w.writeU64_bits(1, 3, v)
   141  }
   142  
   143  func (r *Reader) VarUint() uint64 {
   144  	return r.readU64_bits(1, 3)
   145  }
   146  
   147  func (w *Writer) VarUint(v uint64) {
   148  	w.writeU64_bits(1, 3, v)
   149  }
   150  
   151  func (r *Reader) I64() int64 {
   152  	neg := r.Bool()
   153  	abs := r.U64()
   154  	if neg && abs == 0 {
   155  		panic(ErrNonCanonicalEncoding)
   156  	}
   157  	if neg {
   158  		return -int64(abs)
   159  	}
   160  	return int64(abs)
   161  }
   162  
   163  func (w *Writer) I64(v int64) {
   164  	w.Bool(v < 0)
   165  	if v < 0 {
   166  		w.U64(uint64(-v))
   167  	} else {
   168  		w.U64(uint64(v))
   169  	}
   170  }
   171  
   172  func (r *Reader) U56() uint64 {
   173  	return r.readU64_bits(0, 3)
   174  }
   175  
   176  func (w *Writer) U56(v uint64) {
   177  	const max = 1<<(8*7) - 1
   178  	if v > max {
   179  		panic("Value too big")
   180  	}
   181  	w.writeU64_bits(0, 3, v)
   182  }
   183  
   184  func (r *Reader) Bool() bool {
   185  	u8 := r.BitsR.Read(1)
   186  	return u8 != 0
   187  }
   188  
   189  func (w *Writer) Bool(v bool) {
   190  	u8 := uint(0)
   191  	if v {
   192  		u8 = 1
   193  	}
   194  	w.BitsW.Write(1, u8)
   195  }
   196  
   197  func (r *Reader) FixedBytes(v []byte) {
   198  	buf := r.BytesR.Read(len(v))
   199  	copy(v, buf)
   200  }
   201  
   202  func (w *Writer) FixedBytes(v []byte) {
   203  	w.BytesW.Write(v)
   204  }
   205  
   206  func (r *Reader) SliceBytes(maxLen int) []byte {
   207  	// read slice size
   208  	size := r.U56()
   209  	if size > uint64(maxLen) {
   210  		panic(ErrTooLargeAlloc)
   211  	}
   212  	buf := make([]byte, size)
   213  	// read slice content
   214  	r.FixedBytes(buf)
   215  	return buf
   216  }
   217  
   218  func (w *Writer) SliceBytes(v []byte) {
   219  	// write slice size
   220  	w.U56(uint64(len(v)))
   221  	// write slice content
   222  	w.FixedBytes(v)
   223  }
   224  
   225  // PaddedBytes returns a slice with length of the slice is at least n bytes.
   226  func PaddedBytes(b []byte, n int) []byte {
   227  	if len(b) >= n {
   228  		return b
   229  	}
   230  	padding := make([]byte, n-len(b))
   231  	return append(padding, b...)
   232  }
   233  
   234  func (w *Writer) BigInt(v *big.Int) {
   235  	// serialize as an ordinary slice
   236  	bigBytes := []byte{}
   237  	if v.Sign() != 0 {
   238  		bigBytes = v.Bytes()
   239  	}
   240  	w.SliceBytes(bigBytes)
   241  }
   242  
   243  func (r *Reader) BigInt() *big.Int {
   244  	// deserialize as an ordinary slice
   245  	buf := r.SliceBytes(512)
   246  	if len(buf) == 0 {
   247  		return new(big.Int)
   248  	}
   249  	return new(big.Int).SetBytes(buf)
   250  }