decred.org/dcrdex@v1.0.5/dex/marshal.go (about)

     1  // This code is available on the terms of the project LICENSE.md file,
     2  // also available online at https://blueoakcouncil.org/license/1.0.0.
     3  
     4  package dex
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/hex"
     9  	"encoding/json"
    10  	"fmt"
    11  )
    12  
    13  // Bytes is a byte slice that marshals to and unmarshals from a hexadecimal
    14  // string. The default go behavior is to marshal []byte to a base-64 string.
    15  type Bytes []byte
    16  
    17  // String return the hex encoding of the Bytes.
    18  func (b Bytes) String() string {
    19  	return hex.EncodeToString(b)
    20  }
    21  
    22  // MarshalJSON satisfies the json.Marshaller interface, and will marshal the
    23  // bytes to a hex string.
    24  func (b Bytes) MarshalJSON() ([]byte, error) {
    25  	return json.Marshal(hex.EncodeToString(b))
    26  }
    27  
    28  // Scan implements the sql.Scanner interface.
    29  func (b *Bytes) Scan(src any) error {
    30  	switch src := src.(type) {
    31  	case []byte:
    32  		// src may be reused, so create a new slice.
    33  		dst := make(Bytes, len(src))
    34  		copy(dst, src)
    35  		*b = dst
    36  		return nil
    37  	case nil:
    38  		return nil
    39  	}
    40  	return fmt.Errorf("cannot convert %T to Bytes", src)
    41  }
    42  
    43  // UnmarshalJSON satisfies the json.Unmarshaler interface, and expects a UTF-8
    44  // encoding of a hex string in double quotes.
    45  func (b *Bytes) UnmarshalJSON(encHex []byte) (err error) {
    46  	if len(encHex) < 2 {
    47  		return fmt.Errorf("marshalled Bytes, %q, not valid", string(encHex))
    48  	}
    49  	if encHex[0] != '"' || encHex[len(encHex)-1] != '"' {
    50  		return fmt.Errorf("marshalled Bytes, %q, not quoted", string(encHex))
    51  	}
    52  	// DecodeString over-allocates by at least double, and it makes a copy.
    53  	src := encHex[1 : len(encHex)-1]
    54  	dst := make([]byte, len(src)/2)
    55  	_, err = hex.Decode(dst, src)
    56  	if err == nil {
    57  		*b = dst
    58  	}
    59  	return err
    60  }
    61  
    62  func (b Bytes) MarshalBinary() (data []byte, err error) {
    63  	return b, nil
    64  }
    65  
    66  // Equal is true if otherB has identical []byte contents to the Bytes.
    67  func (b Bytes) Equal(otherB []byte) bool {
    68  	return bytes.Equal(b, otherB)
    69  }