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 }