config.go 10 KB

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