1 package flatbuffers
2 3 import "errors"
4 5 var (
6 // Codec implements gRPC-go Codec which is used to encode and decode messages.
7 Codec = "flatbuffers"
8 9 // ErrInsufficientData is returned when the data is too short to read the root UOffsetT.
10 ErrInsufficientData = errors.New("insufficient data")
11 12 // ErrInvalidRootOffset is returned when the root UOffsetT is out of bounds.
13 ErrInvalidRootOffset = errors.New("invalid root offset")
14 )
15 16 // FlatbuffersCodec defines the interface gRPC uses to encode and decode messages. Note
17 // that implementations of this interface must be thread safe; a Codec's
18 // methods can be called from concurrent goroutines.
19 type FlatbuffersCodec struct{}
20 21 // Marshal returns the wire format of v.
22 func (FlatbuffersCodec) Marshal(v interface{}) ([]byte, error) {
23 return v.(*Builder).FinishedBytes(), nil
24 }
25 26 // Unmarshal parses the wire format into v.
27 func (FlatbuffersCodec) Unmarshal(data []byte, v interface{}) error {
28 // Need at least 4 bytes to read the root table offset (UOffsetT).
29 // Vtable soffset_t and metadata are read later during field access.
30 if len(data) < SizeUOffsetT {
31 return ErrInsufficientData
32 }
33 34 off := GetUOffsetT(data)
35 36 // The root UOffsetT must be within the data buffer
37 // Compare in the unsigned domain to avoid signedness pitfalls
38 if off > UOffsetT(len(data)-SizeUOffsetT) {
39 return ErrInvalidRootOffset
40 }
41 42 v.(flatbuffersInit).Init(data, off)
43 return nil
44 }
45 46 // String old gRPC Codec interface func
47 func (FlatbuffersCodec) String() string {
48 return Codec
49 }
50 51 // Name returns the name of the Codec implementation. The returned string
52 // will be used as part of content type in transmission. The result must be
53 // static; the result cannot change between calls.
54 //
55 // add Name() for ForceCodec interface
56 func (FlatbuffersCodec) Name() string {
57 return Codec
58 }
59 60 type flatbuffersInit interface {
61 Init(data []byte, i UOffsetT)
62 }
63