9 // Complex64Extension is the extension number used for complex64
10 Complex64Extension = 3
12 // Complex128Extension is the extension number used for complex128
13 Complex128Extension = 4
15 // TimeExtension is the extension number used for time.Time
19 // our extensions live here
20 var extensionReg = make(map[int8]func() Extension)
22 // RegisterExtension registers extensions so that they
23 // can be initialized and returned by methods that
24 // decode `interface{}` values. This should only
25 // be called during initialization. f() should return
26 // a newly-initialized zero value of the extension. Keep in
27 // mind that extensions 3, 4, and 5 are reserved for
28 // complex64, complex128, and time.Time, respectively,
29 // and that MessagePack reserves extension types from -127 to -1.
31 // For example, if you wanted to register a user-defined struct:
33 // msgp.RegisterExtension(10, func() msgp.Extension { &MyExtension{} })
35 // RegisterExtension will panic if you call it multiple times
36 // with the same 'typ' argument, or if you use a reserved
38 func RegisterExtension(typ int8, f func() Extension) {
40 case Complex64Extension, Complex128Extension, TimeExtension:
41 panic(fmt.Sprint("msgp: forbidden extension type:", typ))
43 if _, ok := extensionReg[typ]; ok {
44 panic(fmt.Sprint("msgp: RegisterExtension() called with typ", typ, "more than once"))
49 // ExtensionTypeError is an error type returned
50 // when there is a mis-match between an extension type
51 // and the type encoded on the wire
52 type ExtensionTypeError struct {
57 // Error implements the error interface
58 func (e ExtensionTypeError) Error() string {
59 return fmt.Sprintf("msgp: error decoding extension: wanted type %d; got type %d", e.Want, e.Got)
62 // Resumable returns 'true' for ExtensionTypeErrors
63 func (e ExtensionTypeError) Resumable() bool { return true }
65 func errExt(got int8, wanted int8) error {
66 return ExtensionTypeError{Got: got, Want: wanted}
69 // Extension is the interface fulfilled
70 // by types that want to define their
71 // own binary encoding.
72 type Extension interface {
73 // ExtensionType should return
74 // a int8 that identifies the concrete
75 // type of the extension. (Types <0 are
76 // officially reserved by the MessagePack
80 // Len should return the length
81 // of the data to be encoded
84 // MarshalBinaryTo should copy
85 // the data into the supplied slice,
86 // assuming that the slice has length Len()
87 MarshalBinaryTo([]byte) error
89 UnmarshalBinary([]byte) error
92 // RawExtension implements the Extension interface
93 type RawExtension struct {
98 // ExtensionType implements Extension.ExtensionType, and returns r.Type
99 func (r *RawExtension) ExtensionType() int8 { return r.Type }
101 // Len implements Extension.Len, and returns len(r.Data)
102 func (r *RawExtension) Len() int { return len(r.Data) }
104 // MarshalBinaryTo implements Extension.MarshalBinaryTo,
105 // and returns a copy of r.Data
106 func (r *RawExtension) MarshalBinaryTo(d []byte) error {
111 // UnmarshalBinary implements Extension.UnmarshalBinary,
112 // and sets r.Data to the contents of the provided slice
113 func (r *RawExtension) UnmarshalBinary(b []byte) error {
114 if cap(r.Data) >= len(b) {
115 r.Data = r.Data[0:len(b)]
117 r.Data = make([]byte, len(b))
123 // WriteExtension writes an extension type to the writer
124 func (mw *Writer) WriteExtension(e Extension) error {
129 o, err := mw.require(3)
135 mw.buf[o+2] = byte(e.ExtensionType())
137 o, err := mw.require(2)
142 mw.buf[o+1] = byte(e.ExtensionType())
144 o, err := mw.require(2)
149 mw.buf[o+1] = byte(e.ExtensionType())
151 o, err := mw.require(2)
156 mw.buf[o+1] = byte(e.ExtensionType())
158 o, err := mw.require(2)
163 mw.buf[o+1] = byte(e.ExtensionType())
165 o, err := mw.require(2)
169 mw.buf[o] = mfixext16
170 mw.buf[o+1] = byte(e.ExtensionType())
173 case l < math.MaxUint8:
174 o, err := mw.require(3)
179 mw.buf[o+1] = byte(uint8(l))
180 mw.buf[o+2] = byte(e.ExtensionType())
181 case l < math.MaxUint16:
182 o, err := mw.require(4)
187 big.PutUint16(mw.buf[o+1:], uint16(l))
188 mw.buf[o+3] = byte(e.ExtensionType())
190 o, err := mw.require(6)
195 big.PutUint32(mw.buf[o+1:], uint32(l))
196 mw.buf[o+5] = byte(e.ExtensionType())
199 // we can only write directly to the
200 // buffer if we're sure that it
202 if l <= mw.bufsize() {
203 o, err := mw.require(l)
207 return e.MarshalBinaryTo(mw.buf[o:])
209 // here we create a new buffer
210 // just large enough for the body
211 // and save it as the write buffer
216 buf := make([]byte, l)
217 err = e.MarshalBinaryTo(buf)
226 // peek at the extension type, assuming the next
227 // kind to be read is Extension
228 func (m *Reader) peekExtensionType() (int8, error) {
229 p, err := m.r.Peek(2)
234 if spec.typ != ExtensionType {
235 return 0, badPrefix(ExtensionType, p[0])
237 if spec.extra == constsize {
238 return int8(p[1]), nil
241 p, err = m.r.Peek(int(size))
245 return int8(p[size-1]), nil
248 // peekExtension peeks at the extension encoding type
249 // (must guarantee at least 1 byte in 'b')
250 func peekExtension(b []byte) (int8, error) {
253 if spec.typ != ExtensionType {
254 return 0, badPrefix(ExtensionType, b[0])
256 if len(b) < int(size) {
257 return 0, ErrShortBytes
259 // for fixed extensions,
260 // the type information is in
262 if spec.extra == constsize {
263 return int8(b[1]), nil
265 // otherwise, it's in the last
266 // part of the prefix
267 return int8(b[size-1]), nil
270 // ReadExtension reads the next object from the reader
271 // as an extension. ReadExtension will fail if the next
272 // object in the stream is not an extension, or if
273 // e.Type() is not the same as the wire type.
274 func (m *Reader) ReadExtension(e Extension) (err error) {
285 if int8(p[1]) != e.ExtensionType() {
286 err = errExt(int8(p[1]), e.ExtensionType())
293 err = e.UnmarshalBinary(p[2:])
300 if int8(p[1]) != e.ExtensionType() {
301 err = errExt(int8(p[1]), e.ExtensionType())
308 err = e.UnmarshalBinary(p[2:])
315 if int8(p[1]) != e.ExtensionType() {
316 err = errExt(int8(p[1]), e.ExtensionType())
323 err = e.UnmarshalBinary(p[2:])
330 if int8(p[1]) != e.ExtensionType() {
331 err = errExt(int8(p[1]), e.ExtensionType())
334 p, err = m.r.Peek(10)
338 err = e.UnmarshalBinary(p[2:])
340 _, err = m.r.Skip(10)
345 if int8(p[1]) != e.ExtensionType() {
346 err = errExt(int8(p[1]), e.ExtensionType())
349 p, err = m.r.Peek(18)
353 err = e.UnmarshalBinary(p[2:])
355 _, err = m.r.Skip(18)
364 if int8(p[2]) != e.ExtensionType() {
365 err = errExt(int8(p[2]), e.ExtensionType())
368 read = int(uint8(p[1]))
376 if int8(p[3]) != e.ExtensionType() {
377 err = errExt(int8(p[3]), e.ExtensionType())
380 read = int(big.Uint16(p[1:]))
388 if int8(p[5]) != e.ExtensionType() {
389 err = errExt(int8(p[5]), e.ExtensionType())
392 read = int(big.Uint32(p[1:]))
396 err = badPrefix(ExtensionType, lead)
400 p, err = m.r.Peek(read + off)
404 err = e.UnmarshalBinary(p[off:])
406 _, err = m.r.Skip(read + off)
411 // AppendExtension appends a MessagePack extension to the provided slice
412 func AppendExtension(b []byte, e Extension) ([]byte, error) {
421 o[n+2] = byte(e.ExtensionType())
426 o[n+1] = byte(e.ExtensionType())
431 o[n+1] = byte(e.ExtensionType())
436 o[n+1] = byte(e.ExtensionType())
441 o[n+1] = byte(e.ExtensionType())
446 o[n+1] = byte(e.ExtensionType())
450 case l < math.MaxUint8:
451 o, n = ensure(b, l+3)
453 o[n+1] = byte(uint8(l))
454 o[n+2] = byte(e.ExtensionType())
456 case l < math.MaxUint16:
457 o, n = ensure(b, l+4)
459 big.PutUint16(o[n+1:], uint16(l))
460 o[n+3] = byte(e.ExtensionType())
463 o, n = ensure(b, l+6)
465 big.PutUint32(o[n+1:], uint32(l))
466 o[n+5] = byte(e.ExtensionType())
469 return o, e.MarshalBinaryTo(o[n:])
472 // ReadExtensionBytes reads an extension from 'b' into 'e'
473 // and returns any remaining bytes.
475 // - ErrShortBytes ('b' not long enough)
476 // - ExtensionTypeErorr{} (wire type not the same as e.Type())
477 // - TypeErorr{} (next object not an extension)
478 // - InvalidPrefixError
479 // - An umarshal error returned from e.UnmarshalBinary
480 func ReadExtensionBytes(b []byte, e Extension) ([]byte, error) {
483 return b, ErrShortBytes
487 sz int // size of 'data'
488 off int // offset of 'data'
513 sz = int(uint8(b[1]))
517 return b[3:], e.UnmarshalBinary(b[3:3])
521 return b, ErrShortBytes
523 sz = int(big.Uint16(b[1:]))
528 return b, ErrShortBytes
530 sz = int(big.Uint32(b[1:]))
534 return b, badPrefix(ExtensionType, lead)
537 if typ != e.ExtensionType() {
538 return b, errExt(typ, e.ExtensionType())
541 // the data of the extension starts
542 // at 'off' and is 'sz' bytes long
543 if len(b[off:]) < sz {
544 return b, ErrShortBytes
547 return b[tot:], e.UnmarshalBinary(b[off:tot])