github.com/philpearl/plenc@v0.0.15/plenccodec/codec.go (about)

     1  // Package plenccodec provides the core Codecs for plenc.
     2  //
     3  // You shouldn't need to interact with this package directly unless you're
     4  // building your own custom codecs.
     5  //
     6  // The exception to this is the Descriptor endpoint on a Codec. This is a
     7  // serialisable description that allows you to decode plenc data without the
     8  // type that the data was encoded from.
     9  package plenccodec
    10  
    11  import (
    12  	"reflect"
    13  	"unsafe"
    14  
    15  	"github.com/philpearl/plenc/plenccore"
    16  )
    17  
    18  // Codec is what you implement to encode / decode a type. Note that codecs are
    19  // separate from the types they encode, and that they are registered with the
    20  // system via RegisterCodec.
    21  //
    22  // It isn't normally necessary to build a codec for a struct. Codecs for structs
    23  // are generated automatically when plenc first sees them and then are re-used
    24  // for the life of the program.
    25  type Codec interface {
    26  	Omit(ptr unsafe.Pointer) bool
    27  	Read(data []byte, ptr unsafe.Pointer, wt plenccore.WireType) (n int, err error)
    28  	New() unsafe.Pointer
    29  	WireType() plenccore.WireType
    30  
    31  	// Descriptor returns a descriptor for the type correspondng to the Codec.
    32  	// The descriptor can be used to interpret plenc data without access to the
    33  	// original type. The descriptor can also be serialised (either as JSON or
    34  	// plenc), so can be stored or communicated with another system
    35  	Descriptor() Descriptor
    36  
    37  	// Size returns the size of the encoded data including the tag and
    38  	// for WTLength types the varint encoded length of the data. If the tag is
    39  	// nil then it is not included in the size and neither is the length for
    40  	// WTLength types
    41  	Size(ptr unsafe.Pointer, tag []byte) int
    42  
    43  	// Append appends the encoded data including the tag and for WTLength
    44  	// types the varint encoded length of the data. If the tag is nil then it is
    45  	// not included in the data and neither is the length for WTLength types
    46  	Append(data []byte, ptr unsafe.Pointer, tag []byte) []byte
    47  }
    48  
    49  // CodecRegistry is a repository of pre-existing Codecs
    50  type CodecRegistry interface {
    51  	// Load loads the codec from the registry. It returns nil if no codec exists
    52  	Load(typ reflect.Type, tag string) Codec
    53  	// StoreOrSwap adds the codec to the registry. It may return a different
    54  	// codec if the codec has been built on another goroutine
    55  	StoreOrSwap(typ reflect.Type, tag string, c Codec) Codec
    56  }
    57  
    58  // CodecBuilder either builds a new codec for a type, or finds an existing codec
    59  type CodecBuilder interface {
    60  	// CodecForTypeRegistry builds a new codec for the requested type,
    61  	// consulting registry for any existing codecs needed
    62  	CodecForTypeRegistry(registry CodecRegistry, typ reflect.Type, tag string) (Codec, error)
    63  }