api.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. //go:build (amd64 && go1.17 && !go1.25) || (arm64 && go1.20 && !go1.25)
  2. // +build amd64,go1.17,!go1.25 arm64,go1.20,!go1.25
  3. /*
  4. * Copyright 2022 ByteDance Inc.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package ast
  19. import (
  20. `runtime`
  21. `unsafe`
  22. `github.com/bytedance/sonic/encoder`
  23. `github.com/bytedance/sonic/internal/native`
  24. `github.com/bytedance/sonic/internal/native/types`
  25. `github.com/bytedance/sonic/internal/rt`
  26. uq `github.com/bytedance/sonic/unquote`
  27. `github.com/bytedance/sonic/utf8`
  28. )
  29. var typeByte = rt.UnpackEface(byte(0)).Type
  30. //go:nocheckptr
  31. func quote(buf *[]byte, val string) {
  32. *buf = append(*buf, '"')
  33. if len(val) == 0 {
  34. *buf = append(*buf, '"')
  35. return
  36. }
  37. sp := rt.IndexChar(val, 0)
  38. nb := len(val)
  39. b := (*rt.GoSlice)(unsafe.Pointer(buf))
  40. // input buffer
  41. for nb > 0 {
  42. // output buffer
  43. dp := unsafe.Pointer(uintptr(b.Ptr) + uintptr(b.Len))
  44. dn := b.Cap - b.Len
  45. // call native.Quote, dn is byte count it outputs
  46. ret := native.Quote(sp, nb, dp, &dn, 0)
  47. // update *buf length
  48. b.Len += dn
  49. // no need more output
  50. if ret >= 0 {
  51. break
  52. }
  53. // double buf size
  54. *b = rt.GrowSlice(typeByte, *b, b.Cap*2)
  55. // ret is the complement of consumed input
  56. ret = ^ret
  57. // update input buffer
  58. nb -= ret
  59. sp = unsafe.Pointer(uintptr(sp) + uintptr(ret))
  60. }
  61. runtime.KeepAlive(buf)
  62. runtime.KeepAlive(sp)
  63. *buf = append(*buf, '"')
  64. }
  65. func unquote(src string) (string, types.ParsingError) {
  66. return uq.String(src)
  67. }
  68. func (self *Parser) decodeValue() (val types.JsonState) {
  69. sv := (*rt.GoString)(unsafe.Pointer(&self.s))
  70. flag := types.F_USE_NUMBER
  71. if self.dbuf != nil {
  72. flag = 0
  73. val.Dbuf = self.dbuf
  74. val.Dcap = types.MaxDigitNums
  75. }
  76. self.p = native.Value(sv.Ptr, sv.Len, self.p, &val, uint64(flag))
  77. return
  78. }
  79. func (self *Parser) skip() (int, types.ParsingError) {
  80. fsm := types.NewStateMachine()
  81. start := native.SkipOne(&self.s, &self.p, fsm, 0)
  82. types.FreeStateMachine(fsm)
  83. if start < 0 {
  84. return self.p, types.ParsingError(-start)
  85. }
  86. return start, 0
  87. }
  88. func (self *Node) encodeInterface(buf *[]byte) error {
  89. //WARN: NOT compatible with json.Encoder
  90. return encoder.EncodeInto(buf, self.packAny(), encoder.NoEncoderNewline)
  91. }
  92. func (self *Parser) skipFast() (int, types.ParsingError) {
  93. start := native.SkipOneFast(&self.s, &self.p)
  94. if start < 0 {
  95. return self.p, types.ParsingError(-start)
  96. }
  97. return start, 0
  98. }
  99. func (self *Parser) getByPath(validate bool, path ...interface{}) (int, types.ParsingError) {
  100. var fsm *types.StateMachine
  101. if validate {
  102. fsm = types.NewStateMachine()
  103. }
  104. start := native.GetByPath(&self.s, &self.p, &path, fsm)
  105. if validate {
  106. types.FreeStateMachine(fsm)
  107. }
  108. runtime.KeepAlive(path)
  109. if start < 0 {
  110. return self.p, types.ParsingError(-start)
  111. }
  112. return start, 0
  113. }
  114. func validate_utf8(str string) bool {
  115. return utf8.ValidateString(str)
  116. }