ipld-eth-server/vendor/github.com/ipfs/go-ipld-cbor/encoding/marshaller.go

83 lines
1.9 KiB
Go

package encoding
import (
"bytes"
"io"
"sync"
cbor "github.com/polydawn/refmt/cbor"
"github.com/polydawn/refmt/obj/atlas"
)
type proxyWriter struct {
w io.Writer
}
func (w *proxyWriter) Write(b []byte) (int, error) {
return w.w.Write(b)
}
// Marshaller is a reusbale CBOR marshaller.
type Marshaller struct {
marshal *cbor.Marshaller
writer proxyWriter
}
// NewMarshallerAtlased constructs a new cbor Marshaller using the given atlas.
func NewMarshallerAtlased(atl atlas.Atlas) *Marshaller {
m := new(Marshaller)
m.marshal = cbor.NewMarshallerAtlased(&m.writer, atl)
return m
}
// Encode encodes the given object to the given writer.
func (m *Marshaller) Encode(obj interface{}, w io.Writer) error {
m.writer.w = w
err := m.marshal.Marshal(obj)
m.writer.w = nil
return err
}
// Marshal marshels the given object to a byte slice.
func (m *Marshaller) Marshal(obj interface{}) ([]byte, error) {
var buf bytes.Buffer
if err := m.Encode(obj, &buf); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// PooledMarshaller is a thread-safe pooled CBOR marshaller.
type PooledMarshaller struct {
pool sync.Pool
}
// NewPooledMarshaller returns a PooledMarshaller with the given atlas. Do not
// copy after use.
func NewPooledMarshaller(atl atlas.Atlas) PooledMarshaller {
return PooledMarshaller{
pool: sync.Pool{
New: func() interface{} {
return NewMarshallerAtlased(atl)
},
},
}
}
// Marshal marshals the passed object using the pool of marshallers.
func (p *PooledMarshaller) Marshal(obj interface{}) ([]byte, error) {
m := p.pool.Get().(*Marshaller)
bts, err := m.Marshal(obj)
p.pool.Put(m)
return bts, err
}
// Encode encodes the passed object to the given writer using the pool of
// marshallers.
func (p *PooledMarshaller) Encode(obj interface{}, w io.Writer) error {
m := p.pool.Get().(*Marshaller)
err := m.Encode(obj, w)
p.pool.Put(m)
return err
}