| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- package serial
- import (
- "bytes"
- "encoding/json"
- "io"
- "io/ioutil"
- "github.com/ghodss/yaml"
- "github.com/pelletier/go-toml"
- "github.com/xtls/xray-core/common/errors"
- "github.com/xtls/xray-core/core"
- "github.com/xtls/xray-core/infra/conf"
- json_reader "github.com/xtls/xray-core/infra/conf/json"
- )
- type offset struct {
- line int
- char int
- }
- func findOffset(b []byte, o int) *offset {
- if o >= len(b) || o < 0 {
- return nil
- }
- line := 1
- char := 0
- for i, x := range b {
- if i == o {
- break
- }
- if x == '\n' {
- line++
- char = 0
- } else {
- char++
- }
- }
- return &offset{line: line, char: char}
- }
- // DecodeJSONConfig reads from reader and decode the config into *conf.Config
- // syntax error could be detected.
- func DecodeJSONConfig(reader io.Reader) (*conf.Config, error) {
- jsonConfig := &conf.Config{}
- jsonContent := bytes.NewBuffer(make([]byte, 0, 10240))
- jsonReader := io.TeeReader(&json_reader.Reader{
- Reader: reader,
- }, jsonContent)
- decoder := json.NewDecoder(jsonReader)
- if err := decoder.Decode(jsonConfig); err != nil {
- var pos *offset
- cause := errors.Cause(err)
- switch tErr := cause.(type) {
- case *json.SyntaxError:
- pos = findOffset(jsonContent.Bytes(), int(tErr.Offset))
- case *json.UnmarshalTypeError:
- pos = findOffset(jsonContent.Bytes(), int(tErr.Offset))
- }
- if pos != nil {
- return nil, newError("failed to read config file at line ", pos.line, " char ", pos.char).Base(err)
- }
- return nil, newError("failed to read config file").Base(err)
- }
- return jsonConfig, nil
- }
- func LoadJSONConfig(reader io.Reader) (*core.Config, error) {
- jsonConfig, err := DecodeJSONConfig(reader)
- if err != nil {
- return nil, err
- }
- pbConfig, err := jsonConfig.Build()
- if err != nil {
- return nil, newError("failed to parse json config").Base(err)
- }
- return pbConfig, nil
- }
- // DecodeTOMLConfig reads from reader and decode the config into *conf.Config
- // using github.com/pelletier/go-toml and map to convert toml to json.
- func DecodeTOMLConfig(reader io.Reader) (*conf.Config, error) {
- tomlFile, err := ioutil.ReadAll(reader)
- if err != nil {
- return nil, newError("failed to read config file").Base(err)
- }
- configMap := make(map[string]interface{})
- if err := toml.Unmarshal(tomlFile, &configMap); err != nil {
- return nil, newError("failed to convert toml to map").Base(err)
- }
- jsonFile, err := json.Marshal(&configMap)
- if err != nil {
- return nil, newError("failed to convert map to json").Base(err)
- }
- return DecodeJSONConfig(bytes.NewReader(jsonFile))
- }
- func LoadTOMLConfig(reader io.Reader) (*core.Config, error) {
- tomlConfig, err := DecodeTOMLConfig(reader)
- if err != nil {
- return nil, err
- }
- pbConfig, err := tomlConfig.Build()
- if err != nil {
- return nil, newError("failed to parse toml config").Base(err)
- }
- return pbConfig, nil
- }
- // DecodeYAMLConfig reads from reader and decode the config into *conf.Config
- // using github.com/ghodss/yaml to convert yaml to json.
- func DecodeYAMLConfig(reader io.Reader) (*conf.Config, error) {
- yamlFile, err := ioutil.ReadAll(reader)
- if err != nil {
- return nil, newError("failed to read config file").Base(err)
- }
- jsonFile, err := yaml.YAMLToJSON(yamlFile)
- if err != nil {
- return nil, newError("failed to convert yaml to json").Base(err)
- }
- return DecodeJSONConfig(bytes.NewReader(jsonFile))
- }
- func LoadYAMLConfig(reader io.Reader) (*core.Config, error) {
- yamlConfig, err := DecodeYAMLConfig(reader)
- if err != nil {
- return nil, err
- }
- pbConfig, err := yamlConfig.Build()
- if err != nil {
- return nil, newError("failed to parse yaml config").Base(err)
- }
- return pbConfig, nil
- }
|