encoder.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. package encoder
  2. import (
  3. "bytes"
  4. "encoding"
  5. "encoding/base64"
  6. "encoding/json"
  7. "fmt"
  8. "math"
  9. "reflect"
  10. "strconv"
  11. "strings"
  12. "sync"
  13. "unsafe"
  14. "github.com/goccy/go-json/internal/errors"
  15. "github.com/goccy/go-json/internal/runtime"
  16. )
  17. func (t OpType) IsMultipleOpHead() bool {
  18. switch t {
  19. case OpStructHead:
  20. return true
  21. case OpStructHeadSlice:
  22. return true
  23. case OpStructHeadArray:
  24. return true
  25. case OpStructHeadMap:
  26. return true
  27. case OpStructHeadStruct:
  28. return true
  29. case OpStructHeadOmitEmpty:
  30. return true
  31. case OpStructHeadOmitEmptySlice:
  32. return true
  33. case OpStructHeadOmitEmptyArray:
  34. return true
  35. case OpStructHeadOmitEmptyMap:
  36. return true
  37. case OpStructHeadOmitEmptyStruct:
  38. return true
  39. case OpStructHeadSlicePtr:
  40. return true
  41. case OpStructHeadOmitEmptySlicePtr:
  42. return true
  43. case OpStructHeadArrayPtr:
  44. return true
  45. case OpStructHeadOmitEmptyArrayPtr:
  46. return true
  47. case OpStructHeadMapPtr:
  48. return true
  49. case OpStructHeadOmitEmptyMapPtr:
  50. return true
  51. }
  52. return false
  53. }
  54. func (t OpType) IsMultipleOpField() bool {
  55. switch t {
  56. case OpStructField:
  57. return true
  58. case OpStructFieldSlice:
  59. return true
  60. case OpStructFieldArray:
  61. return true
  62. case OpStructFieldMap:
  63. return true
  64. case OpStructFieldStruct:
  65. return true
  66. case OpStructFieldOmitEmpty:
  67. return true
  68. case OpStructFieldOmitEmptySlice:
  69. return true
  70. case OpStructFieldOmitEmptyArray:
  71. return true
  72. case OpStructFieldOmitEmptyMap:
  73. return true
  74. case OpStructFieldOmitEmptyStruct:
  75. return true
  76. case OpStructFieldSlicePtr:
  77. return true
  78. case OpStructFieldOmitEmptySlicePtr:
  79. return true
  80. case OpStructFieldArrayPtr:
  81. return true
  82. case OpStructFieldOmitEmptyArrayPtr:
  83. return true
  84. case OpStructFieldMapPtr:
  85. return true
  86. case OpStructFieldOmitEmptyMapPtr:
  87. return true
  88. }
  89. return false
  90. }
  91. type OpcodeSet struct {
  92. Type *runtime.Type
  93. NoescapeKeyCode *Opcode
  94. EscapeKeyCode *Opcode
  95. InterfaceNoescapeKeyCode *Opcode
  96. InterfaceEscapeKeyCode *Opcode
  97. CodeLength int
  98. EndCode *Opcode
  99. Code Code
  100. QueryCache map[string]*OpcodeSet
  101. cacheMu sync.RWMutex
  102. }
  103. func (s *OpcodeSet) getQueryCache(hash string) *OpcodeSet {
  104. s.cacheMu.RLock()
  105. codeSet := s.QueryCache[hash]
  106. s.cacheMu.RUnlock()
  107. return codeSet
  108. }
  109. func (s *OpcodeSet) setQueryCache(hash string, codeSet *OpcodeSet) {
  110. s.cacheMu.Lock()
  111. s.QueryCache[hash] = codeSet
  112. s.cacheMu.Unlock()
  113. }
  114. type CompiledCode struct {
  115. Code *Opcode
  116. Linked bool // whether recursive code already have linked
  117. CurLen uintptr
  118. NextLen uintptr
  119. }
  120. const StartDetectingCyclesAfter = 1000
  121. func Load(base uintptr, idx uintptr) uintptr {
  122. addr := base + idx
  123. return **(**uintptr)(unsafe.Pointer(&addr))
  124. }
  125. func Store(base uintptr, idx uintptr, p uintptr) {
  126. addr := base + idx
  127. **(**uintptr)(unsafe.Pointer(&addr)) = p
  128. }
  129. func LoadNPtr(base uintptr, idx uintptr, ptrNum int) uintptr {
  130. addr := base + idx
  131. p := **(**uintptr)(unsafe.Pointer(&addr))
  132. if p == 0 {
  133. return 0
  134. }
  135. return PtrToPtr(p)
  136. /*
  137. for i := 0; i < ptrNum; i++ {
  138. if p == 0 {
  139. return p
  140. }
  141. p = PtrToPtr(p)
  142. }
  143. return p
  144. */
  145. }
  146. func PtrToUint64(p uintptr) uint64 { return **(**uint64)(unsafe.Pointer(&p)) }
  147. func PtrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) }
  148. func PtrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) }
  149. func PtrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) }
  150. func PtrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) }
  151. func PtrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) }
  152. func PtrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) }
  153. func PtrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) }
  154. func PtrToPtr(p uintptr) uintptr {
  155. return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
  156. }
  157. func PtrToNPtr(p uintptr, ptrNum int) uintptr {
  158. for i := 0; i < ptrNum; i++ {
  159. if p == 0 {
  160. return 0
  161. }
  162. p = PtrToPtr(p)
  163. }
  164. return p
  165. }
  166. func PtrToUnsafePtr(p uintptr) unsafe.Pointer {
  167. return *(*unsafe.Pointer)(unsafe.Pointer(&p))
  168. }
  169. func PtrToInterface(code *Opcode, p uintptr) interface{} {
  170. return *(*interface{})(unsafe.Pointer(&emptyInterface{
  171. typ: code.Type,
  172. ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
  173. }))
  174. }
  175. func ErrUnsupportedValue(code *Opcode, ptr uintptr) *errors.UnsupportedValueError {
  176. v := *(*interface{})(unsafe.Pointer(&emptyInterface{
  177. typ: code.Type,
  178. ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)),
  179. }))
  180. return &errors.UnsupportedValueError{
  181. Value: reflect.ValueOf(v),
  182. Str: fmt.Sprintf("encountered a cycle via %s", code.Type),
  183. }
  184. }
  185. func ErrUnsupportedFloat(v float64) *errors.UnsupportedValueError {
  186. return &errors.UnsupportedValueError{
  187. Value: reflect.ValueOf(v),
  188. Str: strconv.FormatFloat(v, 'g', -1, 64),
  189. }
  190. }
  191. func ErrMarshalerWithCode(code *Opcode, err error) *errors.MarshalerError {
  192. return &errors.MarshalerError{
  193. Type: runtime.RType2Type(code.Type),
  194. Err: err,
  195. }
  196. }
  197. type emptyInterface struct {
  198. typ *runtime.Type
  199. ptr unsafe.Pointer
  200. }
  201. type MapItem struct {
  202. Key []byte
  203. Value []byte
  204. }
  205. type Mapslice struct {
  206. Items []MapItem
  207. }
  208. func (m *Mapslice) Len() int {
  209. return len(m.Items)
  210. }
  211. func (m *Mapslice) Less(i, j int) bool {
  212. return bytes.Compare(m.Items[i].Key, m.Items[j].Key) < 0
  213. }
  214. func (m *Mapslice) Swap(i, j int) {
  215. m.Items[i], m.Items[j] = m.Items[j], m.Items[i]
  216. }
  217. //nolint:structcheck,unused
  218. type mapIter struct {
  219. key unsafe.Pointer
  220. elem unsafe.Pointer
  221. t unsafe.Pointer
  222. h unsafe.Pointer
  223. buckets unsafe.Pointer
  224. bptr unsafe.Pointer
  225. overflow unsafe.Pointer
  226. oldoverflow unsafe.Pointer
  227. startBucket uintptr
  228. offset uint8
  229. wrapped bool
  230. B uint8
  231. i uint8
  232. bucket uintptr
  233. checkBucket uintptr
  234. }
  235. type MapContext struct {
  236. Start int
  237. First int
  238. Idx int
  239. Slice *Mapslice
  240. Buf []byte
  241. Len int
  242. Iter mapIter
  243. }
  244. var mapContextPool = sync.Pool{
  245. New: func() interface{} {
  246. return &MapContext{
  247. Slice: &Mapslice{},
  248. }
  249. },
  250. }
  251. func NewMapContext(mapLen int, unorderedMap bool) *MapContext {
  252. ctx := mapContextPool.Get().(*MapContext)
  253. if !unorderedMap {
  254. if len(ctx.Slice.Items) < mapLen {
  255. ctx.Slice.Items = make([]MapItem, mapLen)
  256. } else {
  257. ctx.Slice.Items = ctx.Slice.Items[:mapLen]
  258. }
  259. }
  260. ctx.Buf = ctx.Buf[:0]
  261. ctx.Iter = mapIter{}
  262. ctx.Idx = 0
  263. ctx.Len = mapLen
  264. return ctx
  265. }
  266. func ReleaseMapContext(c *MapContext) {
  267. mapContextPool.Put(c)
  268. }
  269. //go:linkname MapIterInit runtime.mapiterinit
  270. //go:noescape
  271. func MapIterInit(mapType *runtime.Type, m unsafe.Pointer, it *mapIter)
  272. //go:linkname MapIterKey reflect.mapiterkey
  273. //go:noescape
  274. func MapIterKey(it *mapIter) unsafe.Pointer
  275. //go:linkname MapIterNext reflect.mapiternext
  276. //go:noescape
  277. func MapIterNext(it *mapIter)
  278. //go:linkname MapLen reflect.maplen
  279. //go:noescape
  280. func MapLen(m unsafe.Pointer) int
  281. func AppendByteSlice(_ *RuntimeContext, b []byte, src []byte) []byte {
  282. if src == nil {
  283. return append(b, `null`...)
  284. }
  285. encodedLen := base64.StdEncoding.EncodedLen(len(src))
  286. b = append(b, '"')
  287. pos := len(b)
  288. remainLen := cap(b[pos:])
  289. var buf []byte
  290. if remainLen > encodedLen {
  291. buf = b[pos : pos+encodedLen]
  292. } else {
  293. buf = make([]byte, encodedLen)
  294. }
  295. base64.StdEncoding.Encode(buf, src)
  296. return append(append(b, buf...), '"')
  297. }
  298. func AppendFloat32(_ *RuntimeContext, b []byte, v float32) []byte {
  299. f64 := float64(v)
  300. abs := math.Abs(f64)
  301. fmt := byte('f')
  302. // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
  303. if abs != 0 {
  304. f32 := float32(abs)
  305. if f32 < 1e-6 || f32 >= 1e21 {
  306. fmt = 'e'
  307. }
  308. }
  309. return strconv.AppendFloat(b, f64, fmt, -1, 32)
  310. }
  311. func AppendFloat64(_ *RuntimeContext, b []byte, v float64) []byte {
  312. abs := math.Abs(v)
  313. fmt := byte('f')
  314. // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
  315. if abs != 0 {
  316. if abs < 1e-6 || abs >= 1e21 {
  317. fmt = 'e'
  318. }
  319. }
  320. return strconv.AppendFloat(b, v, fmt, -1, 64)
  321. }
  322. func AppendBool(_ *RuntimeContext, b []byte, v bool) []byte {
  323. if v {
  324. return append(b, "true"...)
  325. }
  326. return append(b, "false"...)
  327. }
  328. var (
  329. floatTable = [256]bool{
  330. '0': true,
  331. '1': true,
  332. '2': true,
  333. '3': true,
  334. '4': true,
  335. '5': true,
  336. '6': true,
  337. '7': true,
  338. '8': true,
  339. '9': true,
  340. '.': true,
  341. 'e': true,
  342. 'E': true,
  343. '+': true,
  344. '-': true,
  345. }
  346. )
  347. func AppendNumber(_ *RuntimeContext, b []byte, n json.Number) ([]byte, error) {
  348. if len(n) == 0 {
  349. return append(b, '0'), nil
  350. }
  351. for i := 0; i < len(n); i++ {
  352. if !floatTable[n[i]] {
  353. return nil, fmt.Errorf("json: invalid number literal %q", n)
  354. }
  355. }
  356. b = append(b, n...)
  357. return b, nil
  358. }
  359. func AppendMarshalJSON(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) {
  360. rv := reflect.ValueOf(v) // convert by dynamic interface type
  361. if (code.Flags & AddrForMarshalerFlags) != 0 {
  362. if rv.CanAddr() {
  363. rv = rv.Addr()
  364. } else {
  365. newV := reflect.New(rv.Type())
  366. newV.Elem().Set(rv)
  367. rv = newV
  368. }
  369. }
  370. v = rv.Interface()
  371. var bb []byte
  372. if (code.Flags & MarshalerContextFlags) != 0 {
  373. marshaler, ok := v.(marshalerContext)
  374. if !ok {
  375. return AppendNull(ctx, b), nil
  376. }
  377. stdctx := ctx.Option.Context
  378. if ctx.Option.Flag&FieldQueryOption != 0 {
  379. stdctx = SetFieldQueryToContext(stdctx, code.FieldQuery)
  380. }
  381. b, err := marshaler.MarshalJSON(stdctx)
  382. if err != nil {
  383. return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
  384. }
  385. bb = b
  386. } else {
  387. marshaler, ok := v.(json.Marshaler)
  388. if !ok {
  389. return AppendNull(ctx, b), nil
  390. }
  391. b, err := marshaler.MarshalJSON()
  392. if err != nil {
  393. return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
  394. }
  395. bb = b
  396. }
  397. marshalBuf := ctx.MarshalBuf[:0]
  398. marshalBuf = append(append(marshalBuf, bb...), nul)
  399. compactedBuf, err := compact(b, marshalBuf, (ctx.Option.Flag&HTMLEscapeOption) != 0)
  400. if err != nil {
  401. return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
  402. }
  403. ctx.MarshalBuf = marshalBuf
  404. return compactedBuf, nil
  405. }
  406. func AppendMarshalJSONIndent(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) {
  407. rv := reflect.ValueOf(v) // convert by dynamic interface type
  408. if (code.Flags & AddrForMarshalerFlags) != 0 {
  409. if rv.CanAddr() {
  410. rv = rv.Addr()
  411. } else {
  412. newV := reflect.New(rv.Type())
  413. newV.Elem().Set(rv)
  414. rv = newV
  415. }
  416. }
  417. v = rv.Interface()
  418. var bb []byte
  419. if (code.Flags & MarshalerContextFlags) != 0 {
  420. marshaler, ok := v.(marshalerContext)
  421. if !ok {
  422. return AppendNull(ctx, b), nil
  423. }
  424. b, err := marshaler.MarshalJSON(ctx.Option.Context)
  425. if err != nil {
  426. return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
  427. }
  428. bb = b
  429. } else {
  430. marshaler, ok := v.(json.Marshaler)
  431. if !ok {
  432. return AppendNull(ctx, b), nil
  433. }
  434. b, err := marshaler.MarshalJSON()
  435. if err != nil {
  436. return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
  437. }
  438. bb = b
  439. }
  440. marshalBuf := ctx.MarshalBuf[:0]
  441. marshalBuf = append(append(marshalBuf, bb...), nul)
  442. indentedBuf, err := doIndent(
  443. b,
  444. marshalBuf,
  445. string(ctx.Prefix)+strings.Repeat(string(ctx.IndentStr), int(ctx.BaseIndent+code.Indent)),
  446. string(ctx.IndentStr),
  447. (ctx.Option.Flag&HTMLEscapeOption) != 0,
  448. )
  449. if err != nil {
  450. return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
  451. }
  452. ctx.MarshalBuf = marshalBuf
  453. return indentedBuf, nil
  454. }
  455. func AppendMarshalText(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) {
  456. rv := reflect.ValueOf(v) // convert by dynamic interface type
  457. if (code.Flags & AddrForMarshalerFlags) != 0 {
  458. if rv.CanAddr() {
  459. rv = rv.Addr()
  460. } else {
  461. newV := reflect.New(rv.Type())
  462. newV.Elem().Set(rv)
  463. rv = newV
  464. }
  465. }
  466. v = rv.Interface()
  467. marshaler, ok := v.(encoding.TextMarshaler)
  468. if !ok {
  469. return AppendNull(ctx, b), nil
  470. }
  471. bytes, err := marshaler.MarshalText()
  472. if err != nil {
  473. return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
  474. }
  475. return AppendString(ctx, b, *(*string)(unsafe.Pointer(&bytes))), nil
  476. }
  477. func AppendMarshalTextIndent(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) {
  478. rv := reflect.ValueOf(v) // convert by dynamic interface type
  479. if (code.Flags & AddrForMarshalerFlags) != 0 {
  480. if rv.CanAddr() {
  481. rv = rv.Addr()
  482. } else {
  483. newV := reflect.New(rv.Type())
  484. newV.Elem().Set(rv)
  485. rv = newV
  486. }
  487. }
  488. v = rv.Interface()
  489. marshaler, ok := v.(encoding.TextMarshaler)
  490. if !ok {
  491. return AppendNull(ctx, b), nil
  492. }
  493. bytes, err := marshaler.MarshalText()
  494. if err != nil {
  495. return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
  496. }
  497. return AppendString(ctx, b, *(*string)(unsafe.Pointer(&bytes))), nil
  498. }
  499. func AppendNull(_ *RuntimeContext, b []byte) []byte {
  500. return append(b, "null"...)
  501. }
  502. func AppendComma(_ *RuntimeContext, b []byte) []byte {
  503. return append(b, ',')
  504. }
  505. func AppendCommaIndent(_ *RuntimeContext, b []byte) []byte {
  506. return append(b, ',', '\n')
  507. }
  508. func AppendStructEnd(_ *RuntimeContext, b []byte) []byte {
  509. return append(b, '}', ',')
  510. }
  511. func AppendStructEndIndent(ctx *RuntimeContext, code *Opcode, b []byte) []byte {
  512. b = append(b, '\n')
  513. b = append(b, ctx.Prefix...)
  514. indentNum := ctx.BaseIndent + code.Indent - 1
  515. for i := uint32(0); i < indentNum; i++ {
  516. b = append(b, ctx.IndentStr...)
  517. }
  518. return append(b, '}', ',', '\n')
  519. }
  520. func AppendIndent(ctx *RuntimeContext, b []byte, indent uint32) []byte {
  521. b = append(b, ctx.Prefix...)
  522. indentNum := ctx.BaseIndent + indent
  523. for i := uint32(0); i < indentNum; i++ {
  524. b = append(b, ctx.IndentStr...)
  525. }
  526. return b
  527. }
  528. func IsNilForMarshaler(v interface{}) bool {
  529. rv := reflect.ValueOf(v)
  530. switch rv.Kind() {
  531. case reflect.Bool:
  532. return !rv.Bool()
  533. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  534. return rv.Int() == 0
  535. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  536. return rv.Uint() == 0
  537. case reflect.Float32, reflect.Float64:
  538. return math.Float64bits(rv.Float()) == 0
  539. case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Func:
  540. return rv.IsNil()
  541. case reflect.Slice:
  542. return rv.IsNil() || rv.Len() == 0
  543. case reflect.String:
  544. return rv.Len() == 0
  545. }
  546. return false
  547. }