config.go 9.7 KB

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