json.go 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. package msgp
  2. import (
  3. "bufio"
  4. "encoding/base64"
  5. "encoding/json"
  6. "io"
  7. "strconv"
  8. "unicode/utf8"
  9. )
  10. var (
  11. null = []byte("null")
  12. hex = []byte("0123456789abcdef")
  13. )
  14. var defuns [_maxtype]func(jsWriter, *Reader) (int, error)
  15. // note: there is an initialization loop if
  16. // this isn't set up during init()
  17. func init() {
  18. // since none of these functions are inline-able,
  19. // there is not much of a penalty to the indirect
  20. // call. however, this is best expressed as a jump-table...
  21. defuns = [_maxtype]func(jsWriter, *Reader) (int, error){
  22. StrType: rwString,
  23. BinType: rwBytes,
  24. MapType: rwMap,
  25. ArrayType: rwArray,
  26. Float64Type: rwFloat64,
  27. Float32Type: rwFloat32,
  28. BoolType: rwBool,
  29. IntType: rwInt,
  30. UintType: rwUint,
  31. NilType: rwNil,
  32. ExtensionType: rwExtension,
  33. Complex64Type: rwExtension,
  34. Complex128Type: rwExtension,
  35. TimeType: rwTime,
  36. }
  37. }
  38. // this is the interface
  39. // used to write json
  40. type jsWriter interface {
  41. io.Writer
  42. io.ByteWriter
  43. WriteString(string) (int, error)
  44. }
  45. // CopyToJSON reads MessagePack from 'src' and copies it
  46. // as JSON to 'dst' until EOF.
  47. func CopyToJSON(dst io.Writer, src io.Reader) (n int64, err error) {
  48. r := NewReader(src)
  49. n, err = r.WriteToJSON(dst)
  50. freeR(r)
  51. return
  52. }
  53. // WriteToJSON translates MessagePack from 'r' and writes it as
  54. // JSON to 'w' until the underlying reader returns io.EOF. It returns
  55. // the number of bytes written, and an error if it stopped before EOF.
  56. func (r *Reader) WriteToJSON(w io.Writer) (n int64, err error) {
  57. var j jsWriter
  58. var bf *bufio.Writer
  59. if jsw, ok := w.(jsWriter); ok {
  60. j = jsw
  61. } else {
  62. bf = bufio.NewWriter(w)
  63. j = bf
  64. }
  65. var nn int
  66. for err == nil {
  67. nn, err = rwNext(j, r)
  68. n += int64(nn)
  69. }
  70. if err != io.EOF {
  71. if bf != nil {
  72. bf.Flush()
  73. }
  74. return
  75. }
  76. err = nil
  77. if bf != nil {
  78. err = bf.Flush()
  79. }
  80. return
  81. }
  82. func rwNext(w jsWriter, src *Reader) (int, error) {
  83. t, err := src.NextType()
  84. if err != nil {
  85. return 0, err
  86. }
  87. return defuns[t](w, src)
  88. }
  89. func rwMap(dst jsWriter, src *Reader) (n int, err error) {
  90. var comma bool
  91. var sz uint32
  92. var field []byte
  93. sz, err = src.ReadMapHeader()
  94. if err != nil {
  95. return
  96. }
  97. if sz == 0 {
  98. return dst.WriteString("{}")
  99. }
  100. err = dst.WriteByte('{')
  101. if err != nil {
  102. return
  103. }
  104. n++
  105. var nn int
  106. for i := uint32(0); i < sz; i++ {
  107. if comma {
  108. err = dst.WriteByte(',')
  109. if err != nil {
  110. return
  111. }
  112. n++
  113. }
  114. field, err = src.ReadMapKeyPtr()
  115. if err != nil {
  116. return
  117. }
  118. nn, err = rwquoted(dst, field)
  119. n += nn
  120. if err != nil {
  121. return
  122. }
  123. err = dst.WriteByte(':')
  124. if err != nil {
  125. return
  126. }
  127. n++
  128. nn, err = rwNext(dst, src)
  129. n += nn
  130. if err != nil {
  131. return
  132. }
  133. if !comma {
  134. comma = true
  135. }
  136. }
  137. err = dst.WriteByte('}')
  138. if err != nil {
  139. return
  140. }
  141. n++
  142. return
  143. }
  144. func rwArray(dst jsWriter, src *Reader) (n int, err error) {
  145. err = dst.WriteByte('[')
  146. if err != nil {
  147. return
  148. }
  149. var sz uint32
  150. var nn int
  151. sz, err = src.ReadArrayHeader()
  152. if err != nil {
  153. return
  154. }
  155. comma := false
  156. for i := uint32(0); i < sz; i++ {
  157. if comma {
  158. err = dst.WriteByte(',')
  159. if err != nil {
  160. return
  161. }
  162. n++
  163. }
  164. nn, err = rwNext(dst, src)
  165. n += nn
  166. if err != nil {
  167. return
  168. }
  169. comma = true
  170. }
  171. err = dst.WriteByte(']')
  172. if err != nil {
  173. return
  174. }
  175. n++
  176. return
  177. }
  178. func rwNil(dst jsWriter, src *Reader) (int, error) {
  179. err := src.ReadNil()
  180. if err != nil {
  181. return 0, err
  182. }
  183. return dst.Write(null)
  184. }
  185. func rwFloat32(dst jsWriter, src *Reader) (int, error) {
  186. f, err := src.ReadFloat32()
  187. if err != nil {
  188. return 0, err
  189. }
  190. src.scratch = strconv.AppendFloat(src.scratch[:0], float64(f), 'f', -1, 32)
  191. return dst.Write(src.scratch)
  192. }
  193. func rwFloat64(dst jsWriter, src *Reader) (int, error) {
  194. f, err := src.ReadFloat64()
  195. if err != nil {
  196. return 0, err
  197. }
  198. src.scratch = strconv.AppendFloat(src.scratch[:0], f, 'f', -1, 64)
  199. return dst.Write(src.scratch)
  200. }
  201. func rwInt(dst jsWriter, src *Reader) (int, error) {
  202. i, err := src.ReadInt64()
  203. if err != nil {
  204. return 0, err
  205. }
  206. src.scratch = strconv.AppendInt(src.scratch[:0], i, 10)
  207. return dst.Write(src.scratch)
  208. }
  209. func rwUint(dst jsWriter, src *Reader) (int, error) {
  210. u, err := src.ReadUint64()
  211. if err != nil {
  212. return 0, err
  213. }
  214. src.scratch = strconv.AppendUint(src.scratch[:0], u, 10)
  215. return dst.Write(src.scratch)
  216. }
  217. func rwBool(dst jsWriter, src *Reader) (int, error) {
  218. b, err := src.ReadBool()
  219. if err != nil {
  220. return 0, err
  221. }
  222. if b {
  223. return dst.WriteString("true")
  224. }
  225. return dst.WriteString("false")
  226. }
  227. func rwTime(dst jsWriter, src *Reader) (int, error) {
  228. t, err := src.ReadTime()
  229. if err != nil {
  230. return 0, err
  231. }
  232. bts, err := t.MarshalJSON()
  233. if err != nil {
  234. return 0, err
  235. }
  236. return dst.Write(bts)
  237. }
  238. func rwExtension(dst jsWriter, src *Reader) (n int, err error) {
  239. et, err := src.peekExtensionType()
  240. if err != nil {
  241. return 0, err
  242. }
  243. // registered extensions can override
  244. // the JSON encoding
  245. if j, ok := extensionReg[et]; ok {
  246. var bts []byte
  247. e := j()
  248. err = src.ReadExtension(e)
  249. if err != nil {
  250. return
  251. }
  252. bts, err = json.Marshal(e)
  253. if err != nil {
  254. return
  255. }
  256. return dst.Write(bts)
  257. }
  258. e := RawExtension{}
  259. e.Type = et
  260. err = src.ReadExtension(&e)
  261. if err != nil {
  262. return
  263. }
  264. var nn int
  265. err = dst.WriteByte('{')
  266. if err != nil {
  267. return
  268. }
  269. n++
  270. nn, err = dst.WriteString(`"type:"`)
  271. n += nn
  272. if err != nil {
  273. return
  274. }
  275. src.scratch = strconv.AppendInt(src.scratch[0:0], int64(e.Type), 10)
  276. nn, err = dst.Write(src.scratch)
  277. n += nn
  278. if err != nil {
  279. return
  280. }
  281. nn, err = dst.WriteString(`,"data":"`)
  282. n += nn
  283. if err != nil {
  284. return
  285. }
  286. enc := base64.NewEncoder(base64.StdEncoding, dst)
  287. nn, err = enc.Write(e.Data)
  288. n += nn
  289. if err != nil {
  290. return
  291. }
  292. err = enc.Close()
  293. if err != nil {
  294. return
  295. }
  296. nn, err = dst.WriteString(`"}`)
  297. n += nn
  298. return
  299. }
  300. func rwString(dst jsWriter, src *Reader) (n int, err error) {
  301. var p []byte
  302. p, err = src.R.Peek(1)
  303. if err != nil {
  304. return
  305. }
  306. lead := p[0]
  307. var read int
  308. if isfixstr(lead) {
  309. read = int(rfixstr(lead))
  310. src.R.Skip(1)
  311. goto write
  312. }
  313. switch lead {
  314. case mstr8:
  315. p, err = src.R.Next(2)
  316. if err != nil {
  317. return
  318. }
  319. read = int(uint8(p[1]))
  320. case mstr16:
  321. p, err = src.R.Next(3)
  322. if err != nil {
  323. return
  324. }
  325. read = int(big.Uint16(p[1:]))
  326. case mstr32:
  327. p, err = src.R.Next(5)
  328. if err != nil {
  329. return
  330. }
  331. read = int(big.Uint32(p[1:]))
  332. default:
  333. err = badPrefix(StrType, lead)
  334. return
  335. }
  336. write:
  337. p, err = src.R.Next(read)
  338. if err != nil {
  339. return
  340. }
  341. n, err = rwquoted(dst, p)
  342. return
  343. }
  344. func rwBytes(dst jsWriter, src *Reader) (n int, err error) {
  345. var nn int
  346. err = dst.WriteByte('"')
  347. if err != nil {
  348. return
  349. }
  350. n++
  351. src.scratch, err = src.ReadBytes(src.scratch[:0])
  352. if err != nil {
  353. return
  354. }
  355. enc := base64.NewEncoder(base64.StdEncoding, dst)
  356. nn, err = enc.Write(src.scratch)
  357. n += nn
  358. if err != nil {
  359. return
  360. }
  361. err = enc.Close()
  362. if err != nil {
  363. return
  364. }
  365. err = dst.WriteByte('"')
  366. if err != nil {
  367. return
  368. }
  369. n++
  370. return
  371. }
  372. // Below (c) The Go Authors, 2009-2014
  373. // Subject to the BSD-style license found at http://golang.org
  374. //
  375. // see: encoding/json/encode.go:(*encodeState).stringbytes()
  376. func rwquoted(dst jsWriter, s []byte) (n int, err error) {
  377. var nn int
  378. err = dst.WriteByte('"')
  379. if err != nil {
  380. return
  381. }
  382. n++
  383. start := 0
  384. for i := 0; i < len(s); {
  385. if b := s[i]; b < utf8.RuneSelf {
  386. if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
  387. i++
  388. continue
  389. }
  390. if start < i {
  391. nn, err = dst.Write(s[start:i])
  392. n += nn
  393. if err != nil {
  394. return
  395. }
  396. }
  397. switch b {
  398. case '\\', '"':
  399. err = dst.WriteByte('\\')
  400. if err != nil {
  401. return
  402. }
  403. n++
  404. err = dst.WriteByte(b)
  405. if err != nil {
  406. return
  407. }
  408. n++
  409. case '\n':
  410. err = dst.WriteByte('\\')
  411. if err != nil {
  412. return
  413. }
  414. n++
  415. err = dst.WriteByte('n')
  416. if err != nil {
  417. return
  418. }
  419. n++
  420. case '\r':
  421. err = dst.WriteByte('\\')
  422. if err != nil {
  423. return
  424. }
  425. n++
  426. err = dst.WriteByte('r')
  427. if err != nil {
  428. return
  429. }
  430. n++
  431. case '\t':
  432. err = dst.WriteByte('\\')
  433. if err != nil {
  434. return
  435. }
  436. n++
  437. err = dst.WriteByte('t')
  438. if err != nil {
  439. return
  440. }
  441. n++
  442. default:
  443. // This encodes bytes < 0x20 except for \t, \n and \r.
  444. // It also escapes <, >, and &
  445. // because they can lead to security holes when
  446. // user-controlled strings are rendered into JSON
  447. // and served to some browsers.
  448. nn, err = dst.WriteString(`\u00`)
  449. n += nn
  450. if err != nil {
  451. return
  452. }
  453. err = dst.WriteByte(hex[b>>4])
  454. if err != nil {
  455. return
  456. }
  457. n++
  458. err = dst.WriteByte(hex[b&0xF])
  459. if err != nil {
  460. return
  461. }
  462. n++
  463. }
  464. i++
  465. start = i
  466. continue
  467. }
  468. c, size := utf8.DecodeRune(s[i:])
  469. if c == utf8.RuneError && size == 1 {
  470. if start < i {
  471. nn, err = dst.Write(s[start:i])
  472. n += nn
  473. if err != nil {
  474. return
  475. }
  476. }
  477. nn, err = dst.WriteString(`\ufffd`)
  478. n += nn
  479. if err != nil {
  480. return
  481. }
  482. i += size
  483. start = i
  484. continue
  485. }
  486. // U+2028 is LINE SEPARATOR.
  487. // U+2029 is PARAGRAPH SEPARATOR.
  488. // They are both technically valid characters in JSON strings,
  489. // but don't work in JSONP, which has to be evaluated as JavaScript,
  490. // and can lead to security holes there. It is valid JSON to
  491. // escape them, so we do so unconditionally.
  492. // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
  493. if c == '\u2028' || c == '\u2029' {
  494. if start < i {
  495. nn, err = dst.Write(s[start:i])
  496. n += nn
  497. if err != nil {
  498. return
  499. }
  500. }
  501. nn, err = dst.WriteString(`\u202`)
  502. n += nn
  503. if err != nil {
  504. return
  505. }
  506. err = dst.WriteByte(hex[c&0xF])
  507. if err != nil {
  508. return
  509. }
  510. n++
  511. i += size
  512. start = i
  513. continue
  514. }
  515. i += size
  516. }
  517. if start < len(s) {
  518. nn, err = dst.Write(s[start:])
  519. n += nn
  520. if err != nil {
  521. return
  522. }
  523. }
  524. err = dst.WriteByte('"')
  525. if err != nil {
  526. return
  527. }
  528. n++
  529. return
  530. }