config.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. package jsoniter
  2. import (
  3. "encoding/json"
  4. "io"
  5. "reflect"
  6. "sync"
  7. "unsafe"
  8. "github.com/modern-go/concurrent"
  9. "github.com/modern-go/reflect2"
  10. )
  11. // limit maximum depth of nesting, as allowed by https://tools.ietf.org/html/rfc7159#section-9
  12. const defaultMaxDepth = 10000
  13. // Config customize how the API should behave.
  14. // The API is created from Config by Froze.
  15. type Config struct {
  16. IndentionStep int
  17. MarshalFloatWith6Digits bool
  18. EscapeHTML bool
  19. SortMapKeys bool
  20. UseNumber bool
  21. DisallowUnknownFields bool
  22. TagKey string
  23. OnlyTaggedField bool
  24. ValidateJsonRawMessage bool
  25. ObjectFieldMustBeSimpleString bool
  26. CaseSensitive bool
  27. MaxDepth int
  28. }
  29. // API the public interface of this package.
  30. // Primary Marshal and Unmarshal.
  31. type API interface {
  32. IteratorPool
  33. StreamPool
  34. MarshalToString(v interface{}) (string, error)
  35. Marshal(v interface{}) ([]byte, error)
  36. MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
  37. UnmarshalFromString(str string, v interface{}) error
  38. Unmarshal(data []byte, v interface{}) error
  39. Get(data []byte, path ...interface{}) Any
  40. NewEncoder(writer io.Writer) *Encoder
  41. NewDecoder(reader io.Reader) *Decoder
  42. Valid(data []byte) bool
  43. RegisterExtension(extension Extension)
  44. DecoderOf(typ reflect2.Type) ValDecoder
  45. EncoderOf(typ reflect2.Type) ValEncoder
  46. }
  47. // ConfigDefault the default API
  48. var ConfigDefault = Config{
  49. EscapeHTML: true,
  50. }.Froze()
  51. // ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior
  52. var ConfigCompatibleWithStandardLibrary = Config{
  53. EscapeHTML: true,
  54. SortMapKeys: true,
  55. ValidateJsonRawMessage: true,
  56. MaxDepth: -1, // encoding/json has no max depth (stack overflow at 2581101)
  57. }.Froze()
  58. // ConfigFastest marshals float with only 6 digits precision
  59. var ConfigFastest = Config{
  60. EscapeHTML: false,
  61. MarshalFloatWith6Digits: true, // will lose precession
  62. ObjectFieldMustBeSimpleString: true, // do not unescape object field
  63. }.Froze()
  64. type frozenConfig struct {
  65. configBeforeFrozen Config
  66. sortMapKeys bool
  67. indentionStep int
  68. objectFieldMustBeSimpleString bool
  69. onlyTaggedField bool
  70. disallowUnknownFields bool
  71. decoderCache *concurrent.Map
  72. encoderCache *concurrent.Map
  73. encoderExtension Extension
  74. decoderExtension Extension
  75. extraExtensions []Extension
  76. streamPool *sync.Pool
  77. iteratorPool *sync.Pool
  78. caseSensitive bool
  79. maxDepth int
  80. }
  81. func (cfg *frozenConfig) initCache() {
  82. cfg.decoderCache = concurrent.NewMap()
  83. cfg.encoderCache = concurrent.NewMap()
  84. }
  85. func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) {
  86. cfg.decoderCache.Store(cacheKey, decoder)
  87. }
  88. func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) {
  89. cfg.encoderCache.Store(cacheKey, encoder)
  90. }
  91. func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder {
  92. decoder, found := cfg.decoderCache.Load(cacheKey)
  93. if found {
  94. return decoder.(ValDecoder)
  95. }
  96. return nil
  97. }
  98. func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder {
  99. encoder, found := cfg.encoderCache.Load(cacheKey)
  100. if found {
  101. return encoder.(ValEncoder)
  102. }
  103. return nil
  104. }
  105. var cfgCache = concurrent.NewMap()
  106. func getFrozenConfigFromCache(cfg Config) *frozenConfig {
  107. obj, found := cfgCache.Load(cfg)
  108. if found {
  109. return obj.(*frozenConfig)
  110. }
  111. return nil
  112. }
  113. func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) {
  114. cfgCache.Store(cfg, frozenConfig)
  115. }
  116. // Froze forge API from config
  117. func (cfg Config) Froze() API {
  118. if cfg.MaxDepth == 0 {
  119. cfg.MaxDepth = defaultMaxDepth
  120. }
  121. api := &frozenConfig{
  122. sortMapKeys: cfg.SortMapKeys,
  123. indentionStep: cfg.IndentionStep,
  124. objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString,
  125. onlyTaggedField: cfg.OnlyTaggedField,
  126. disallowUnknownFields: cfg.DisallowUnknownFields,
  127. caseSensitive: cfg.CaseSensitive,
  128. maxDepth: cfg.MaxDepth,
  129. }
  130. api.streamPool = &sync.Pool{
  131. New: func() interface{} {
  132. return NewStream(api, nil, 512)
  133. },
  134. }
  135. api.iteratorPool = &sync.Pool{
  136. New: func() interface{} {
  137. return NewIterator(api)
  138. },
  139. }
  140. api.initCache()
  141. encoderExtension := EncoderExtension{}
  142. decoderExtension := DecoderExtension{}
  143. if cfg.MarshalFloatWith6Digits {
  144. api.marshalFloatWith6Digits(encoderExtension)
  145. }
  146. if cfg.EscapeHTML {
  147. api.escapeHTML(encoderExtension)
  148. }
  149. if cfg.UseNumber {
  150. api.useNumber(decoderExtension)
  151. }
  152. if cfg.ValidateJsonRawMessage {
  153. api.validateJsonRawMessage(encoderExtension)
  154. }
  155. api.encoderExtension = encoderExtension
  156. api.decoderExtension = decoderExtension
  157. api.configBeforeFrozen = cfg
  158. return api
  159. }
  160. func (cfg Config) frozeWithCacheReuse(extraExtensions []Extension) *frozenConfig {
  161. api := getFrozenConfigFromCache(cfg)
  162. if api != nil {
  163. return api
  164. }
  165. api = cfg.Froze().(*frozenConfig)
  166. for _, extension := range extraExtensions {
  167. api.RegisterExtension(extension)
  168. }
  169. addFrozenConfigToCache(cfg, api)
  170. return api
  171. }
  172. func (cfg *frozenConfig) validateJsonRawMessage(extension EncoderExtension) {
  173. encoder := &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) {
  174. rawMessage := *(*json.RawMessage)(ptr)
  175. iter := cfg.BorrowIterator([]byte(rawMessage))
  176. iter.Read()
  177. if iter.Error != nil {
  178. stream.WriteRaw("null")
  179. } else {
  180. cfg.ReturnIterator(iter)
  181. stream.WriteRaw(string(rawMessage))
  182. }
  183. }, func(ptr unsafe.Pointer) bool {
  184. return len(*((*json.RawMessage)(ptr))) == 0
  185. }}
  186. extension[reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()] = encoder
  187. extension[reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()] = encoder
  188. }
  189. func (cfg *frozenConfig) useNumber(extension DecoderExtension) {
  190. extension[reflect2.TypeOfPtr((*interface{})(nil)).Elem()] = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) {
  191. exitingValue := *((*interface{})(ptr))
  192. if exitingValue != nil && reflect.TypeOf(exitingValue).Kind() == reflect.Ptr {
  193. iter.ReadVal(exitingValue)
  194. return
  195. }
  196. if iter.WhatIsNext() == NumberValue {
  197. *((*interface{})(ptr)) = json.Number(iter.readNumberAsString())
  198. } else {
  199. *((*interface{})(ptr)) = iter.Read()
  200. }
  201. }}
  202. }
  203. func (cfg *frozenConfig) getTagKey() string {
  204. tagKey := cfg.configBeforeFrozen.TagKey
  205. if tagKey == "" {
  206. return "json"
  207. }
  208. return tagKey
  209. }
  210. func (cfg *frozenConfig) RegisterExtension(extension Extension) {
  211. cfg.extraExtensions = append(cfg.extraExtensions, extension)
  212. copied := cfg.configBeforeFrozen
  213. cfg.configBeforeFrozen = copied
  214. }
  215. type lossyFloat32Encoder struct {
  216. }
  217. func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  218. stream.WriteFloat32Lossy(*((*float32)(ptr)))
  219. }
  220. func (encoder *lossyFloat32Encoder) IsEmpty(ptr unsafe.Pointer) bool {
  221. return *((*float32)(ptr)) == 0
  222. }
  223. type lossyFloat64Encoder struct {
  224. }
  225. func (encoder *lossyFloat64Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  226. stream.WriteFloat64Lossy(*((*float64)(ptr)))
  227. }
  228. func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool {
  229. return *((*float64)(ptr)) == 0
  230. }
  231. // EnableLossyFloatMarshalling keeps 10**(-6) precision
  232. // for float variables for better performance.
  233. func (cfg *frozenConfig) marshalFloatWith6Digits(extension EncoderExtension) {
  234. // for better performance
  235. extension[reflect2.TypeOfPtr((*float32)(nil)).Elem()] = &lossyFloat32Encoder{}
  236. extension[reflect2.TypeOfPtr((*float64)(nil)).Elem()] = &lossyFloat64Encoder{}
  237. }
  238. type htmlEscapedStringEncoder struct {
  239. }
  240. func (encoder *htmlEscapedStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  241. str := *((*string)(ptr))
  242. stream.WriteStringWithHTMLEscaped(str)
  243. }
  244. func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  245. return *((*string)(ptr)) == ""
  246. }
  247. func (cfg *frozenConfig) escapeHTML(encoderExtension EncoderExtension) {
  248. encoderExtension[reflect2.TypeOfPtr((*string)(nil)).Elem()] = &htmlEscapedStringEncoder{}
  249. }
  250. func (cfg *frozenConfig) cleanDecoders() {
  251. typeDecoders = map[string]ValDecoder{}
  252. fieldDecoders = map[string]ValDecoder{}
  253. *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig))
  254. }
  255. func (cfg *frozenConfig) cleanEncoders() {
  256. typeEncoders = map[string]ValEncoder{}
  257. fieldEncoders = map[string]ValEncoder{}
  258. *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig))
  259. }
  260. func (cfg *frozenConfig) MarshalToString(v interface{}) (string, error) {
  261. stream := cfg.BorrowStream(nil)
  262. defer cfg.ReturnStream(stream)
  263. stream.WriteVal(v)
  264. if stream.Error != nil {
  265. return "", stream.Error
  266. }
  267. return string(stream.Buffer()), nil
  268. }
  269. func (cfg *frozenConfig) Marshal(v interface{}) ([]byte, error) {
  270. stream := cfg.BorrowStream(nil)
  271. defer cfg.ReturnStream(stream)
  272. stream.WriteVal(v)
  273. if stream.Error != nil {
  274. return nil, stream.Error
  275. }
  276. result := stream.Buffer()
  277. copied := make([]byte, len(result))
  278. copy(copied, result)
  279. return copied, nil
  280. }
  281. func (cfg *frozenConfig) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
  282. if prefix != "" {
  283. panic("prefix is not supported")
  284. }
  285. for _, r := range indent {
  286. if r != ' ' {
  287. panic("indent can only be space")
  288. }
  289. }
  290. newCfg := cfg.configBeforeFrozen
  291. newCfg.IndentionStep = len(indent)
  292. return newCfg.frozeWithCacheReuse(cfg.extraExtensions).Marshal(v)
  293. }
  294. func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error {
  295. data := []byte(str)
  296. iter := cfg.BorrowIterator(data)
  297. defer cfg.ReturnIterator(iter)
  298. iter.ReadVal(v)
  299. c := iter.nextToken()
  300. if c == 0 {
  301. if iter.Error == io.EOF {
  302. return nil
  303. }
  304. return iter.Error
  305. }
  306. iter.ReportError("Unmarshal", "there are bytes left after unmarshal")
  307. return iter.Error
  308. }
  309. func (cfg *frozenConfig) Get(data []byte, path ...interface{}) Any {
  310. iter := cfg.BorrowIterator(data)
  311. defer cfg.ReturnIterator(iter)
  312. return locatePath(iter, path)
  313. }
  314. func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error {
  315. iter := cfg.BorrowIterator(data)
  316. defer cfg.ReturnIterator(iter)
  317. iter.ReadVal(v)
  318. c := iter.nextToken()
  319. if c == 0 {
  320. if iter.Error == io.EOF {
  321. return nil
  322. }
  323. return iter.Error
  324. }
  325. iter.ReportError("Unmarshal", "there are bytes left after unmarshal")
  326. return iter.Error
  327. }
  328. func (cfg *frozenConfig) NewEncoder(writer io.Writer) *Encoder {
  329. stream := NewStream(cfg, writer, 512)
  330. return &Encoder{stream}
  331. }
  332. func (cfg *frozenConfig) NewDecoder(reader io.Reader) *Decoder {
  333. iter := Parse(cfg, reader, 512)
  334. return &Decoder{iter}
  335. }
  336. func (cfg *frozenConfig) Valid(data []byte) bool {
  337. iter := cfg.BorrowIterator(data)
  338. defer cfg.ReturnIterator(iter)
  339. iter.Skip()
  340. return iter.Error == nil
  341. }