164 lines
3.2 KiB
Go
164 lines
3.2 KiB
Go
package parser
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
type ClientConfig struct {
|
|
Types map[int]ClientValue
|
|
TypeName2Index map[string]int
|
|
Data map[string]map[int]string
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
type ClientValue struct {
|
|
Desc string
|
|
Type string
|
|
Name string
|
|
}
|
|
|
|
func NewClientConfig() *ClientConfig {
|
|
return &ClientConfig{
|
|
Types: make(map[int]ClientValue),
|
|
Data: make(map[string]map[int]string),
|
|
TypeName2Index: make(map[string]int),
|
|
mu: sync.RWMutex{},
|
|
}
|
|
}
|
|
|
|
func NewClientConfigWithFile(filename string) (*ClientConfig, error) {
|
|
c := NewClientConfig()
|
|
return c, c.LoadFile(filename)
|
|
}
|
|
|
|
func (c *ClientConfig) LoadFile(filename string) error {
|
|
file, err := os.Open(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
return c.loadByReader(bufio.NewReader(file))
|
|
}
|
|
|
|
func (c *ClientConfig) LoadByReader(reader io.Reader) error {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
return c.loadByReader(reader)
|
|
}
|
|
|
|
func (c *ClientConfig) loadByReader(reader io.Reader) error {
|
|
// 创建缓存读取 分隔符设置成 回车
|
|
scan := bufio.NewScanner(reader)
|
|
scan.Split(bufio.ScanLines)
|
|
|
|
var line int
|
|
var types []string
|
|
var desc []string
|
|
|
|
for scan.Scan() {
|
|
line++
|
|
|
|
lineContent := strings.TrimSpace(scan.Text())
|
|
if len(lineContent) == 0 {
|
|
continue
|
|
}
|
|
|
|
// 去除注释
|
|
split := strings.Split(lineContent, "//")
|
|
if len(split) > 1 {
|
|
lineContent = split[0]
|
|
}
|
|
|
|
// 类型
|
|
if line == 1 {
|
|
types = strings.Split(lineContent, "\t")
|
|
continue
|
|
}
|
|
|
|
// 备注
|
|
if line == 2 {
|
|
desc = strings.Split(lineContent, "\t")
|
|
continue
|
|
}
|
|
|
|
// key
|
|
if line == 3 {
|
|
for i, t := range strings.Split(lineContent, "\t") {
|
|
if len(types) < i {
|
|
return fmt.Errorf("line %d: invalid type", line)
|
|
}
|
|
|
|
if len(desc) < i {
|
|
return fmt.Errorf("line %d: invalid desc", line)
|
|
}
|
|
|
|
c.Types[i] = ClientValue{
|
|
Desc: desc[i],
|
|
Type: types[i],
|
|
Name: t,
|
|
}
|
|
c.TypeName2Index[t] = i
|
|
}
|
|
|
|
continue
|
|
}
|
|
var lineData = make(map[int]string)
|
|
var lineKey string
|
|
for i1, v1 := range strings.Split(lineContent, "\t") {
|
|
if i1 == 0 {
|
|
lineKey = strings.TrimSpace(v1)
|
|
}
|
|
lineData[i1] = strings.TrimSpace(v1)
|
|
}
|
|
if len(lineData) == 0 {
|
|
continue
|
|
}
|
|
c.Data[lineKey] = lineData
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Value 读取单个
|
|
func (c *ClientConfig) Value(key string, objKey string) (ClientValue, string, error) {
|
|
c.mu.RLock()
|
|
defer c.mu.RUnlock()
|
|
|
|
l, is := c.Data[key]
|
|
if !is {
|
|
return ClientValue{}, "", fmt.Errorf("key %s not found", key)
|
|
}
|
|
index, is2 := c.TypeName2Index[objKey]
|
|
if !is2 {
|
|
return ClientValue{}, "", fmt.Errorf("objKey %s not found", objKey)
|
|
}
|
|
return c.Types[index], l[index], nil
|
|
}
|
|
|
|
// ValueByLine 读取
|
|
func (c *ClientConfig) ValueByLine(line map[int]string, key string) (ClientValue, string, error) {
|
|
c.mu.RLock()
|
|
defer c.mu.RUnlock()
|
|
|
|
index, is2 := c.TypeName2Index[key]
|
|
if !is2 {
|
|
return ClientValue{}, "", fmt.Errorf("objKey %s not found", key)
|
|
}
|
|
return c.Types[index], line[index], nil
|
|
}
|
|
|
|
// LineByKey 通过Key获取一行
|
|
func (c *ClientConfig) LineByKey(key string) map[int]string {
|
|
c.mu.RLock()
|
|
defer c.mu.RUnlock()
|
|
|
|
return c.Data[key]
|
|
}
|