From 98475267bf00ec9133627a642abb08287f8a0523 Mon Sep 17 00:00:00 2001 From: Topper Bowers Date: Mon, 2 Sep 2019 14:04:15 +0200 Subject: [PATCH] if an object can marshal or unmarshal itself, use that ability --- encoding/cloner.go | 8 ++++++++ encoding/marshaller.go | 12 +++++++++++- encoding/unmarshaller.go | 13 +++++++++++-- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/encoding/cloner.go b/encoding/cloner.go index 0a04a3c..d054eb4 100644 --- a/encoding/cloner.go +++ b/encoding/cloner.go @@ -24,8 +24,16 @@ func NewPooledCloner(atl atlas.Atlas) PooledCloner { } } +type selfCloner interface { + Clone(b interface{}) error +} + // Clone clones a into b using a cloner from the pool. func (p *PooledCloner) Clone(a, b interface{}) error { + if self, ok := a.(selfCloner); ok { + return self.Clone(b) + } + c := p.pool.Get().(refmt.Cloner) err := c.Clone(a, b) p.pool.Put(c) diff --git a/encoding/marshaller.go b/encoding/marshaller.go index f4fe84b..a517f47 100644 --- a/encoding/marshaller.go +++ b/encoding/marshaller.go @@ -30,10 +30,20 @@ func NewMarshallerAtlased(atl atlas.Atlas) *Marshaller { return m } +type cborMarshaler interface { + MarshalCBOR(w io.Writer) error +} + // 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) + var err error + selfMarshaling, ok := obj.(cborMarshaler) + if ok { + err = selfMarshaling.MarshalCBOR(w) + } else { + err = m.marshal.Marshal(obj) + } m.writer.w = nil return err } diff --git a/encoding/unmarshaller.go b/encoding/unmarshaller.go index 2561dd7..559cbeb 100644 --- a/encoding/unmarshaller.go +++ b/encoding/unmarshaller.go @@ -30,11 +30,20 @@ func NewUnmarshallerAtlased(atl atlas.Atlas) *Unmarshaller { return m } +type cborUnmarshaler interface { + UnmarshalCBOR(r io.Reader) error +} + // Decode reads a CBOR object from the given reader and decodes it into the // given object. -func (m *Unmarshaller) Decode(r io.Reader, obj interface{}) error { +func (m *Unmarshaller) Decode(r io.Reader, obj interface{}) (err error) { m.reader.r = r - err := m.unmarshal.Unmarshal(obj) + selfUnmarshaler, ok := obj.(cborUnmarshaler) + if ok { + err = selfUnmarshaler.UnmarshalCBOR(r) + } else { + err = m.unmarshal.Unmarshal(obj) + } m.reader.r = nil return err }