9 "github.com/vmihailenco/msgpack/codes"
12 var extTypes = make(map[int8]reflect.Type)
14 var bufferPool = &sync.Pool{
15 New: func() interface{} {
16 return new(bytes.Buffer)
20 // RegisterExt records a type, identified by a value for that type,
21 // under the provided id. That id will identify the concrete type of a value
22 // sent or received as an interface variable. Only types that will be
23 // transferred as implementations of interface values need to be registered.
24 // Expecting to be used only during initialization, it panics if the mapping
25 // between types and ids is not a bijection.
26 func RegisterExt(id int8, value interface{}) {
27 typ := reflect.TypeOf(value)
28 if typ.Kind() == reflect.Ptr {
31 ptr := reflect.PtrTo(typ)
33 if _, ok := extTypes[id]; ok {
34 panic(fmt.Errorf("msgpack: ext with id=%d is already registered", id))
37 registerExt(id, ptr, getEncoder(ptr), getDecoder(ptr))
38 registerExt(id, typ, getEncoder(typ), getDecoder(typ))
41 func registerExt(id int8, typ reflect.Type, enc encoderFunc, dec decoderFunc) {
46 typEncMap[typ] = makeExtEncoder(id, enc)
49 typDecMap[typ] = makeExtDecoder(id, dec)
53 func (e *Encoder) EncodeExtHeader(typeId int8, length int) error {
54 if err := e.encodeExtLen(length); err != nil {
57 if err := e.w.WriteByte(byte(typeId)); err != nil {
63 func makeExtEncoder(typeId int8, enc encoderFunc) encoderFunc {
64 return func(e *Encoder, v reflect.Value) error {
65 buf := bufferPool.Get().(*bytes.Buffer)
66 defer bufferPool.Put(buf)
78 err = e.EncodeExtHeader(typeId, buf.Len())
82 return e.write(buf.Bytes())
86 func makeExtDecoder(typeId int8, dec decoderFunc) decoderFunc {
87 return func(d *Decoder, v reflect.Value) error {
88 c, err := d.PeekCode()
97 id, extLen, err := d.DecodeExtHeader()
103 return fmt.Errorf("msgpack: got ext type=%d, wanted %d", int8(c), typeId)
111 func (e *Encoder) encodeExtLen(l int) error {
114 return e.writeCode(codes.FixExt1)
116 return e.writeCode(codes.FixExt2)
118 return e.writeCode(codes.FixExt4)
120 return e.writeCode(codes.FixExt8)
122 return e.writeCode(codes.FixExt16)
125 return e.write1(codes.Ext8, uint8(l))
128 return e.write2(codes.Ext16, uint16(l))
130 return e.write4(codes.Ext32, uint32(l))
133 func (d *Decoder) parseExtLen(c codes.Code) (int, error) {
155 return 0, fmt.Errorf("msgpack: invalid code=%x decoding ext length", c)
159 func (d *Decoder) decodeExtHeader(c codes.Code) (int8, int, error) {
160 length, err := d.parseExtLen(c)
165 typeId, err := d.readCode()
170 return int8(typeId), length, nil
173 func (d *Decoder) DecodeExtHeader() (typeId int8, length int, err error) {
174 c, err := d.readCode()
178 return d.decodeExtHeader(c)
181 func (d *Decoder) extInterface(c codes.Code) (interface{}, error) {
182 extId, extLen, err := d.decodeExtHeader(c)
187 typ, ok := extTypes[extId]
189 return nil, fmt.Errorf("msgpack: unregistered ext id=%d", extId)
192 v := reflect.New(typ)
195 err = d.DecodeValue(v.Elem())
201 return v.Interface(), nil
204 func (d *Decoder) skipExt(c codes.Code) error {
205 n, err := d.parseExtLen(c)
209 return d.skipN(n + 1)
212 func (d *Decoder) skipExtHeader(c codes.Code) error {
214 _, err := d.readCode()
218 // Read ext body len.
219 for i := 0; i < extHeaderLen(c); i++ {
220 _, err := d.readCode()
228 func extHeaderLen(c codes.Code) int {