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  }