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 }