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] }