object.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package badjson
  2. import (
  3. "bytes"
  4. "strings"
  5. "github.com/sagernet/sing-box/common/json"
  6. E "github.com/sagernet/sing/common/exceptions"
  7. "github.com/sagernet/sing/common/x/linkedhashmap"
  8. )
  9. type JSONObject struct {
  10. linkedhashmap.Map[string, any]
  11. }
  12. func (m JSONObject) MarshalJSON() ([]byte, error) {
  13. buffer := new(bytes.Buffer)
  14. buffer.WriteString("{")
  15. items := m.Entries()
  16. iLen := len(items)
  17. for i, entry := range items {
  18. keyContent, err := json.Marshal(entry.Key)
  19. if err != nil {
  20. return nil, err
  21. }
  22. buffer.WriteString(strings.TrimSpace(string(keyContent)))
  23. buffer.WriteString(": ")
  24. valueContent, err := json.Marshal(entry.Value)
  25. if err != nil {
  26. return nil, err
  27. }
  28. buffer.WriteString(strings.TrimSpace(string(valueContent)))
  29. if i < iLen-1 {
  30. buffer.WriteString(", ")
  31. }
  32. }
  33. buffer.WriteString("}")
  34. return buffer.Bytes(), nil
  35. }
  36. func (m *JSONObject) UnmarshalJSON(content []byte) error {
  37. decoder := json.NewDecoder(bytes.NewReader(content))
  38. m.Clear()
  39. objectStart, err := decoder.Token()
  40. if err != nil {
  41. return err
  42. } else if objectStart != json.Delim('{') {
  43. return E.New("expected json object start, but starts with ", objectStart)
  44. }
  45. err = m.decodeJSON(decoder)
  46. if err != nil {
  47. return E.Cause(err, "decode json object content")
  48. }
  49. objectEnd, err := decoder.Token()
  50. if err != nil {
  51. return err
  52. } else if objectEnd != json.Delim('}') {
  53. return E.New("expected json object end, but ends with ", objectEnd)
  54. }
  55. return nil
  56. }
  57. func (m *JSONObject) decodeJSON(decoder *json.Decoder) error {
  58. for decoder.More() {
  59. var entryKey string
  60. keyToken, err := decoder.Token()
  61. if err != nil {
  62. return err
  63. }
  64. entryKey = keyToken.(string)
  65. var entryValue any
  66. entryValue, err = decodeJSON(decoder)
  67. if err != nil {
  68. return E.Cause(err, "decode value for ", entryKey)
  69. }
  70. m.Put(entryKey, entryValue)
  71. }
  72. return nil
  73. }