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" }