compat.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // +build !amd64 !go1.16 go1.22
  2. /*
  3. * Copyright 2021 ByteDance Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package sonic
  18. import (
  19. `bytes`
  20. `encoding/json`
  21. `io`
  22. `reflect`
  23. `github.com/bytedance/sonic/option`
  24. )
  25. type frozenConfig struct {
  26. Config
  27. }
  28. // Froze convert the Config to API
  29. func (cfg Config) Froze() API {
  30. api := &frozenConfig{Config: cfg}
  31. return api
  32. }
  33. func (cfg frozenConfig) marshalOptions(val interface{}, prefix, indent string) ([]byte, error) {
  34. w := bytes.NewBuffer([]byte{})
  35. enc := json.NewEncoder(w)
  36. enc.SetEscapeHTML(cfg.EscapeHTML)
  37. enc.SetIndent(prefix, indent)
  38. err := enc.Encode(val)
  39. out := w.Bytes()
  40. // json.Encoder always appends '\n' after encoding,
  41. // which is not same with json.Marshal()
  42. if len(out) > 0 && out[len(out)-1] == '\n' {
  43. out = out[:len(out)-1]
  44. }
  45. return out, err
  46. }
  47. // Marshal is implemented by sonic
  48. func (cfg frozenConfig) Marshal(val interface{}) ([]byte, error) {
  49. if !cfg.EscapeHTML {
  50. return cfg.marshalOptions(val, "", "")
  51. }
  52. return json.Marshal(val)
  53. }
  54. // MarshalToString is implemented by sonic
  55. func (cfg frozenConfig) MarshalToString(val interface{}) (string, error) {
  56. out, err := cfg.Marshal(val)
  57. return string(out), err
  58. }
  59. // MarshalIndent is implemented by sonic
  60. func (cfg frozenConfig) MarshalIndent(val interface{}, prefix, indent string) ([]byte, error) {
  61. if !cfg.EscapeHTML {
  62. return cfg.marshalOptions(val, prefix, indent)
  63. }
  64. return json.MarshalIndent(val, prefix, indent)
  65. }
  66. // UnmarshalFromString is implemented by sonic
  67. func (cfg frozenConfig) UnmarshalFromString(buf string, val interface{}) error {
  68. r := bytes.NewBufferString(buf)
  69. dec := json.NewDecoder(r)
  70. if cfg.UseNumber {
  71. dec.UseNumber()
  72. }
  73. if cfg.DisallowUnknownFields {
  74. dec.DisallowUnknownFields()
  75. }
  76. return dec.Decode(val)
  77. }
  78. // Unmarshal is implemented by sonic
  79. func (cfg frozenConfig) Unmarshal(buf []byte, val interface{}) error {
  80. return cfg.UnmarshalFromString(string(buf), val)
  81. }
  82. // NewEncoder is implemented by sonic
  83. func (cfg frozenConfig) NewEncoder(writer io.Writer) Encoder {
  84. enc := json.NewEncoder(writer)
  85. if !cfg.EscapeHTML {
  86. enc.SetEscapeHTML(cfg.EscapeHTML)
  87. }
  88. return enc
  89. }
  90. // NewDecoder is implemented by sonic
  91. func (cfg frozenConfig) NewDecoder(reader io.Reader) Decoder {
  92. dec := json.NewDecoder(reader)
  93. if cfg.UseNumber {
  94. dec.UseNumber()
  95. }
  96. if cfg.DisallowUnknownFields {
  97. dec.DisallowUnknownFields()
  98. }
  99. return dec
  100. }
  101. // Valid is implemented by sonic
  102. func (cfg frozenConfig) Valid(data []byte) bool {
  103. return json.Valid(data)
  104. }
  105. // Pretouch compiles vt ahead-of-time to avoid JIT compilation on-the-fly, in
  106. // order to reduce the first-hit latency at **amd64** Arch.
  107. // Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is
  108. // a compile option to set the depth of recursive compile for the nested struct type.
  109. // * This is the none implement for !amd64.
  110. // It will be useful for someone who develop with !amd64 arch,like Mac M1.
  111. func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {
  112. return nil
  113. }