From ff45eecd692a072e2113a83c79d0370c7516b531 Mon Sep 17 00:00:00 2001 From: ren yuze Date: Wed, 11 Sep 2019 15:05:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EStarCFG=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crypto_test.go | 2 +- database.go | 24 +++- ini.go | 350 ++++++++++++++++++++++++++++++++++++++++++++++++- ini_test.go | 23 ++++ 4 files changed, 393 insertions(+), 6 deletions(-) create mode 100644 ini_test.go diff --git a/crypto_test.go b/crypto_test.go index 509b38d..3850bb5 100644 --- a/crypto_test.go +++ b/crypto_test.go @@ -7,7 +7,7 @@ import ( func Test_FileSumAll(t *testing.T) { cry := new(StarCrypto) - fmt.Println(cry.FileSumAll("D:\\Download\\macos.iso", func(pect float64) { + fmt.Println(cry.FileSumAll("D:\\Download\\macos.iso",[]string{"md5"}, func(pect float64) { fmt.Printf("已处理%f\r", pect) })) } diff --git a/database.go b/database.go index 27eedbb..ae78e72 100644 --- a/database.go +++ b/database.go @@ -67,11 +67,21 @@ func (this *StarResultCol) MustFloat64() []float64 { } func (this *StarResultCol) MustString() []string { var res []string + var tmp string for _, v := range this.Result { - res = append(res, v.(string)) + switch vtype := v.(type) { + case nil: + tmp = "" + case string: + tmp = vtype + default: + tmp = v.(string) + } + res = append(res, tmp) } return res } + func (this *StarResultCol) MustInt32() []int32 { var res []int32 for _, v := range this.Result { @@ -111,11 +121,17 @@ func (this *StarResult) MustInt32(name string) int32 { return res } func (this *StarResult) MustString(name string) string { + var res string num, ok := this.columnref[name] if !ok { return "" } - res := this.Result[num].(string) + switch vtype := this.Result[num].(type) { + case nil: + res = "" + case string: + res = vtype + } return res } func (this *StarResult) MustFloat64(name string) float64 { @@ -255,10 +271,10 @@ func (this *StarDB) Query(args ...interface{}) (*StarRows, error) { } sql := args[0] stmt, err := this.DB.Prepare(sql.(string)) - defer stmt.Close() if err != nil { return effect, err } + defer stmt.Close() var para []interface{} for k, v := range args { if k != 0 { @@ -290,7 +306,7 @@ func (this *StarDB) Close() error { if err := this.DB.Close(); err != nil { return err } - return this.Rows.Close() + return this.DB.Close() } func (this *StarDB) Exec(args ...interface{}) (sql.Result, error) { diff --git a/ini.go b/ini.go index e2ca1f7..39d520d 100644 --- a/ini.go +++ b/ini.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "os" "regexp" + "strconv" "strings" ) @@ -159,7 +160,7 @@ jump: if ok, _ := regexp.MatchString("^#", v); ok { continue } - segfind := regexp.MustCompile(`\[(.*)\]`) + segfind := regexp.MustCompile(`^\[(.*)\]`) if !inseg { if ok, _ := regexp.MatchString(`(.*?)=(.*)`, v); ok { nolabel = true @@ -195,3 +196,350 @@ jump: } return result, nil } + +type StarCfg struct { + Data []*CfgSegment + segmap map[string]int + nodemap map[int]map[string]int +} + +type CfgNode struct { + Key string + Value string + Comment string +} + +type CfgSegment struct { + Name string + cmap map[string]int + Comment string + Node []*CfgNode + InsertNode []*CfgNode +} + +func (this *StarCfg) ParseFromFile(filepath string) error { + if !Exists(filepath) { + return errors.New(filepath + " 不存在") + } + data, err := ioutil.ReadFile(filepath) + if err != nil { + return err + } + this.Parse(data) + return nil +} + +func (this *StarCfg) WriteToFile(filepath string) error { + data := this.Build() + return ioutil.WriteFile(filepath, data, 0644) +} + +func (this *StarCfg) Parse(data []byte) { + var newnode *CfgNode + segint := 0 + nodeint := 0 + this.segmap = make(map[string]int) + this.nodemap = make(map[int]map[string]int) + strdata := string(data) + list := strings.Split(strdata, "\n") + newseg := new(CfgSegment) + newseg.Name = "unnamed" + newseg.InsertNode = []*CfgNode{} + this.segmap["unnamed"] = 0 + lastiseg := true + for _, v := range list { + istrans := false + isseg := false + isnote := false + isequal := false + tmp1 := []rune{} + tmp2 := []rune{} + note := []rune{} + v = strings.TrimSpace(v) + for k, v2 := range v { + if k == 0 { + if v2 == '[' { + isseg = true + continue + } + } + if v2 == '=' && (!istrans && !isnote) { + isequal = true + continue + } + if v2 == ']' && (!istrans && !isnote) { + continue + } + if v2 == '#' && (!istrans && !isnote) { + isnote = true + continue + } + if v2 == '\\' && (!istrans && !isnote) { + istrans = true + continue + } + if istrans { + istrans = false + } + if !isnote && (!isequal) { + tmp1 = append(tmp1, v2) + } else if !isnote && isequal { + tmp2 = append(tmp2, v2) + } else if isnote { + note = append(note, v2) + } + } + if isseg { + this.Data = append(this.Data, newseg) + newseg = new(CfgSegment) + newseg.InsertNode = []*CfgNode{} + newseg.Name = strings.TrimSpace(string(tmp1)) + if isnote { + newseg.Comment = strings.TrimSpace(string(note)) + } + segint++ + this.segmap[newseg.Name] = segint + nodeint = 0 + lastiseg = true + continue + } + if isequal { + newnode = new(CfgNode) + newnode.Key = strings.TrimSpace(string(tmp1)) + newnode.Value = strings.TrimSpace(string(tmp2)) + if isnote { + newnode.Comment = strings.TrimSpace(string(note)) + } + newseg.Node = append(newseg.Node, newnode) + if this.nodemap[segint] == nil { + this.nodemap[segint] = make(map[string]int) + } + this.nodemap[segint][newnode.Key] = nodeint + nodeint++ + lastiseg = false + continue + } + if isnote { + comment := strings.TrimSpace(string(note)) + if lastiseg { + newseg.Comment += "\n" + comment + } else { + newnode.Comment += "\n" + comment + } + continue + } + + } + this.Data = append(this.Data, newseg) +} + +func (this *StarCfg) Seg(name string) *CfgSegment { + if _, ok := this.segmap[name]; !ok { + return nil + } + seg := this.Data[this.segmap[name]] + if seg.Name == name { + seg.cmap = this.nodemap[this.segmap[name]] + return seg + } + return nil +} + +func (this *StarCfg) Build() []byte { + var res, comm string + for _, v := range this.Data { + comm = "" + if v.Name != "unnamed" { + res += `[ ` + this.repkv(v.Name) + ` ]` + } + if v.Comment != "" { + comm = strings.Replace(v.Comment, "\n", "\n#", -1) + if comm[0:1] != "\n" { + comm = " #" + comm + } + + } + res += comm + "\n" + comm = "" + for _, v2 := range v.Node { + res += this.repkv(v2.Key) + " = " + this.repkv(v2.Value) + if v2.Comment != "" { + comm = strings.Replace(v2.Comment, "\n", "\n#", -1) + if comm[0:1] != "\n" { + comm = " #" + comm + } + } + res += comm + "\n" + } + comm = "" + for _, v2 := range v.InsertNode { + res += this.repkv(v2.Key) + " = " + this.repkv(v2.Value) + if v2.Comment != "" { + comm = strings.Replace(v2.Comment, "\n", "\n#", -1) + if comm[0:1] != "\n" { + comm = " #" + comm + } + } + res += comm + "\n" + } + } + return []byte(strings.TrimSpace(res)) +} + +func (this *StarCfg) repkv(value string) string { + value = strings.Replace(value, `\`, `\\`, -1) + value = strings.Replace(value, `#`, `\#`, -1) + value = strings.Replace(value, `=`, `\=`, -1) + value = strings.Replace(value, `[`, `\[`, -1) + value = strings.Replace(value, `]`, `\]`, -1) + return value +} + +func (this *CfgSegment) GetComment(key string) string { + if v, ok := this.cmap[key]; !ok { + for _, v2 := range this.InsertNode { + if v2.Key == key { + return this.Node[v].Comment + } + } + return "" + } else { + return this.Node[v].Comment + } +} + +func (this *CfgSegment) Exist(key string) bool { + if _, ok := this.cmap[key]; !ok { + for _, v2 := range this.InsertNode { + if v2.Key == key { + return true + } + } + return false + } else { + return true + } +} + +func (this *CfgSegment) Get(key string) string { + if v, ok := this.cmap[key]; !ok { + for _, v2 := range this.InsertNode { + if v2.Key == key { + return this.Node[v].Value + } + } + return "" + } else { + return this.Node[v].Value + } +} + +func (this *CfgSegment) Int(key string) int { + val := this.Get(key) + if val == "" { + return 0 + } + res, _ := strconv.Atoi(val) + return res +} + +func (this *CfgSegment) Int64(key string) int64 { + val := this.Get(key) + if val == "" { + return 0 + } + res, _ := strconv.ParseInt(val, 10, 64) + return res +} + +func (this *CfgSegment) Int32(key string) int32 { + val := this.Get(key) + if val == "" { + return 0 + } + res, _ := strconv.ParseInt(val, 10, 32) + return int32(res) +} + +func (this *CfgSegment) Float64(key string) float64 { + val := this.Get(key) + if val == "" { + return 0 + } + res, _ := strconv.ParseFloat(val, 64) + return res +} + +func (this *CfgSegment) Float32(key string) float32 { + val := this.Get(key) + if val == "" { + return 0 + } + res, _ := strconv.ParseFloat(val, 32) + return float32(res) +} + +func (this *CfgSegment) Bool(key string) bool { + val := this.Get(key) + if val == "" { + return false + } + res, _ := strconv.ParseBool(val) + return res +} + +func (this *CfgSegment) SetBool(key string, value bool, comment string) error { + res := strconv.FormatBool(value) + return this.Set(key, res, comment) +} + +func (this *CfgSegment) SetFloat64(key string, prec int, value float64, comment string) error { + res := strconv.FormatFloat(value, 'f', prec, 64) + return this.Set(key, res, comment) +} + +func (this *CfgSegment) SetFloat32(key string, prec int, value float32, comment string) error { + res := strconv.FormatFloat(float64(value), 'f', prec, 32) + return this.Set(key, res, comment) +} + +func (this *CfgSegment) SetInt64(key string, value int64, comment string) error { + res := strconv.FormatInt(value, 10) + return this.Set(key, res, comment) +} + +func (this *CfgSegment) SetInt32(key string, value int32, comment string) error { + res := strconv.FormatInt(int64(value), 10) + return this.Set(key, res, comment) +} + +func (this *CfgSegment) SetInt(key string, value int, comment string) error { + res := strconv.Itoa(value) + return this.Set(key, res, comment) +} + +func (this *CfgSegment) Set(key, value, comment string) error { + if v, ok := this.cmap[key]; !ok { + for _, v2 := range this.InsertNode { + if v2.Key == key { + this.Node[v].Value = value + if comment != "" { + this.Node[v].Comment = comment + } + return nil + } + } + node := new(CfgNode) + node.Key = key + node.Value = value + node.Comment = comment + this.InsertNode = append(this.InsertNode, node) + return nil + } else { + this.Node[v].Value = value + if comment != "" { + this.Node[v].Comment = comment + } + } + return nil +} diff --git a/ini_test.go b/ini_test.go new file mode 100644 index 0000000..a0f18d9 --- /dev/null +++ b/ini_test.go @@ -0,0 +1,23 @@ +package starainrt + +import ( + "fmt" + "testing" +) + +func Test_CfgParse(t *testing.T) { + data := `#lalala + ok =true\# #ok + [happy] #ok + #kkk + me = \=tru + sa = p\\k + migrate = ok #oooo + [siki] + sakurs = ssss #[ossk]` + //data, _ := ioutil.ReadFile(`c:\Users\Starainrt\Desktop\postgresql.conf`) + ini := new(StarCfg) + ini.ParseINI([]byte(data)) + ini.Seg("happy").SetInt64("sakura", 986787,"") + fmt.Println(string(ini.Build())) +}