loader.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. // DecodeJSONConfig reads from reader and decode the config into *conf.Config
  35. // syntax error could be detected.
  36. func DecodeJSONConfig(reader io.Reader) (*conf.Config, error) {
  37. jsonConfig := &conf.Config{}
  38. jsonContent := bytes.NewBuffer(make([]byte, 0, 10240))
  39. jsonReader := io.TeeReader(&json_reader.Reader{
  40. Reader: reader,
  41. }, jsonContent)
  42. decoder := json.NewDecoder(jsonReader)
  43. if err := decoder.Decode(jsonConfig); err != nil {
  44. var pos *offset
  45. cause := errors.Cause(err)
  46. switch tErr := cause.(type) {
  47. case *json.SyntaxError:
  48. pos = findOffset(jsonContent.Bytes(), int(tErr.Offset))
  49. case *json.UnmarshalTypeError:
  50. pos = findOffset(jsonContent.Bytes(), int(tErr.Offset))
  51. }
  52. if pos != nil {
  53. return nil, newError("failed to read config file at line ", pos.line, " char ", pos.char).Base(err)
  54. }
  55. return nil, newError("failed to read config file").Base(err)
  56. }
  57. return jsonConfig, nil
  58. }
  59. func LoadJSONConfig(reader io.Reader) (*core.Config, error) {
  60. jsonConfig, err := DecodeJSONConfig(reader)
  61. if err != nil {
  62. return nil, err
  63. }
  64. pbConfig, err := jsonConfig.Build()
  65. if err != nil {
  66. return nil, newError("failed to parse json config").Base(err)
  67. }
  68. return pbConfig, nil
  69. }