You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

extension.go 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. package msgp
  2. import (
  3. "fmt"
  4. "math"
  5. )
  6. const (
  7. // Complex64Extension is the extension number used for complex64
  8. Complex64Extension = 3
  9. // Complex128Extension is the extension number used for complex128
  10. Complex128Extension = 4
  11. // TimeExtension is the extension number used for time.Time
  12. TimeExtension = 5
  13. )
  14. // our extensions live here
  15. var extensionReg = make(map[int8]func() Extension)
  16. // RegisterExtension registers extensions so that they
  17. // can be initialized and returned by methods that
  18. // decode `interface{}` values. This should only
  19. // be called during initialization. f() should return
  20. // a newly-initialized zero value of the extension. Keep in
  21. // mind that extensions 3, 4, and 5 are reserved for
  22. // complex64, complex128, and time.Time, respectively,
  23. // and that MessagePack reserves extension types from -127 to -1.
  24. //
  25. // For example, if you wanted to register a user-defined struct:
  26. //
  27. // msgp.RegisterExtension(10, func() msgp.Extension { &MyExtension{} })
  28. //
  29. // RegisterExtension will panic if you call it multiple times
  30. // with the same 'typ' argument, or if you use a reserved
  31. // type (3, 4, or 5).
  32. func RegisterExtension(typ int8, f func() Extension) {
  33. switch typ {
  34. case Complex64Extension, Complex128Extension, TimeExtension:
  35. panic(fmt.Sprint("msgp: forbidden extension type:", typ))
  36. }
  37. if _, ok := extensionReg[typ]; ok {
  38. panic(fmt.Sprint("msgp: RegisterExtension() called with typ", typ, "more than once"))
  39. }
  40. extensionReg[typ] = f
  41. }
  42. // ExtensionTypeError is an error type returned
  43. // when there is a mis-match between an extension type
  44. // and the type encoded on the wire
  45. type ExtensionTypeError struct {
  46. Got int8
  47. Want int8
  48. }
  49. // Error implements the error interface
  50. func (e ExtensionTypeError) Error() string {
  51. return fmt.Sprintf("msgp: error decoding extension: wanted type %d; got type %d", e.Want, e.Got)
  52. }
  53. // Resumable returns 'true' for ExtensionTypeErrors
  54. func (e ExtensionTypeError) Resumable() bool { return true }
  55. func errExt(got int8, wanted int8) error {
  56. return ExtensionTypeError{Got: got, Want: wanted}
  57. }
  58. // Extension is the interface fulfilled
  59. // by types that want to define their
  60. // own binary encoding.
  61. type Extension interface {
  62. // ExtensionType should return
  63. // a int8 that identifies the concrete
  64. // type of the extension. (Types <0 are
  65. // officially reserved by the MessagePack
  66. // specifications.)
  67. ExtensionType() int8
  68. // Len should return the length
  69. // of the data to be encoded
  70. Len() int
  71. // MarshalBinaryTo should copy
  72. // the data into the supplied slice,
  73. // assuming that the slice has length Len()
  74. MarshalBinaryTo([]byte) error
  75. UnmarshalBinary([]byte) error
  76. }
  77. // RawExtension implements the Extension interface
  78. type RawExtension struct {
  79. Data []byte
  80. Type int8
  81. }
  82. // ExtensionType implements Extension.ExtensionType, and returns r.Type
  83. func (r *RawExtension) ExtensionType() int8 { return r.Type }
  84. // Len implements Extension.Len, and returns len(r.Data)
  85. func (r *RawExtension) Len() int { return len(r.Data) }
  86. // MarshalBinaryTo implements Extension.MarshalBinaryTo,
  87. // and returns a copy of r.Data
  88. func (r *RawExtension) MarshalBinaryTo(d []byte) error {
  89. copy(d, r.Data)
  90. return nil
  91. }
  92. // UnmarshalBinary implements Extension.UnmarshalBinary,
  93. // and sets r.Data to the contents of the provided slice
  94. func (r *RawExtension) UnmarshalBinary(b []byte) error {
  95. if cap(r.Data) >= len(b) {
  96. r.Data = r.Data[0:len(b)]
  97. } else {
  98. r.Data = make([]byte, len(b))
  99. }
  100. copy(r.Data, b)
  101. return nil
  102. }
  103. // WriteExtension writes an extension type to the writer
  104. func (mw *Writer) WriteExtension(e Extension) error {
  105. l := e.Len()
  106. var err error
  107. switch l {
  108. case 0:
  109. o, err := mw.require(3)
  110. if err != nil {
  111. return err
  112. }
  113. mw.buf[o] = mext8
  114. mw.buf[o+1] = 0
  115. mw.buf[o+2] = byte(e.ExtensionType())
  116. case 1:
  117. o, err := mw.require(2)
  118. if err != nil {
  119. return err
  120. }
  121. mw.buf[o] = mfixext1
  122. mw.buf[o+1] = byte(e.ExtensionType())
  123. case 2:
  124. o, err := mw.require(2)
  125. if err != nil {
  126. return err
  127. }
  128. mw.buf[o] = mfixext2
  129. mw.buf[o+1] = byte(e.ExtensionType())
  130. case 4:
  131. o, err := mw.require(2)
  132. if err != nil {
  133. return err
  134. }
  135. mw.buf[o] = mfixext4
  136. mw.buf[o+1] = byte(e.ExtensionType())
  137. case 8:
  138. o, err := mw.require(2)
  139. if err != nil {
  140. return err
  141. }
  142. mw.buf[o] = mfixext8
  143. mw.buf[o+1] = byte(e.ExtensionType())
  144. case 16:
  145. o, err := mw.require(2)
  146. if err != nil {
  147. return err
  148. }
  149. mw.buf[o] = mfixext16
  150. mw.buf[o+1] = byte(e.ExtensionType())
  151. default:
  152. switch {
  153. case l < math.MaxUint8:
  154. o, err := mw.require(3)
  155. if err != nil {
  156. return err
  157. }
  158. mw.buf[o] = mext8
  159. mw.buf[o+1] = byte(uint8(l))
  160. mw.buf[o+2] = byte(e.ExtensionType())
  161. case l < math.MaxUint16:
  162. o, err := mw.require(4)
  163. if err != nil {
  164. return err
  165. }
  166. mw.buf[o] = mext16
  167. big.PutUint16(mw.buf[o+1:], uint16(l))
  168. mw.buf[o+3] = byte(e.ExtensionType())
  169. default:
  170. o, err := mw.require(6)
  171. if err != nil {
  172. return err
  173. }
  174. mw.buf[o] = mext32
  175. big.PutUint32(mw.buf[o+1:], uint32(l))
  176. mw.buf[o+5] = byte(e.ExtensionType())
  177. }
  178. }
  179. // we can only write directly to the
  180. // buffer if we're sure that it
  181. // fits the object
  182. if l <= mw.bufsize() {
  183. o, err := mw.require(l)
  184. if err != nil {
  185. return err
  186. }
  187. return e.MarshalBinaryTo(mw.buf[o:])
  188. }
  189. // here we create a new buffer
  190. // just large enough for the body
  191. // and save it as the write buffer
  192. err = mw.flush()
  193. if err != nil {
  194. return err
  195. }
  196. buf := make([]byte, l)
  197. err = e.MarshalBinaryTo(buf)
  198. if err != nil {
  199. return err
  200. }
  201. mw.buf = buf
  202. mw.wloc = l
  203. return nil
  204. }
  205. // peek at the extension type, assuming the next
  206. // kind to be read is Extension
  207. func (m *Reader) peekExtensionType() (int8, error) {
  208. p, err := m.R.Peek(2)
  209. if err != nil {
  210. return 0, err
  211. }
  212. spec := sizes[p[0]]
  213. if spec.typ != ExtensionType {
  214. return 0, badPrefix(ExtensionType, p[0])
  215. }
  216. if spec.extra == constsize {
  217. return int8(p[1]), nil
  218. }
  219. size := spec.size
  220. p, err = m.R.Peek(int(size))
  221. if err != nil {
  222. return 0, err
  223. }
  224. return int8(p[size-1]), nil
  225. }
  226. // peekExtension peeks at the extension encoding type
  227. // (must guarantee at least 1 byte in 'b')
  228. func peekExtension(b []byte) (int8, error) {
  229. spec := sizes[b[0]]
  230. size := spec.size
  231. if spec.typ != ExtensionType {
  232. return 0, badPrefix(ExtensionType, b[0])
  233. }
  234. if len(b) < int(size) {
  235. return 0, ErrShortBytes
  236. }
  237. // for fixed extensions,
  238. // the type information is in
  239. // the second byte
  240. if spec.extra == constsize {
  241. return int8(b[1]), nil
  242. }
  243. // otherwise, it's in the last
  244. // part of the prefix
  245. return int8(b[size-1]), nil
  246. }
  247. // ReadExtension reads the next object from the reader
  248. // as an extension. ReadExtension will fail if the next
  249. // object in the stream is not an extension, or if
  250. // e.Type() is not the same as the wire type.
  251. func (m *Reader) ReadExtension(e Extension) (err error) {
  252. var p []byte
  253. p, err = m.R.Peek(2)
  254. if err != nil {
  255. return
  256. }
  257. lead := p[0]
  258. var read int
  259. var off int
  260. switch lead {
  261. case mfixext1:
  262. if int8(p[1]) != e.ExtensionType() {
  263. err = errExt(int8(p[1]), e.ExtensionType())
  264. return
  265. }
  266. p, err = m.R.Peek(3)
  267. if err != nil {
  268. return
  269. }
  270. err = e.UnmarshalBinary(p[2:])
  271. if err == nil {
  272. _, err = m.R.Skip(3)
  273. }
  274. return
  275. case mfixext2:
  276. if int8(p[1]) != e.ExtensionType() {
  277. err = errExt(int8(p[1]), e.ExtensionType())
  278. return
  279. }
  280. p, err = m.R.Peek(4)
  281. if err != nil {
  282. return
  283. }
  284. err = e.UnmarshalBinary(p[2:])
  285. if err == nil {
  286. _, err = m.R.Skip(4)
  287. }
  288. return
  289. case mfixext4:
  290. if int8(p[1]) != e.ExtensionType() {
  291. err = errExt(int8(p[1]), e.ExtensionType())
  292. return
  293. }
  294. p, err = m.R.Peek(6)
  295. if err != nil {
  296. return
  297. }
  298. err = e.UnmarshalBinary(p[2:])
  299. if err == nil {
  300. _, err = m.R.Skip(6)
  301. }
  302. return
  303. case mfixext8:
  304. if int8(p[1]) != e.ExtensionType() {
  305. err = errExt(int8(p[1]), e.ExtensionType())
  306. return
  307. }
  308. p, err = m.R.Peek(10)
  309. if err != nil {
  310. return
  311. }
  312. err = e.UnmarshalBinary(p[2:])
  313. if err == nil {
  314. _, err = m.R.Skip(10)
  315. }
  316. return
  317. case mfixext16:
  318. if int8(p[1]) != e.ExtensionType() {
  319. err = errExt(int8(p[1]), e.ExtensionType())
  320. return
  321. }
  322. p, err = m.R.Peek(18)
  323. if err != nil {
  324. return
  325. }
  326. err = e.UnmarshalBinary(p[2:])
  327. if err == nil {
  328. _, err = m.R.Skip(18)
  329. }
  330. return
  331. case mext8:
  332. p, err = m.R.Peek(3)
  333. if err != nil {
  334. return
  335. }
  336. if int8(p[2]) != e.ExtensionType() {
  337. err = errExt(int8(p[2]), e.ExtensionType())
  338. return
  339. }
  340. read = int(uint8(p[1]))
  341. off = 3
  342. case mext16:
  343. p, err = m.R.Peek(4)
  344. if err != nil {
  345. return
  346. }
  347. if int8(p[3]) != e.ExtensionType() {
  348. err = errExt(int8(p[3]), e.ExtensionType())
  349. return
  350. }
  351. read = int(big.Uint16(p[1:]))
  352. off = 4
  353. case mext32:
  354. p, err = m.R.Peek(6)
  355. if err != nil {
  356. return
  357. }
  358. if int8(p[5]) != e.ExtensionType() {
  359. err = errExt(int8(p[5]), e.ExtensionType())
  360. return
  361. }
  362. read = int(big.Uint32(p[1:]))
  363. off = 6
  364. default:
  365. err = badPrefix(ExtensionType, lead)
  366. return
  367. }
  368. p, err = m.R.Peek(read + off)
  369. if err != nil {
  370. return
  371. }
  372. err = e.UnmarshalBinary(p[off:])
  373. if err == nil {
  374. _, err = m.R.Skip(read + off)
  375. }
  376. return
  377. }
  378. // AppendExtension appends a MessagePack extension to the provided slice
  379. func AppendExtension(b []byte, e Extension) ([]byte, error) {
  380. l := e.Len()
  381. var o []byte
  382. var n int
  383. switch l {
  384. case 0:
  385. o, n = ensure(b, 3)
  386. o[n] = mext8
  387. o[n+1] = 0
  388. o[n+2] = byte(e.ExtensionType())
  389. return o[:n+3], nil
  390. case 1:
  391. o, n = ensure(b, 3)
  392. o[n] = mfixext1
  393. o[n+1] = byte(e.ExtensionType())
  394. n += 2
  395. case 2:
  396. o, n = ensure(b, 4)
  397. o[n] = mfixext2
  398. o[n+1] = byte(e.ExtensionType())
  399. n += 2
  400. case 4:
  401. o, n = ensure(b, 6)
  402. o[n] = mfixext4
  403. o[n+1] = byte(e.ExtensionType())
  404. n += 2
  405. case 8:
  406. o, n = ensure(b, 10)
  407. o[n] = mfixext8
  408. o[n+1] = byte(e.ExtensionType())
  409. n += 2
  410. case 16:
  411. o, n = ensure(b, 18)
  412. o[n] = mfixext16
  413. o[n+1] = byte(e.ExtensionType())
  414. n += 2
  415. default:
  416. switch {
  417. case l < math.MaxUint8:
  418. o, n = ensure(b, l+3)
  419. o[n] = mext8
  420. o[n+1] = byte(uint8(l))
  421. o[n+2] = byte(e.ExtensionType())
  422. n += 3
  423. case l < math.MaxUint16:
  424. o, n = ensure(b, l+4)
  425. o[n] = mext16
  426. big.PutUint16(o[n+1:], uint16(l))
  427. o[n+3] = byte(e.ExtensionType())
  428. n += 4
  429. default:
  430. o, n = ensure(b, l+6)
  431. o[n] = mext32
  432. big.PutUint32(o[n+1:], uint32(l))
  433. o[n+5] = byte(e.ExtensionType())
  434. n += 6
  435. }
  436. }
  437. return o, e.MarshalBinaryTo(o[n:])
  438. }
  439. // ReadExtensionBytes reads an extension from 'b' into 'e'
  440. // and returns any remaining bytes.
  441. // Possible errors:
  442. // - ErrShortBytes ('b' not long enough)
  443. // - ExtensionTypeError{} (wire type not the same as e.Type())
  444. // - TypeError{} (next object not an extension)
  445. // - InvalidPrefixError
  446. // - An umarshal error returned from e.UnmarshalBinary
  447. func ReadExtensionBytes(b []byte, e Extension) ([]byte, error) {
  448. l := len(b)
  449. if l < 3 {
  450. return b, ErrShortBytes
  451. }
  452. lead := b[0]
  453. var (
  454. sz int // size of 'data'
  455. off int // offset of 'data'
  456. typ int8
  457. )
  458. switch lead {
  459. case mfixext1:
  460. typ = int8(b[1])
  461. sz = 1
  462. off = 2
  463. case mfixext2:
  464. typ = int8(b[1])
  465. sz = 2
  466. off = 2
  467. case mfixext4:
  468. typ = int8(b[1])
  469. sz = 4
  470. off = 2
  471. case mfixext8:
  472. typ = int8(b[1])
  473. sz = 8
  474. off = 2
  475. case mfixext16:
  476. typ = int8(b[1])
  477. sz = 16
  478. off = 2
  479. case mext8:
  480. sz = int(uint8(b[1]))
  481. typ = int8(b[2])
  482. off = 3
  483. if sz == 0 {
  484. return b[3:], e.UnmarshalBinary(b[3:3])
  485. }
  486. case mext16:
  487. if l < 4 {
  488. return b, ErrShortBytes
  489. }
  490. sz = int(big.Uint16(b[1:]))
  491. typ = int8(b[3])
  492. off = 4
  493. case mext32:
  494. if l < 6 {
  495. return b, ErrShortBytes
  496. }
  497. sz = int(big.Uint32(b[1:]))
  498. typ = int8(b[5])
  499. off = 6
  500. default:
  501. return b, badPrefix(ExtensionType, lead)
  502. }
  503. if typ != e.ExtensionType() {
  504. return b, errExt(typ, e.ExtensionType())
  505. }
  506. // the data of the extension starts
  507. // at 'off' and is 'sz' bytes long
  508. if len(b[off:]) < sz {
  509. return b, ErrShortBytes
  510. }
  511. tot := off + sz
  512. return b[tot:], e.UnmarshalBinary(b[off:tot])
  513. }