Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

json.go 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package json
  4. // Allow "encoding/json" import.
  5. import (
  6. "bytes"
  7. "encoding/binary"
  8. "encoding/json" //nolint:depguard
  9. "io"
  10. jsoniter "github.com/json-iterator/go"
  11. )
  12. // Encoder represents an encoder for json
  13. type Encoder interface {
  14. Encode(v interface{}) error
  15. }
  16. // Decoder represents a decoder for json
  17. type Decoder interface {
  18. Decode(v interface{}) error
  19. }
  20. // Interface represents an interface to handle json data
  21. type Interface interface {
  22. Marshal(v interface{}) ([]byte, error)
  23. Unmarshal(data []byte, v interface{}) error
  24. NewEncoder(writer io.Writer) Encoder
  25. NewDecoder(reader io.Reader) Decoder
  26. Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error
  27. }
  28. var (
  29. // DefaultJSONHandler default json handler
  30. DefaultJSONHandler Interface = JSONiter{jsoniter.ConfigCompatibleWithStandardLibrary}
  31. _ Interface = StdJSON{}
  32. _ Interface = JSONiter{}
  33. )
  34. // StdJSON implements Interface via encoding/json
  35. type StdJSON struct{}
  36. // Marshal implements Interface
  37. func (StdJSON) Marshal(v interface{}) ([]byte, error) {
  38. return json.Marshal(v)
  39. }
  40. // Unmarshal implements Interface
  41. func (StdJSON) Unmarshal(data []byte, v interface{}) error {
  42. return json.Unmarshal(data, v)
  43. }
  44. // NewEncoder implements Interface
  45. func (StdJSON) NewEncoder(writer io.Writer) Encoder {
  46. return json.NewEncoder(writer)
  47. }
  48. // NewDecoder implements Interface
  49. func (StdJSON) NewDecoder(reader io.Reader) Decoder {
  50. return json.NewDecoder(reader)
  51. }
  52. // Indent implements Interface
  53. func (StdJSON) Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
  54. return json.Indent(dst, src, prefix, indent)
  55. }
  56. // JSONiter implements Interface via jsoniter
  57. type JSONiter struct {
  58. jsoniter.API
  59. }
  60. // Marshal implements Interface
  61. func (j JSONiter) Marshal(v interface{}) ([]byte, error) {
  62. return j.API.Marshal(v)
  63. }
  64. // Unmarshal implements Interface
  65. func (j JSONiter) Unmarshal(data []byte, v interface{}) error {
  66. return j.API.Unmarshal(data, v)
  67. }
  68. // NewEncoder implements Interface
  69. func (j JSONiter) NewEncoder(writer io.Writer) Encoder {
  70. return j.API.NewEncoder(writer)
  71. }
  72. // NewDecoder implements Interface
  73. func (j JSONiter) NewDecoder(reader io.Reader) Decoder {
  74. return j.API.NewDecoder(reader)
  75. }
  76. // Indent implements Interface, since jsoniter don't support Indent, just use encoding/json's
  77. func (j JSONiter) Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
  78. return json.Indent(dst, src, prefix, indent)
  79. }
  80. // Marshal converts object as bytes
  81. func Marshal(v interface{}) ([]byte, error) {
  82. return DefaultJSONHandler.Marshal(v)
  83. }
  84. // Unmarshal decodes object from bytes
  85. func Unmarshal(data []byte, v interface{}) error {
  86. return DefaultJSONHandler.Unmarshal(data, v)
  87. }
  88. // NewEncoder creates an encoder to write objects to writer
  89. func NewEncoder(writer io.Writer) Encoder {
  90. return DefaultJSONHandler.NewEncoder(writer)
  91. }
  92. // NewDecoder creates a decoder to read objects from reader
  93. func NewDecoder(reader io.Reader) Decoder {
  94. return DefaultJSONHandler.NewDecoder(reader)
  95. }
  96. // Indent appends to dst an indented form of the JSON-encoded src.
  97. func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
  98. return DefaultJSONHandler.Indent(dst, src, prefix, indent)
  99. }
  100. // MarshalIndent copied from encoding/json
  101. func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
  102. b, err := Marshal(v)
  103. if err != nil {
  104. return nil, err
  105. }
  106. var buf bytes.Buffer
  107. err = Indent(&buf, b, prefix, indent)
  108. if err != nil {
  109. return nil, err
  110. }
  111. return buf.Bytes(), nil
  112. }
  113. // Valid proxy to json.Valid
  114. func Valid(data []byte) bool {
  115. return json.Valid(data)
  116. }
  117. // UnmarshalHandleDoubleEncode - due to a bug in xorm (see https://gitea.com/xorm/xorm/pulls/1957) - it's
  118. // possible that a Blob may be double encoded or gain an unwanted prefix of 0xff 0xfe.
  119. func UnmarshalHandleDoubleEncode(bs []byte, v interface{}) error {
  120. err := json.Unmarshal(bs, v)
  121. if err != nil {
  122. ok := true
  123. rs := []byte{}
  124. temp := make([]byte, 2)
  125. for _, rn := range string(bs) {
  126. if rn > 0xffff {
  127. ok = false
  128. break
  129. }
  130. binary.LittleEndian.PutUint16(temp, uint16(rn))
  131. rs = append(rs, temp...)
  132. }
  133. if ok {
  134. if len(rs) > 1 && rs[0] == 0xff && rs[1] == 0xfe {
  135. rs = rs[2:]
  136. }
  137. err = json.Unmarshal(rs, v)
  138. }
  139. }
  140. if err != nil && len(bs) > 2 && bs[0] == 0xff && bs[1] == 0xfe {
  141. err = json.Unmarshal(bs[2:], v)
  142. }
  143. return err
  144. }