2021-02-21 10:02:42 -05:00
|
|
|
package mergers
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
core "github.com/v2fly/v2ray-core/v4"
|
|
|
|
"github.com/v2fly/v2ray-core/v4/common/cmdarg"
|
|
|
|
)
|
|
|
|
|
|
|
|
// MergeAs load input and merge as specified format into m
|
|
|
|
func MergeAs(formatName string, input interface{}, m map[string]interface{}) error {
|
2021-03-10 16:03:26 -05:00
|
|
|
f, found := mergersByName[formatName]
|
2021-02-21 10:02:42 -05:00
|
|
|
if !found {
|
2021-03-10 16:03:26 -05:00
|
|
|
return newError("format merger not found for: ", formatName)
|
2021-02-21 10:02:42 -05:00
|
|
|
}
|
2021-03-10 16:03:26 -05:00
|
|
|
return f.Merge(input, m)
|
2021-02-21 10:02:42 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Merge loads inputs and merges them into m
|
2021-03-10 16:03:26 -05:00
|
|
|
// it detects extension for merger selecting, or try all mergers
|
2021-02-21 10:02:42 -05:00
|
|
|
// if no extension found
|
|
|
|
func Merge(input interface{}, m map[string]interface{}) error {
|
|
|
|
switch v := input.(type) {
|
|
|
|
case string:
|
|
|
|
err := mergeSingleFile(v, m)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
case []string:
|
|
|
|
for _, file := range v {
|
|
|
|
err := mergeSingleFile(file, m)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case cmdarg.Arg:
|
|
|
|
for _, file := range v {
|
|
|
|
err := mergeSingleFile(file, m)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case []byte:
|
|
|
|
err := mergeSingleFile(v, m)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
case io.Reader:
|
2021-03-10 16:03:26 -05:00
|
|
|
// read to []byte incase it tries different mergers
|
2021-02-21 10:02:42 -05:00
|
|
|
bs, err := ioutil.ReadAll(v)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
err = mergeSingleFile(bs, m)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return newError("unknow merge input type")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func mergeSingleFile(input interface{}, m map[string]interface{}) error {
|
|
|
|
if file, ok := input.(string); ok {
|
|
|
|
ext := getExtension(file)
|
|
|
|
if ext != "" {
|
|
|
|
lext := strings.ToLower(ext)
|
2021-03-10 16:03:26 -05:00
|
|
|
f, found := mergersByExt[lext]
|
2021-02-21 10:02:42 -05:00
|
|
|
if !found {
|
|
|
|
return newError("unmergeable format extension: ", ext)
|
|
|
|
}
|
2021-03-10 16:03:26 -05:00
|
|
|
return f.Merge(file, m)
|
2021-02-21 10:02:42 -05:00
|
|
|
}
|
|
|
|
}
|
2021-03-10 16:03:26 -05:00
|
|
|
// no extension, try all mergers
|
|
|
|
for _, f := range mergersByName {
|
2021-02-21 10:02:42 -05:00
|
|
|
if f.Name == core.FormatAuto {
|
|
|
|
continue
|
|
|
|
}
|
2021-03-10 16:03:26 -05:00
|
|
|
err := f.Merge(input, m)
|
2021-02-21 10:02:42 -05:00
|
|
|
if err == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
2021-03-10 16:03:26 -05:00
|
|
|
return newError("tried all mergers but failed for: ", input).AtWarning()
|
2021-02-21 10:02:42 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func getExtension(filename string) string {
|
|
|
|
ext := filepath.Ext(filename)
|
|
|
|
return strings.ToLower(ext)
|
|
|
|
}
|