config.go 10 KB

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