jsonutils.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package jsonutils
  15. import (
  16. "bytes"
  17. "reflect"
  18. "strconv"
  19. "strings"
  20. "time"
  21. "unicode/utf8"
  22. "yunion.io/x/log"
  23. "yunion.io/x/pkg/errors"
  24. "yunion.io/x/pkg/gotypes"
  25. "yunion.io/x/pkg/sortedmap"
  26. )
  27. // swagger:type object
  28. type JSONObject interface {
  29. gotypes.ISerializable
  30. parse(s *sJsonParseSession, str []byte, offset int) (int, error)
  31. writeSource
  32. // String() string
  33. PrettyString() string
  34. prettyString(level int) string
  35. YAMLString() string
  36. QueryString() string
  37. _queryString(key string) string
  38. Contains(keys ...string) bool
  39. ContainsIgnoreCases(keys ...string) bool
  40. Get(keys ...string) (JSONObject, error)
  41. GetIgnoreCases(keys ...string) (JSONObject, error)
  42. GetAt(i int, keys ...string) (JSONObject, error)
  43. Int(keys ...string) (int64, error)
  44. Float(keys ...string) (float64, error)
  45. Bool(keys ...string) (bool, error)
  46. GetMap(keys ...string) (map[string]JSONObject, error)
  47. GetArray(keys ...string) ([]JSONObject, error)
  48. GetTime(keys ...string) (time.Time, error)
  49. GetString(keys ...string) (string, error)
  50. Unmarshal(obj interface{}, keys ...string) error
  51. Equals(obj JSONObject) bool
  52. unmarshalValue(s *sJsonUnmarshalSession, val reflect.Value) error
  53. // IsZero() bool
  54. Interface() interface{}
  55. isCompond() bool
  56. }
  57. type JSONValue struct {
  58. }
  59. var (
  60. JSONNull = &JSONValue{}
  61. JSONTrue = &JSONBool{data: true}
  62. JSONFalse = &JSONBool{data: false}
  63. )
  64. // swagger:type object
  65. type JSONDict struct {
  66. JSONValue
  67. data sortedmap.SSortedMap
  68. nodeId int
  69. }
  70. type JSONArray struct {
  71. JSONValue
  72. data []JSONObject
  73. }
  74. type JSONString struct {
  75. JSONValue
  76. data string
  77. }
  78. type JSONInt struct {
  79. JSONValue
  80. data int64
  81. }
  82. type JSONFloat struct {
  83. JSONValue
  84. data float64
  85. bit int
  86. }
  87. type JSONBool struct {
  88. JSONValue
  89. data bool
  90. }
  91. func skipEmpty(str []byte, offset int) int {
  92. i := offset
  93. for i < len(str) {
  94. switch str[i] {
  95. case ' ', '\t', '\n', '\r':
  96. i++
  97. default:
  98. return i
  99. }
  100. }
  101. return i
  102. }
  103. func hexchar2num(v byte) (byte, error) {
  104. switch {
  105. case v >= '0' && v <= '9':
  106. return v - '0', nil
  107. case v >= 'a' && v <= 'f':
  108. return v - 'a' + 10, nil
  109. case v >= 'A' && v <= 'F':
  110. return v - 'A' + 10, nil
  111. default:
  112. return 0, ErrInvalidChar // fmt.Errorf("Illegal char %c", v)
  113. }
  114. }
  115. func hexstr2byte(str []byte) (byte, error) {
  116. if len(str) < 2 {
  117. return 0, ErrInvalidHex // fmt.Errorf("Input must be 2 hex chars")
  118. }
  119. v1, e := hexchar2num(str[0])
  120. if e != nil {
  121. return 0, e
  122. }
  123. v2, e := hexchar2num(str[1])
  124. if e != nil {
  125. return 0, e
  126. }
  127. return v1*16 + v2, nil
  128. }
  129. func hexstr2rune(str []byte) (rune, error) {
  130. if len(str) < 4 {
  131. return 0, ErrInvalidRune // fmt.Errorf("Input must be 4 hex chars")
  132. }
  133. v1, e := hexstr2byte(str[0:2])
  134. if e != nil {
  135. return 0, e
  136. }
  137. v2, e := hexstr2byte(str[2:4])
  138. if e != nil {
  139. return 0, e
  140. }
  141. return rune(v1)*256 + rune(v2), nil
  142. }
  143. func parseQuoteString(str []byte, offset int, quotec byte) (string, int, error) {
  144. var (
  145. buffer []byte
  146. runebytes = make([]byte, 4)
  147. runen int
  148. i = offset
  149. )
  150. ret:
  151. for i < len(str) {
  152. switch str[i] {
  153. case '\\':
  154. if i+1 < len(str) {
  155. i++
  156. switch str[i] {
  157. case 'u':
  158. i++
  159. if i+4 >= len(str) {
  160. return "", i, NewJSONError(str, i, "Incomplete unicode")
  161. }
  162. r, e := hexstr2rune(str[i : i+4])
  163. if e != nil {
  164. return "", i, NewJSONError(str, i, e.Error())
  165. }
  166. runen = utf8.EncodeRune(runebytes, r)
  167. buffer = append(buffer, runebytes[0:runen]...)
  168. i += 4
  169. case 'x':
  170. i++
  171. if i+2 >= len(str) {
  172. return "", i, NewJSONError(str, i, "Incomplete hex")
  173. }
  174. b, e := hexstr2byte(str[i : i+2])
  175. if e != nil {
  176. return "", i, NewJSONError(str, i, e.Error())
  177. }
  178. buffer = append(buffer, b)
  179. i += 2
  180. case 'n':
  181. buffer = append(buffer, '\n')
  182. i++
  183. case 'r':
  184. buffer = append(buffer, '\r')
  185. i++
  186. case 't':
  187. buffer = append(buffer, '\t')
  188. i++
  189. case 'b':
  190. buffer = append(buffer, '\b')
  191. i++
  192. case 'f':
  193. buffer = append(buffer, '\f')
  194. i++
  195. case '\\':
  196. buffer = append(buffer, '\\')
  197. i++
  198. default:
  199. buffer = append(buffer, str[i])
  200. i++
  201. }
  202. } else {
  203. return "", i, NewJSONError(str, i, "Incomplete escape")
  204. }
  205. case quotec:
  206. i++
  207. break ret
  208. default:
  209. buffer = append(buffer, str[i])
  210. i++
  211. }
  212. }
  213. return string(buffer), i, nil
  214. }
  215. func parseString(str []byte, offset int) (string, bool, int, error) {
  216. var (
  217. i = offset
  218. )
  219. if c := str[i]; c == '"' || c == '\'' {
  220. r, newOfs, err := parseQuoteString(str, i+1, c)
  221. return r, true, newOfs, err
  222. }
  223. ret2:
  224. for i < len(str) {
  225. switch str[i] {
  226. case ' ', ':', ',', '\t', '\r', '\n', '}', ']':
  227. break ret2
  228. default:
  229. i++
  230. }
  231. }
  232. return string(str[offset:i]), false, i, nil
  233. }
  234. func (s *sJsonParseSession) parseJSONValue(str []byte, offset int) (JSONObject, int, error) {
  235. val, quote, i, e := parseString(str, offset)
  236. if e != nil {
  237. return nil, i, errors.Wrap(e, "parseString")
  238. } else if quote {
  239. return &JSONString{data: val}, i, nil
  240. } else if val[0] == '<' && val[len(val)-1] == '>' {
  241. // Pointer <nnnn>
  242. val = val[1 : len(val)-1]
  243. ival, err := strconv.ParseInt(val, 10, 64)
  244. if err != nil {
  245. return nil, i, errors.Wrapf(errors.ErrInvalidStatus, "invalid node id %s", val)
  246. }
  247. nodeId := int(ival)
  248. ptr := &sJSONPointer{
  249. nodeId: nodeId,
  250. }
  251. s.saveReferer(nodeId, ptr)
  252. return ptr, i, nil
  253. } else {
  254. lval := strings.ToLower(val)
  255. if len(lval) == 0 || lval == "null" || lval == "none" {
  256. return JSONNull, i, nil
  257. }
  258. if lval == "true" || lval == "yes" {
  259. return JSONTrue, i, nil
  260. }
  261. if lval == "false" || lval == "no" {
  262. return JSONFalse, i, nil
  263. }
  264. ival, err := strconv.ParseInt(val, 10, 64)
  265. if err == nil {
  266. return &JSONInt{data: ival}, i, nil
  267. }
  268. fval, err := strconv.ParseFloat(val, 64)
  269. if err == nil {
  270. return &JSONFloat{data: fval}, i, nil
  271. }
  272. return &JSONString{data: val}, i, nil
  273. }
  274. }
  275. // https://www.ietf.org/rfc/rfc4627.txt
  276. //
  277. // string = quotation-mark *char quotation-mark
  278. //
  279. // char = unescaped /
  280. // escape (
  281. // %x22 / ; " quotation mark U+0022
  282. // %x5C / ; \ reverse solidus U+005C
  283. // %x2F / ; / solidus U+002F
  284. // %x62 / ; b backspace U+0008
  285. // %x66 / ; f form feed U+000C
  286. // %x6E / ; n line feed U+000A
  287. // %x72 / ; r carriage return U+000D
  288. // %x74 / ; t tab U+0009
  289. // %x75 4HEXDIG ) ; uXXXX U+XXXX
  290. //
  291. // escape = %x5C ; \
  292. //
  293. // quotation-mark = %x22 ; "
  294. //
  295. // unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
  296. func escapeJsonChar(sb *strings.Builder, ch byte) {
  297. switch ch {
  298. case '"':
  299. sb.Write([]byte{'\\', '"'})
  300. case '\\':
  301. sb.Write([]byte{'\\', '\\'})
  302. case '\b':
  303. sb.Write([]byte{'\\', 'b'})
  304. case '\f':
  305. sb.Write([]byte{'\\', 'f'})
  306. case '\n':
  307. sb.Write([]byte{'\\', 'n'})
  308. case '\r':
  309. sb.Write([]byte{'\\', 'r'})
  310. case '\t':
  311. sb.Write([]byte{'\\', 't'})
  312. default:
  313. sb.WriteByte(ch)
  314. /*if ((ch >= 0x20 && ch <= 0x21) || (ch >= 0x23 || ch <= 0x5B) || (ch >= 0x5D && ch <= 0x10FFFF)) && ch != 0x81 && ch != 0x8d && ch != 0x8f && ch != 0x90 && ch != 0x9d {
  315. sb.WriteRune(ch)
  316. } else if ch <= 0xff {
  317. sb.Write([]byte{'\\', 'x'})
  318. sb.WriteString(fmt.Sprintf("%02x", ch))
  319. } else if ch <= 0xffff {
  320. sb.Write([]byte{'\\', 'u'})
  321. sb.WriteString(fmt.Sprintf("%04x", ch))
  322. } else {
  323. sb.Write([]byte{'\\', 'u'})
  324. sb.WriteString(fmt.Sprintf("%04x", ch>>16))
  325. sb.Write([]byte{'\\', 'u'})
  326. sb.WriteString(fmt.Sprintf("%04x", (ch & 0xffff)))
  327. }*/
  328. }
  329. }
  330. func quoteString(str string) string {
  331. sb := &strings.Builder{}
  332. sb.Grow(len(str) + 2)
  333. sb.WriteByte('"')
  334. for i := 0; i < len(str); i += 1 {
  335. escapeJsonChar(sb, str[i])
  336. }
  337. sb.WriteByte('"')
  338. return sb.String()
  339. }
  340. func jsonPrettyString(o JSONObject, level int) string {
  341. var buffer bytes.Buffer
  342. for i := 0; i < level; i++ {
  343. buffer.WriteString(" ")
  344. }
  345. buffer.WriteString(o.String())
  346. return buffer.String()
  347. }
  348. func (this *JSONString) PrettyString() string {
  349. return this.String()
  350. }
  351. func (this *JSONString) prettyString(level int) string {
  352. return jsonPrettyString(this, level)
  353. }
  354. func (this *JSONValue) parse(s *sJsonParseSession, str []byte, offset int) (int, error) {
  355. return 0, nil
  356. }
  357. func (this *JSONValue) PrettyString() string {
  358. return this.String()
  359. }
  360. func (this *JSONValue) prettyString(level int) string {
  361. return jsonPrettyString(this, level)
  362. }
  363. func (this *JSONInt) PrettyString() string {
  364. return this.String()
  365. }
  366. func (this *JSONInt) prettyString(level int) string {
  367. return jsonPrettyString(this, level)
  368. }
  369. func (this *JSONFloat) PrettyString() string {
  370. return this.String()
  371. }
  372. func (this *JSONFloat) prettyString(level int) string {
  373. return jsonPrettyString(this, level)
  374. }
  375. func (this *JSONBool) PrettyString() string {
  376. return this.String()
  377. }
  378. func (this *JSONBool) prettyString(level int) string {
  379. return jsonPrettyString(this, level)
  380. }
  381. func (s *sJsonParseSession) parseDict(str []byte, offset int) (sortedmap.SSortedMap, int, int, error) {
  382. var nodeId int
  383. smap := sortedmap.NewSortedMap()
  384. if str[offset] != '{' {
  385. return smap, offset, nodeId, NewJSONError(str, offset, "{ not found")
  386. }
  387. var i = offset + 1
  388. var e error = nil
  389. var key string
  390. var stop = false
  391. for !stop && i < len(str) {
  392. i = skipEmpty(str, i)
  393. if i >= len(str) {
  394. return smap, i, nodeId, NewJSONError(str, i, "Truncated")
  395. }
  396. if str[i] == '}' {
  397. stop = true
  398. i++
  399. continue
  400. }
  401. key, _, i, e = parseString(str, i)
  402. if e != nil {
  403. return smap, i, nodeId, errors.Wrap(e, "parseString")
  404. }
  405. if i >= len(str) {
  406. return smap, i, nodeId, NewJSONError(str, i, "Truncated")
  407. }
  408. i = skipEmpty(str, i)
  409. if i >= len(str) {
  410. return smap, i, nodeId, NewJSONError(str, i, "Truncated")
  411. }
  412. if str[i] != ':' {
  413. return smap, i, nodeId, NewJSONError(str, i, ": not found")
  414. }
  415. i++
  416. i = skipEmpty(str, i)
  417. if i >= len(str) {
  418. return smap, i, nodeId, NewJSONError(str, i, "Truncated")
  419. }
  420. var val JSONObject = nil
  421. switch str[i] {
  422. case '[':
  423. val = &JSONArray{}
  424. i, e = val.parse(s, str, i)
  425. case '{':
  426. val = &JSONDict{}
  427. i, e = val.parse(s, str, i)
  428. default:
  429. val, i, e = s.parseJSONValue(str, i)
  430. }
  431. if e != nil {
  432. return smap, i, nodeId, errors.Wrap(e, "parse misc")
  433. }
  434. if key == jsonPointerKey {
  435. // node id
  436. nodeId = int(val.(*JSONInt).data)
  437. } else {
  438. smap = sortedmap.Add(smap, key, val)
  439. }
  440. i = skipEmpty(str, i)
  441. if i >= len(str) {
  442. return smap, i, nodeId, NewJSONError(str, i, "Truncated")
  443. }
  444. switch str[i] {
  445. case ',':
  446. i++
  447. case '}':
  448. i++
  449. stop = true
  450. default:
  451. return smap, i, nodeId, NewJSONError(str, i, "Unexpected char")
  452. }
  453. }
  454. return smap, i, nodeId, nil
  455. }
  456. func (s *sJsonParseSession) parseArray(str []byte, offset int) ([]JSONObject, int, error) {
  457. if str[offset] != '[' {
  458. return nil, offset, NewJSONError(str, offset, "[ not found")
  459. }
  460. var (
  461. list []JSONObject
  462. i = offset + 1
  463. val JSONObject
  464. e error
  465. stop bool
  466. )
  467. for !stop && i < len(str) {
  468. i = skipEmpty(str, i)
  469. if i >= len(str) {
  470. return list, i, NewJSONError(str, i, "Truncated")
  471. }
  472. switch str[i] {
  473. case ']':
  474. i++
  475. stop = true
  476. continue
  477. case '[':
  478. val = &JSONArray{}
  479. i, e = val.parse(s, str, i)
  480. case '{':
  481. val = &JSONDict{}
  482. i, e = val.parse(s, str, i)
  483. default:
  484. val, i, e = s.parseJSONValue(str, i)
  485. }
  486. if e != nil {
  487. return list, i, errors.Wrap(e, "parse misc")
  488. }
  489. if i >= len(str) {
  490. return list, i, NewJSONError(str, i, "Truncated")
  491. }
  492. list = append(list, val)
  493. i = skipEmpty(str, i)
  494. if i >= len(str) {
  495. return list, i, NewJSONError(str, i, "Truncated")
  496. }
  497. switch str[i] {
  498. case ',':
  499. i++
  500. case ']':
  501. i++
  502. stop = true
  503. default:
  504. return list, i, NewJSONError(str, i, "Unexpected char")
  505. }
  506. }
  507. return list, i, nil
  508. }
  509. func (this *JSONDict) parse(s *sJsonParseSession, str []byte, offset int) (int, error) {
  510. smap, i, nodeId, e := s.parseDict(str, offset)
  511. if e == nil {
  512. this.nodeId = nodeId
  513. this.data = smap
  514. if this.nodeId > 0 {
  515. s.saveNode(nodeId, this)
  516. }
  517. return i, nil
  518. }
  519. return i, errors.Wrap(e, "parseDict")
  520. }
  521. func (this *JSONDict) SortedKeys() []string {
  522. return this.data.Keys()
  523. }
  524. func (this *JSONDict) PrettyString() string {
  525. return this.prettyString(0)
  526. }
  527. func (this *JSONDict) prettyString(level int) string {
  528. var buffer bytes.Buffer
  529. var linebuf bytes.Buffer
  530. for i := 0; i < level; i++ {
  531. linebuf.WriteString(" ")
  532. }
  533. var tab = linebuf.String()
  534. buffer.WriteString(tab)
  535. buffer.WriteByte('{')
  536. var idx = 0
  537. for iter := sortedmap.NewIterator(this.data); iter.HasMore(); iter.Next() {
  538. k, vInf := iter.Get()
  539. v := vInf.(JSONObject)
  540. if idx > 0 {
  541. buffer.WriteString(",")
  542. }
  543. buffer.WriteByte('\n')
  544. buffer.WriteString(tab)
  545. buffer.WriteString(" ")
  546. buffer.WriteByte('"')
  547. buffer.WriteString(k)
  548. buffer.WriteString("\":")
  549. _, okdict := v.(*JSONDict)
  550. _, okarray := v.(*JSONArray)
  551. if okdict || okarray {
  552. buffer.WriteByte('\n')
  553. buffer.WriteString(v.prettyString(level + 2))
  554. } else {
  555. buffer.WriteByte(' ')
  556. buffer.WriteString(v.String())
  557. }
  558. idx++
  559. }
  560. if len(this.data) > 0 {
  561. buffer.WriteByte('\n')
  562. buffer.WriteString(tab)
  563. }
  564. buffer.WriteByte('}')
  565. return buffer.String()
  566. }
  567. func (this *JSONArray) parse(s *sJsonParseSession, str []byte, offset int) (int, error) {
  568. val, i, e := s.parseArray(str, offset)
  569. if e == nil {
  570. this.data = val
  571. }
  572. return i, errors.Wrap(e, "parseArray")
  573. }
  574. func (this *JSONArray) PrettyString() string {
  575. return this.prettyString(0)
  576. }
  577. func (this *JSONArray) prettyString(level int) string {
  578. var buffer bytes.Buffer
  579. var linebuf bytes.Buffer
  580. for i := 0; i < level; i++ {
  581. linebuf.WriteString(" ")
  582. }
  583. var tab = linebuf.String()
  584. buffer.WriteString(tab)
  585. buffer.WriteByte('[')
  586. for idx, v := range this.data {
  587. if idx > 0 {
  588. buffer.WriteString(",")
  589. }
  590. buffer.WriteByte('\n')
  591. buffer.WriteString(v.prettyString(level + 1))
  592. }
  593. if len(this.data) > 0 {
  594. buffer.WriteByte('\n')
  595. buffer.WriteString(tab)
  596. }
  597. buffer.WriteByte(']')
  598. return buffer.String()
  599. }
  600. func ParseString(str string) (JSONObject, error) {
  601. return Parse([]byte(str))
  602. }
  603. func Parse(str []byte) (JSONObject, error) {
  604. json, _, err := ParseStream(str, 0)
  605. return json, err
  606. }
  607. func ParseStream(str []byte, offset int) (JSONObject, int, error) {
  608. s := newJsonParseSession()
  609. i := offset
  610. i = skipEmpty(str, i)
  611. var val JSONObject = nil
  612. var e error = nil
  613. if i < len(str) {
  614. switch str[i] {
  615. case '{':
  616. val = &JSONDict{}
  617. i, e = val.parse(s, str, i)
  618. case '[':
  619. val = &JSONArray{}
  620. i, e = val.parse(s, str, i)
  621. default:
  622. val, i, e = s.parseJSONValue(str, i)
  623. // return nil, NewJSONError(str, i, "Invalid JSON string")
  624. }
  625. if e != nil {
  626. return nil, i, errors.Wrap(e, "parse misc")
  627. } else {
  628. return val, i, nil
  629. }
  630. } else {
  631. return nil, i, NewJSONError(str, i, "Empty string")
  632. }
  633. }
  634. func ParseJsonStreams(stream []byte) ([]JSONObject, error) {
  635. ret := make([]JSONObject, 0)
  636. errs := make([]error, 0)
  637. offset := 0
  638. for offset < len(stream) {
  639. for offset < len(stream) && stream[offset] != '[' && stream[offset] != '{' {
  640. offset++
  641. }
  642. if offset >= len(stream) {
  643. break
  644. }
  645. json, noffset, err := ParseStream(stream, offset)
  646. if err != nil {
  647. errs = append(errs, errors.Wrapf(err, "jsonutils.ParseStream fail at %d", offset))
  648. offset++
  649. } else {
  650. ret = append(ret, json)
  651. offset = noffset
  652. }
  653. }
  654. if len(errs) > 0 && len(ret) == 0 {
  655. return nil, errors.NewAggregate(errs)
  656. }
  657. if len(errs) > 0 {
  658. log.Warningf("jsonutils.ParseJsonStreams: %d errors, %s", len(errs), errors.NewAggregate(errs))
  659. }
  660. return ret, nil
  661. }