loader.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package serial
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "io"
  6. "v2ray.com/core"
  7. "v2ray.com/core/common/errors"
  8. "v2ray.com/core/infra/conf"
  9. json_reader "v2ray.com/core/infra/conf/json"
  10. )
  11. type offset struct {
  12. line int
  13. char int
  14. }
  15. func findOffset(b []byte, o int) *offset {
  16. if o >= len(b) || o < 0 {
  17. return nil
  18. }
  19. line := 1
  20. char := 0
  21. for i, x := range b {
  22. if i == o {
  23. break
  24. }
  25. if x == '\n' {
  26. line++
  27. char = 0
  28. } else {
  29. char++
  30. }
  31. }
  32. return &offset{line: line, char: char}
  33. }
  34. func LoadJSONConfig(reader io.Reader) (*core.Config, error) {
  35. jsonConfig := &conf.Config{}
  36. jsonContent := bytes.NewBuffer(make([]byte, 0, 10240))
  37. jsonReader := io.TeeReader(&json_reader.Reader{
  38. Reader: reader,
  39. }, jsonContent)
  40. decoder := json.NewDecoder(jsonReader)
  41. if err := decoder.Decode(jsonConfig); err != nil {
  42. var pos *offset
  43. cause := errors.Cause(err)
  44. switch tErr := cause.(type) {
  45. case *json.SyntaxError:
  46. pos = findOffset(jsonContent.Bytes(), int(tErr.Offset))
  47. case *json.UnmarshalTypeError:
  48. pos = findOffset(jsonContent.Bytes(), int(tErr.Offset))
  49. }
  50. if pos != nil {
  51. return nil, newError("failed to read config file at line ", pos.line, " char ", pos.char).Base(err)
  52. }
  53. return nil, newError("failed to read config file").Base(err)
  54. }
  55. pbConfig, err := jsonConfig.Build()
  56. if err != nil {
  57. return nil, newError("failed to parse json config").Base(err)
  58. }
  59. return pbConfig, nil
  60. }