github.com/ipld/go-ipld-prime@v0.21.0/codec/raw/codec.go (about)

     1  // Package raw implements IPLD's raw codec, which simply writes and reads a Node
     2  // which can be represented as bytes.
     3  //
     4  // The codec can be used with any node which supports AsBytes and AssignBytes.
     5  // In general, it only makes sense to use this codec on a plain "bytes" node
     6  // such as github.com/ipld/go-ipld-prime/node/basicnode.Prototype.Bytes.
     7  package raw
     8  
     9  import (
    10  	"fmt"
    11  	"io"
    12  
    13  	"github.com/ipld/go-ipld-prime/codec"
    14  	"github.com/ipld/go-ipld-prime/datamodel"
    15  	"github.com/ipld/go-ipld-prime/multicodec"
    16  )
    17  
    18  // TODO(mvdan): make go-ipld use go-multicodec soon
    19  const rawMulticodec = 0x55
    20  
    21  var (
    22  	_ codec.Decoder = Decode
    23  	_ codec.Encoder = Encode
    24  )
    25  
    26  func init() {
    27  	multicodec.RegisterEncoder(rawMulticodec, Encode)
    28  	multicodec.RegisterDecoder(rawMulticodec, Decode)
    29  }
    30  
    31  // Decode implements decoding of a node with the raw codec.
    32  //
    33  // Note that if r has a Bytes method, such as is the case with *bytes.Buffer, we
    34  // will use those bytes directly to save having to allocate and copy them. The
    35  // Node interface is defined as immutable, so it is assumed that its bytes won't
    36  // be modified in-place. Similarly, we assume that the incoming buffer's bytes
    37  // won't get modified in-place later.
    38  //
    39  // To disable the shortcut above, hide the Bytes method by wrapping the buffer
    40  // with an io.Reader:
    41  //
    42  //	Decode([...], struct{io.Reader}{buf})
    43  func Decode(am datamodel.NodeAssembler, r io.Reader) error {
    44  	var data []byte
    45  	if buf, ok := r.(interface{ Bytes() []byte }); ok {
    46  		data = buf.Bytes()
    47  	} else {
    48  		var err error
    49  		data, err = io.ReadAll(r)
    50  		if err != nil {
    51  			return fmt.Errorf("could not decode raw node: %v", err)
    52  		}
    53  	}
    54  	return am.AssignBytes(data)
    55  }
    56  
    57  // Encode implements encoding of a node with the raw codec.
    58  //
    59  // Note that Encode won't copy the node's bytes as returned by AsBytes, but the
    60  // call to Write will typically have to copy the bytes anyway.
    61  func Encode(node datamodel.Node, w io.Writer) error {
    62  	data, err := node.AsBytes()
    63  	if err != nil {
    64  		return err
    65  	}
    66  	_, err = w.Write(data)
    67  	return err
    68  }