github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/gnovm/stdlibs/encoding/binary/binary.gno (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package binary implements simple translation between numbers and byte
     6  // sequences and encoding and decoding of varints.
     7  //
     8  // Numbers are translated by reading and writing fixed-size values.
     9  // A fixed-size value is either a fixed-size arithmetic
    10  // type (bool, int8, uint8, int16, float32, complex64, ...)
    11  // or an array or struct containing only fixed-size values.
    12  //
    13  // The varint functions encode and decode single integer values using
    14  // a variable-length encoding; smaller values require fewer bytes.
    15  // For a specification, see
    16  // https://developers.google.com/protocol-buffers/docs/encoding.
    17  //
    18  // This package favors simplicity over efficiency. Clients that require
    19  // high-performance serialization, especially for large data structures,
    20  // should look at more advanced solutions such as the encoding/gob
    21  // package or protocol buffers.
    22  package binary
    23  
    24  // A ByteOrder specifies how to convert byte slices into
    25  // 16-, 32-, or 64-bit unsigned integers.
    26  type ByteOrder interface {
    27  	Uint16([]byte) uint16
    28  	Uint32([]byte) uint32
    29  	Uint64([]byte) uint64
    30  	PutUint16([]byte, uint16)
    31  	PutUint32([]byte, uint32)
    32  	PutUint64([]byte, uint64)
    33  	String() string
    34  }
    35  
    36  // AppendByteOrder specifies how to append 16-, 32-, or 64-bit unsigned integers
    37  // into a byte slice.
    38  type AppendByteOrder interface {
    39  	AppendUint16([]byte, uint16) []byte
    40  	AppendUint32([]byte, uint32) []byte
    41  	AppendUint64([]byte, uint64) []byte
    42  	String() string
    43  }
    44  
    45  // LittleEndian is the little-endian implementation of ByteOrder and AppendByteOrder.
    46  var LittleEndian littleEndian
    47  
    48  // BigEndian is the big-endian implementation of ByteOrder and AppendByteOrder.
    49  var BigEndian bigEndian
    50  
    51  type littleEndian struct{}
    52  
    53  func (littleEndian) Uint16(b []byte) uint16 {
    54  	_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
    55  	return uint16(b[0]) | uint16(b[1])<<8
    56  }
    57  
    58  func (littleEndian) PutUint16(b []byte, v uint16) {
    59  	_ = b[1] // early bounds check to guarantee safety of writes below
    60  	b[0] = byte(v)
    61  	b[1] = byte(v >> 8)
    62  }
    63  
    64  func (littleEndian) AppendUint16(b []byte, v uint16) []byte {
    65  	return append(b,
    66  		byte(v),
    67  		byte(v>>8),
    68  	)
    69  }
    70  
    71  func (littleEndian) Uint32(b []byte) uint32 {
    72  	_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
    73  	return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
    74  }
    75  
    76  func (littleEndian) PutUint32(b []byte, v uint32) {
    77  	_ = b[3] // early bounds check to guarantee safety of writes below
    78  	b[0] = byte(v)
    79  	b[1] = byte(v >> 8)
    80  	b[2] = byte(v >> 16)
    81  	b[3] = byte(v >> 24)
    82  }
    83  
    84  func (littleEndian) AppendUint32(b []byte, v uint32) []byte {
    85  	return append(b,
    86  		byte(v),
    87  		byte(v>>8),
    88  		byte(v>>16),
    89  		byte(v>>24),
    90  	)
    91  }
    92  
    93  func (littleEndian) Uint64(b []byte) uint64 {
    94  	_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
    95  	return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
    96  		uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
    97  }
    98  
    99  func (littleEndian) PutUint64(b []byte, v uint64) {
   100  	_ = b[7] // early bounds check to guarantee safety of writes below
   101  	b[0] = byte(v)
   102  	b[1] = byte(v >> 8)
   103  	b[2] = byte(v >> 16)
   104  	b[3] = byte(v >> 24)
   105  	b[4] = byte(v >> 32)
   106  	b[5] = byte(v >> 40)
   107  	b[6] = byte(v >> 48)
   108  	b[7] = byte(v >> 56)
   109  }
   110  
   111  func (littleEndian) AppendUint64(b []byte, v uint64) []byte {
   112  	return append(b,
   113  		byte(v),
   114  		byte(v>>8),
   115  		byte(v>>16),
   116  		byte(v>>24),
   117  		byte(v>>32),
   118  		byte(v>>40),
   119  		byte(v>>48),
   120  		byte(v>>56),
   121  	)
   122  }
   123  
   124  func (littleEndian) String() string { return "LittleEndian" }
   125  
   126  func (littleEndian) GoString() string { return "binary.LittleEndian" }
   127  
   128  type bigEndian struct{}
   129  
   130  func (bigEndian) Uint16(b []byte) uint16 {
   131  	_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
   132  	return uint16(b[1]) | uint16(b[0])<<8
   133  }
   134  
   135  func (bigEndian) PutUint16(b []byte, v uint16) {
   136  	_ = b[1] // early bounds check to guarantee safety of writes below
   137  	b[0] = byte(v >> 8)
   138  	b[1] = byte(v)
   139  }
   140  
   141  func (bigEndian) AppendUint16(b []byte, v uint16) []byte {
   142  	return append(b,
   143  		byte(v>>8),
   144  		byte(v),
   145  	)
   146  }
   147  
   148  func (bigEndian) Uint32(b []byte) uint32 {
   149  	_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
   150  	return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
   151  }
   152  
   153  func (bigEndian) PutUint32(b []byte, v uint32) {
   154  	_ = b[3] // early bounds check to guarantee safety of writes below
   155  	b[0] = byte(v >> 24)
   156  	b[1] = byte(v >> 16)
   157  	b[2] = byte(v >> 8)
   158  	b[3] = byte(v)
   159  }
   160  
   161  func (bigEndian) AppendUint32(b []byte, v uint32) []byte {
   162  	return append(b,
   163  		byte(v>>24),
   164  		byte(v>>16),
   165  		byte(v>>8),
   166  		byte(v),
   167  	)
   168  }
   169  
   170  func (bigEndian) Uint64(b []byte) uint64 {
   171  	_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
   172  	return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
   173  		uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
   174  }
   175  
   176  func (bigEndian) PutUint64(b []byte, v uint64) {
   177  	_ = b[7] // early bounds check to guarantee safety of writes below
   178  	b[0] = byte(v >> 56)
   179  	b[1] = byte(v >> 48)
   180  	b[2] = byte(v >> 40)
   181  	b[3] = byte(v >> 32)
   182  	b[4] = byte(v >> 24)
   183  	b[5] = byte(v >> 16)
   184  	b[6] = byte(v >> 8)
   185  	b[7] = byte(v)
   186  }
   187  
   188  func (bigEndian) AppendUint64(b []byte, v uint64) []byte {
   189  	return append(b,
   190  		byte(v>>56),
   191  		byte(v>>48),
   192  		byte(v>>40),
   193  		byte(v>>32),
   194  		byte(v>>24),
   195  		byte(v>>16),
   196  		byte(v>>8),
   197  		byte(v),
   198  	)
   199  }
   200  
   201  func (bigEndian) String() string { return "BigEndian" }
   202  
   203  func (bigEndian) GoString() string { return "binary.BigEndian" }