sonic.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. //go:build (amd64 && go1.17 && !go1.25) || (arm64 && go1.20 && !go1.25)
  2. // +build amd64,go1.17,!go1.25 arm64,go1.20,!go1.25
  3. /*
  4. * Copyright 2021 ByteDance Inc.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. //go:generate make
  19. package sonic
  20. import (
  21. `io`
  22. `reflect`
  23. `github.com/bytedance/sonic/decoder`
  24. `github.com/bytedance/sonic/encoder`
  25. `github.com/bytedance/sonic/option`
  26. `github.com/bytedance/sonic/internal/rt`
  27. )
  28. const apiKind = UseSonicJSON
  29. type frozenConfig struct {
  30. Config
  31. encoderOpts encoder.Options
  32. decoderOpts decoder.Options
  33. }
  34. // Froze convert the Config to API
  35. func (cfg Config) Froze() API {
  36. api := &frozenConfig{Config: cfg}
  37. // configure encoder options:
  38. if cfg.EscapeHTML {
  39. api.encoderOpts |= encoder.EscapeHTML
  40. }
  41. if cfg.SortMapKeys {
  42. api.encoderOpts |= encoder.SortMapKeys
  43. }
  44. if cfg.CompactMarshaler {
  45. api.encoderOpts |= encoder.CompactMarshaler
  46. }
  47. if cfg.NoQuoteTextMarshaler {
  48. api.encoderOpts |= encoder.NoQuoteTextMarshaler
  49. }
  50. if cfg.NoNullSliceOrMap {
  51. api.encoderOpts |= encoder.NoNullSliceOrMap
  52. }
  53. if cfg.ValidateString {
  54. api.encoderOpts |= encoder.ValidateString
  55. }
  56. if cfg.NoValidateJSONMarshaler {
  57. api.encoderOpts |= encoder.NoValidateJSONMarshaler
  58. }
  59. if cfg.NoEncoderNewline {
  60. api.encoderOpts |= encoder.NoEncoderNewline
  61. }
  62. if cfg.EncodeNullForInfOrNan {
  63. api.encoderOpts |= encoder.EncodeNullForInfOrNan
  64. }
  65. // configure decoder options:
  66. if cfg.NoValidateJSONSkip {
  67. api.decoderOpts |= decoder.OptionNoValidateJSON
  68. }
  69. if cfg.UseInt64 {
  70. api.decoderOpts |= decoder.OptionUseInt64
  71. }
  72. if cfg.UseNumber {
  73. api.decoderOpts |= decoder.OptionUseNumber
  74. }
  75. if cfg.DisallowUnknownFields {
  76. api.decoderOpts |= decoder.OptionDisableUnknown
  77. }
  78. if cfg.CopyString {
  79. api.decoderOpts |= decoder.OptionCopyString
  80. }
  81. if cfg.ValidateString {
  82. api.decoderOpts |= decoder.OptionValidateString
  83. }
  84. return api
  85. }
  86. // Marshal is implemented by sonic
  87. func (cfg frozenConfig) Marshal(val interface{}) ([]byte, error) {
  88. return encoder.Encode(val, cfg.encoderOpts)
  89. }
  90. // MarshalToString is implemented by sonic
  91. func (cfg frozenConfig) MarshalToString(val interface{}) (string, error) {
  92. buf, err := encoder.Encode(val, cfg.encoderOpts)
  93. return rt.Mem2Str(buf), err
  94. }
  95. // MarshalIndent is implemented by sonic
  96. func (cfg frozenConfig) MarshalIndent(val interface{}, prefix, indent string) ([]byte, error) {
  97. return encoder.EncodeIndented(val, prefix, indent, cfg.encoderOpts)
  98. }
  99. // UnmarshalFromString is implemented by sonic
  100. func (cfg frozenConfig) UnmarshalFromString(buf string, val interface{}) error {
  101. dec := decoder.NewDecoder(buf)
  102. dec.SetOptions(cfg.decoderOpts)
  103. err := dec.Decode(val)
  104. /* check for errors */
  105. if err != nil {
  106. return err
  107. }
  108. return dec.CheckTrailings()
  109. }
  110. // Unmarshal is implemented by sonic
  111. func (cfg frozenConfig) Unmarshal(buf []byte, val interface{}) error {
  112. return cfg.UnmarshalFromString(string(buf), val)
  113. }
  114. // NewEncoder is implemented by sonic
  115. func (cfg frozenConfig) NewEncoder(writer io.Writer) Encoder {
  116. enc := encoder.NewStreamEncoder(writer)
  117. enc.Opts = cfg.encoderOpts
  118. return enc
  119. }
  120. // NewDecoder is implemented by sonic
  121. func (cfg frozenConfig) NewDecoder(reader io.Reader) Decoder {
  122. dec := decoder.NewStreamDecoder(reader)
  123. dec.SetOptions(cfg.decoderOpts)
  124. return dec
  125. }
  126. // Valid is implemented by sonic
  127. func (cfg frozenConfig) Valid(data []byte) bool {
  128. ok, _ := encoder.Valid(data)
  129. return ok
  130. }
  131. // Pretouch compiles vt ahead-of-time to avoid JIT compilation on-the-fly, in
  132. // order to reduce the first-hit latency.
  133. //
  134. // Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is
  135. // a compile option to set the depth of recursive compile for the nested struct type.
  136. func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {
  137. if err := encoder.Pretouch(vt, opts...); err != nil {
  138. return err
  139. }
  140. if err := decoder.Pretouch(vt, opts...); err != nil {
  141. return err
  142. }
  143. // to pretouch the corresponding pointer type as well
  144. if vt.Kind() == reflect.Ptr {
  145. vt = vt.Elem()
  146. } else {
  147. vt = reflect.PtrTo(vt)
  148. }
  149. if err := encoder.Pretouch(vt, opts...); err != nil {
  150. return err
  151. }
  152. if err := decoder.Pretouch(vt, opts...); err != nil {
  153. return err
  154. }
  155. return nil
  156. }