config.go 9.9 KB

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