config.go 9.9 KB

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