github.com/decred/dcrlnd@v0.7.6/tlv/primitive.go (about) 1 package tlv 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "io" 7 8 "github.com/decred/dcrd/dcrec/secp256k1/v4" 9 ) 10 11 // ErrTypeForEncoding signals that an incorrect type was passed to an Encoder. 12 type ErrTypeForEncoding struct { 13 val interface{} 14 expType string 15 } 16 17 // NewTypeForEncodingErr creates a new ErrTypeForEncoding given the incorrect 18 // val and the expected type. 19 func NewTypeForEncodingErr(val interface{}, expType string) ErrTypeForEncoding { 20 return ErrTypeForEncoding{ 21 val: val, 22 expType: expType, 23 } 24 } 25 26 // Error returns a human-readable description of the type mismatch. 27 func (e ErrTypeForEncoding) Error() string { 28 return fmt.Sprintf("ErrTypeForEncoding want (type: *%s), "+ 29 "got (type: %T)", e.expType, e.val) 30 } 31 32 // ErrTypeForDecoding signals that an incorrect type was passed to a Decoder or 33 // that the expected length of the encoding is different from that required by 34 // the expected type. 35 type ErrTypeForDecoding struct { 36 val interface{} 37 expType string 38 valLength uint64 39 expLength uint64 40 } 41 42 // NewTypeForDecodingErr creates a new ErrTypeForDecoding given the incorrect 43 // val and expected type, or the mismatch in their expected lengths. 44 func NewTypeForDecodingErr(val interface{}, expType string, 45 valLength, expLength uint64) ErrTypeForDecoding { 46 47 return ErrTypeForDecoding{ 48 val: val, 49 expType: expType, 50 valLength: valLength, 51 expLength: expLength, 52 } 53 } 54 55 // Error returns a human-readable description of the type mismatch. 56 func (e ErrTypeForDecoding) Error() string { 57 return fmt.Sprintf("ErrTypeForDecoding want (type: *%s, length: %v), "+ 58 "got (type: %T, length: %v)", e.expType, e.expLength, e.val, 59 e.valLength) 60 } 61 62 var ( 63 byteOrder = binary.BigEndian 64 ) 65 66 // EUint8 is an Encoder for uint8 values. An error is returned if val is not a 67 // *uint8. 68 func EUint8(w io.Writer, val interface{}, buf *[8]byte) error { 69 if i, ok := val.(*uint8); ok { 70 buf[0] = *i 71 _, err := w.Write(buf[:1]) 72 return err 73 } 74 return NewTypeForEncodingErr(val, "uint8") 75 } 76 77 // EUint8T encodes a uint8 val to the provided io.Writer. This method is exposed 78 // so that encodings for custom uint8-like types can be created without 79 // incurring an extra heap allocation. 80 func EUint8T(w io.Writer, val uint8, buf *[8]byte) error { 81 buf[0] = val 82 _, err := w.Write(buf[:1]) 83 return err 84 } 85 86 // EUint16 is an Encoder for uint16 values. An error is returned if val is not a 87 // *uint16. 88 func EUint16(w io.Writer, val interface{}, buf *[8]byte) error { 89 if i, ok := val.(*uint16); ok { 90 byteOrder.PutUint16(buf[:2], *i) 91 _, err := w.Write(buf[:2]) 92 return err 93 } 94 return NewTypeForEncodingErr(val, "uint16") 95 } 96 97 // EUint16T encodes a uint16 val to the provided io.Writer. This method is 98 // exposed so that encodings for custom uint16-like types can be created without 99 // incurring an extra heap allocation. 100 func EUint16T(w io.Writer, val uint16, buf *[8]byte) error { 101 byteOrder.PutUint16(buf[:2], val) 102 _, err := w.Write(buf[:2]) 103 return err 104 } 105 106 // EUint32 is an Encoder for uint32 values. An error is returned if val is not a 107 // *uint32. 108 func EUint32(w io.Writer, val interface{}, buf *[8]byte) error { 109 if i, ok := val.(*uint32); ok { 110 byteOrder.PutUint32(buf[:4], *i) 111 _, err := w.Write(buf[:4]) 112 return err 113 } 114 return NewTypeForEncodingErr(val, "uint32") 115 } 116 117 // EUint32T encodes a uint32 val to the provided io.Writer. This method is 118 // exposed so that encodings for custom uint32-like types can be created without 119 // incurring an extra heap allocation. 120 func EUint32T(w io.Writer, val uint32, buf *[8]byte) error { 121 byteOrder.PutUint32(buf[:4], val) 122 _, err := w.Write(buf[:4]) 123 return err 124 } 125 126 // EUint64 is an Encoder for uint64 values. An error is returned if val is not a 127 // *uint64. 128 func EUint64(w io.Writer, val interface{}, buf *[8]byte) error { 129 if i, ok := val.(*uint64); ok { 130 byteOrder.PutUint64(buf[:], *i) 131 _, err := w.Write(buf[:]) 132 return err 133 } 134 return NewTypeForEncodingErr(val, "uint64") 135 } 136 137 // EUint64T encodes a uint64 val to the provided io.Writer. This method is 138 // exposed so that encodings for custom uint64-like types can be created without 139 // incurring an extra heap allocation. 140 func EUint64T(w io.Writer, val uint64, buf *[8]byte) error { 141 byteOrder.PutUint64(buf[:], val) 142 _, err := w.Write(buf[:]) 143 return err 144 } 145 146 // DUint8 is a Decoder for uint8 values. An error is returned if val is not a 147 // *uint8. 148 func DUint8(r io.Reader, val interface{}, buf *[8]byte, l uint64) error { 149 if i, ok := val.(*uint8); ok && l == 1 { 150 if _, err := io.ReadFull(r, buf[:1]); err != nil { 151 return err 152 } 153 *i = buf[0] 154 return nil 155 } 156 return NewTypeForDecodingErr(val, "uint8", l, 1) 157 } 158 159 // DUint16 is a Decoder for uint16 values. An error is returned if val is not a 160 // *uint16. 161 func DUint16(r io.Reader, val interface{}, buf *[8]byte, l uint64) error { 162 if i, ok := val.(*uint16); ok && l == 2 { 163 if _, err := io.ReadFull(r, buf[:2]); err != nil { 164 return err 165 } 166 *i = byteOrder.Uint16(buf[:2]) 167 return nil 168 } 169 return NewTypeForDecodingErr(val, "uint16", l, 2) 170 } 171 172 // DUint32 is a Decoder for uint32 values. An error is returned if val is not a 173 // *uint32. 174 func DUint32(r io.Reader, val interface{}, buf *[8]byte, l uint64) error { 175 if i, ok := val.(*uint32); ok && l == 4 { 176 if _, err := io.ReadFull(r, buf[:4]); err != nil { 177 return err 178 } 179 *i = byteOrder.Uint32(buf[:4]) 180 return nil 181 } 182 return NewTypeForDecodingErr(val, "uint32", l, 4) 183 } 184 185 // DUint64 is a Decoder for uint64 values. An error is returned if val is not a 186 // *uint64. 187 func DUint64(r io.Reader, val interface{}, buf *[8]byte, l uint64) error { 188 if i, ok := val.(*uint64); ok && l == 8 { 189 if _, err := io.ReadFull(r, buf[:]); err != nil { 190 return err 191 } 192 *i = byteOrder.Uint64(buf[:]) 193 return nil 194 } 195 return NewTypeForDecodingErr(val, "uint64", l, 8) 196 } 197 198 // EBytes32 is an Encoder for 32-byte arrays. An error is returned if val is not 199 // a *[32]byte. 200 func EBytes32(w io.Writer, val interface{}, _ *[8]byte) error { 201 if b, ok := val.(*[32]byte); ok { 202 _, err := w.Write(b[:]) 203 return err 204 } 205 return NewTypeForEncodingErr(val, "[32]byte") 206 } 207 208 // DBytes32 is a Decoder for 32-byte arrays. An error is returned if val is not 209 // a *[32]byte. 210 func DBytes32(r io.Reader, val interface{}, _ *[8]byte, l uint64) error { 211 if b, ok := val.(*[32]byte); ok && l == 32 { 212 _, err := io.ReadFull(r, b[:]) 213 return err 214 } 215 return NewTypeForDecodingErr(val, "[32]byte", l, 32) 216 } 217 218 // EBytes33 is an Encoder for 33-byte arrays. An error is returned if val is not 219 // a *[33]byte. 220 func EBytes33(w io.Writer, val interface{}, _ *[8]byte) error { 221 if b, ok := val.(*[33]byte); ok { 222 _, err := w.Write(b[:]) 223 return err 224 } 225 return NewTypeForEncodingErr(val, "[33]byte") 226 } 227 228 // DBytes33 is a Decoder for 33-byte arrays. An error is returned if val is not 229 // a *[33]byte. 230 func DBytes33(r io.Reader, val interface{}, _ *[8]byte, l uint64) error { 231 if b, ok := val.(*[33]byte); ok { 232 _, err := io.ReadFull(r, b[:]) 233 return err 234 } 235 return NewTypeForDecodingErr(val, "[33]byte", l, 33) 236 } 237 238 // EBytes64 is an Encoder for 64-byte arrays. An error is returned if val is not 239 // a *[64]byte. 240 func EBytes64(w io.Writer, val interface{}, _ *[8]byte) error { 241 if b, ok := val.(*[64]byte); ok { 242 _, err := w.Write(b[:]) 243 return err 244 } 245 return NewTypeForEncodingErr(val, "[64]byte") 246 } 247 248 // DBytes64 is an Decoder for 64-byte arrays. An error is returned if val is not 249 // a *[64]byte. 250 func DBytes64(r io.Reader, val interface{}, _ *[8]byte, l uint64) error { 251 if b, ok := val.(*[64]byte); ok && l == 64 { 252 _, err := io.ReadFull(r, b[:]) 253 return err 254 } 255 return NewTypeForDecodingErr(val, "[64]byte", l, 64) 256 } 257 258 // EPubKey is an Encoder for *secp256k1.PublicKey values. An error is returned if 259 // val is not a **secp256k1.PublicKey. 260 func EPubKey(w io.Writer, val interface{}, _ *[8]byte) error { 261 if pk, ok := val.(**secp256k1.PublicKey); ok { 262 _, err := w.Write((*pk).SerializeCompressed()) 263 return err 264 } 265 return NewTypeForEncodingErr(val, "*secp256k1.PublicKey") 266 } 267 268 // DPubKey is a Decoder for *secp256k1.PublicKey values. An error is returned if val 269 // is not a **secp256k1.PublicKey. 270 func DPubKey(r io.Reader, val interface{}, _ *[8]byte, l uint64) error { 271 if pk, ok := val.(**secp256k1.PublicKey); ok && l == 33 { 272 var b [33]byte 273 _, err := io.ReadFull(r, b[:]) 274 if err != nil { 275 return err 276 } 277 278 p, err := secp256k1.ParsePubKey(b[:]) 279 if err != nil { 280 return err 281 } 282 283 *pk = p 284 285 return nil 286 } 287 return NewTypeForDecodingErr(val, "*secp256k1.PublicKey", l, 33) 288 } 289 290 // EVarBytes is an Encoder for variable byte slices. An error is returned if val 291 // is not *[]byte. 292 func EVarBytes(w io.Writer, val interface{}, _ *[8]byte) error { 293 if b, ok := val.(*[]byte); ok { 294 _, err := w.Write(*b) 295 return err 296 } 297 return NewTypeForEncodingErr(val, "[]byte") 298 } 299 300 // DVarBytes is a Decoder for variable byte slices. An error is returned if val 301 // is not *[]byte. 302 func DVarBytes(r io.Reader, val interface{}, _ *[8]byte, l uint64) error { 303 if b, ok := val.(*[]byte); ok { 304 *b = make([]byte, l) 305 _, err := io.ReadFull(r, *b) 306 return err 307 } 308 return NewTypeForDecodingErr(val, "[]byte", l, l) 309 }