diff --git a/encoding/gini/gini.go b/encoding/gini/gini.go index deb9c523f..ec3309a1f 100644 --- a/encoding/gini/gini.go +++ b/encoding/gini/gini.go @@ -11,20 +11,19 @@ import ( "bufio" "bytes" "encoding/json" + "errors" "fmt" "io" "strings" ) -//Decode converts INI format to map +// Decode converts INI format to map. func Decode(data []byte) (res map[string]interface{}, err error) { res = make(map[string]interface{}) fieldMap := make(map[string]interface{}) a := bytes.NewReader(data) - r := bufio.NewReader(a) - var section string var lastSection string var haveSection bool @@ -65,30 +64,27 @@ func Decode(data []byte) (res map[string]interface{}, err error) { if strings.Contains(lineStr, "=") && haveSection { values := strings.Split(lineStr, "=") - fieldMap[strings.TrimSpace(values[0])] = strings.TrimSpace(strings.Join(values[1:], "")) res[section] = fieldMap } - } if haveSection == false { - return nil, fmt.Errorf("Failed to parse INI file, not found section") + return nil, errors.New("failed to parse INI file, section not found") } return res, nil } -//Encode converts map to INI format +// Encode converts map to INI format. func Encode(data map[string]interface{}) (res []byte, err error) { w := new(bytes.Buffer) - w.WriteString(";gini\n") + w.WriteString("; this ini file is produced by package gini\n") for k, v := range data { n, err := w.WriteString(fmt.Sprintf("[%s]\n", k)) if err != nil || n == 0 { return nil, fmt.Errorf("write data failed. %v", err) } - for kk, vv := range v.(map[string]interface{}) { n, err := w.WriteString(fmt.Sprintf("%s=%s\n", kk, vv.(string))) if err != nil || n == 0 { @@ -105,12 +101,11 @@ func Encode(data map[string]interface{}) (res []byte, err error) { return res, nil } -//ToJson convert INI format to JSON +// ToJson convert INI format to JSON. func ToJson(data []byte) (res []byte, err error) { iniMap, err := Decode(data) if err != nil { return nil, err } - return json.Marshal(iniMap) } diff --git a/encoding/gjson/gjson.go b/encoding/gjson/gjson.go index 07be1b0dc..f29351bb9 100644 --- a/encoding/gjson/gjson.go +++ b/encoding/gjson/gjson.go @@ -38,7 +38,7 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error { array := strings.Split(pattern, string(j.c)) length := len(array) value = j.convertValue(value) - // 初始化判断 + // Initialization checks. if *j.p == nil { if gstr.IsNumeric(array[0]) { *j.p = make([]interface{}, 0) @@ -146,9 +146,15 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error { pointer = &v } } else { - var v interface{} = make(map[string]interface{}) - pparent = j.setPointerWithValue(pointer, array[i], v) - pointer = &v + v := (*pointer).([]interface{}) + if len(v) > valn { + pparent = pointer + pointer = &(*pointer).([]interface{})[valn] + } else { + var v interface{} = make(map[string]interface{}) + pparent = j.setPointerWithValue(pointer, array[i], v) + pointer = &v + } } } diff --git a/encoding/gjson/gjson_z_example_conversion_test.go b/encoding/gjson/gjson_z_example_conversion_test.go new file mode 100644 index 000000000..c839037d4 --- /dev/null +++ b/encoding/gjson/gjson_z_example_conversion_test.go @@ -0,0 +1,111 @@ +// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gjson_test + +import ( + "fmt" + "github.com/gogf/gf/encoding/gjson" +) + +func Example_Conversion_NormalFormats() { + data := + `{ + "users" : { + "count" : 1, + "array" : ["John", "Ming"] + } + }` + if j, err := gjson.DecodeToJson(data); err != nil { + panic(err) + } else { + fmt.Println("JSON:") + fmt.Println(j.MustToJsonString()) + fmt.Println("======================") + + fmt.Println("XML:") + fmt.Println(j.MustToXmlString()) + fmt.Println("======================") + + fmt.Println("YAML:") + fmt.Println(j.MustToYamlString()) + fmt.Println("======================") + + fmt.Println("TOML:") + fmt.Println(j.MustToTomlString()) + } + + // Output: + // JSON: + // {"users":{"array":["John","Ming"],"count":1}} + // ====================== + // XML: + // JohnMing1 + // ====================== + // YAML: + // users: + // array: + // - John + // - Ming + // count: 1 + // + // ====================== + // TOML: + // [users] + // array = ["John", "Ming"] + // count = 1.0 +} + +func Example_Conversion_GetStruct() { + data := + `{ + "users" : { + "count" : 1, + "array" : ["John", "Ming"] + } + }` + if j, err := gjson.DecodeToJson(data); err != nil { + panic(err) + } else { + type Users struct { + Count int + Array []string + } + users := new(Users) + if err := j.GetStruct("users", users); err != nil { + panic(err) + } + fmt.Printf(`%+v`, users) + } + + // Output: + // &{Count:1 Array:[John Ming]} +} + +func Example_Conversion_ToStruct() { + data := + ` + { + "count" : 1, + "array" : ["John", "Ming"] + }` + if j, err := gjson.DecodeToJson(data); err != nil { + panic(err) + } else { + type Users struct { + Count int + Array []string + } + users := new(Users) + if err := j.ToStruct(users); err != nil { + panic(err) + } + fmt.Printf(`%+v`, users) + } + + // Output: + // &{Count:1 Array:[John Ming]} +} diff --git a/encoding/gjson/gjson_z_example_dataset_test.go b/encoding/gjson/gjson_z_example_dataset_test.go new file mode 100644 index 000000000..78ddd9038 --- /dev/null +++ b/encoding/gjson/gjson_z_example_dataset_test.go @@ -0,0 +1,63 @@ +// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gjson_test + +import ( + "fmt" + "github.com/gogf/gf/encoding/gjson" +) + +func Example_DataSet_Create1() { + j := gjson.New(nil) + j.Set("name", "John") + j.Set("score", 99.5) + fmt.Printf( + "Name: %s, Score: %v\n", + j.GetString("name"), + j.GetFloat32("score"), + ) + fmt.Println(j.MustToJsonString()) + + // Output: + // Name: John, Score: 99.5 + // {"name":"John","score":99.5} +} + +func Example_DataSet_Create2() { + j := gjson.New(nil) + for i := 0; i < 5; i++ { + j.Set(fmt.Sprintf(`%d.id`, i), i) + j.Set(fmt.Sprintf(`%d.name`, i), fmt.Sprintf(`student-%d`, i)) + } + fmt.Println(j.MustToJsonString()) + + // Output: + // [{"id":0,"name":"student-0"},{"id":1,"name":"student-1"},{"id":2,"name":"student-2"},{"id":3,"name":"student-3"},{"id":4,"name":"student-4"}] +} + +func Example_DataSet_RuntimeEdit() { + data := + `{ + "users" : { + "count" : 2, + "list" : [ + {"name" : "Ming", "score" : 60}, + {"name" : "John", "score" : 59} + ] + } + }` + if j, err := gjson.DecodeToJson(data); err != nil { + panic(err) + } else { + j.Set("users.list.1.score", 100) + fmt.Println("John Score:", j.GetFloat32("users.list.1.score")) + fmt.Println(j.MustToJsonString()) + } + // Output: + // John Score: 100 + // {"users":{"count":2,"list":[{"name":"Ming","score":60},{"name":"John","score":100}]}} +} diff --git a/encoding/gjson/gjson_z_example_load_test.go b/encoding/gjson/gjson_z_example_load_test.go index d8ea84a8d..29001ee7f 100644 --- a/encoding/gjson/gjson_z_example_load_test.go +++ b/encoding/gjson/gjson_z_example_load_test.go @@ -10,24 +10,23 @@ import ( "fmt" "github.com/gogf/gf/debug/gdebug" "github.com/gogf/gf/encoding/gjson" - "github.com/gogf/gf/os/gfile" ) -func Example_LoadJson() { +func Example_Load_Json() { jsonFilePath := gdebug.TestDataPath("json", "data1.json") j, _ := gjson.Load(jsonFilePath) fmt.Println(j.Get("name")) fmt.Println(j.Get("score")) } -func Example_LoadXml() { +func Example_Load_Xml() { jsonFilePath := gdebug.TestDataPath("xml", "data1.xml") j, _ := gjson.Load(jsonFilePath) fmt.Println(j.Get("doc.name")) fmt.Println(j.Get("doc.score")) } -func Example_LoadContent() { +func Example_Load_Content() { jsonContent := `{"name":"john", "score":"100"}` j, _ := gjson.LoadContent(jsonContent) fmt.Println(j.Get("name")) diff --git a/encoding/gjson/gjson_z_example_new_test.go b/encoding/gjson/gjson_z_example_new_test.go index 85273fc21..a1c004fb1 100644 --- a/encoding/gjson/gjson_z_example_new_test.go +++ b/encoding/gjson/gjson_z_example_new_test.go @@ -11,7 +11,7 @@ import ( "github.com/gogf/gf/encoding/gjson" ) -func Example_NewFromJson() { +func Example_New_FromJson() { jsonContent := `{"name":"john", "score":"100"}` j := gjson.New(jsonContent) fmt.Println(j.Get("name")) @@ -21,9 +21,10 @@ func Example_NewFromJson() { // 100 } -func Example_NewFromXml() { +func Example_New_FromXml() { jsonContent := `john100` j := gjson.New(jsonContent) + // Note that there's root node in the XML content. fmt.Println(j.Get("doc.name")) fmt.Println(j.Get("doc.score")) // Output: @@ -31,7 +32,7 @@ func Example_NewFromXml() { // 100 } -func Example_NewFromStruct() { +func Example_New_FromStruct() { type Me struct { Name string `json:"name"` Score int `json:"score"` @@ -48,7 +49,7 @@ func Example_NewFromStruct() { // 100 } -func Example_NewFromStructWithTag() { +func Example_New_FromStructWithTag() { type Me struct { Name string `tag:"name"` Score int `tag:"score"` @@ -59,6 +60,8 @@ func Example_NewFromStructWithTag() { Score: 100, Title: "engineer", } + // The parameter specifies custom priority tags for struct conversion to map, + // multiple tags joined with char ','. j := gjson.NewWithTag(me, "tag") fmt.Println(j.Get("name")) fmt.Println(j.Get("score")) diff --git a/encoding/gjson/gjson_z_example_pattern_test.go b/encoding/gjson/gjson_z_example_pattern_test.go new file mode 100644 index 000000000..ecdf6df25 --- /dev/null +++ b/encoding/gjson/gjson_z_example_pattern_test.go @@ -0,0 +1,71 @@ +// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gjson_test + +import ( + "fmt" + "github.com/gogf/gf/encoding/gjson" +) + +func Example_Pattern_Get() { + data := + `{ + "users" : { + "count" : 2, + "list" : [ + {"name" : "Ming", "score" : 60}, + {"name" : "John", "score" : 99.5} + ] + } + }` + if j, err := gjson.DecodeToJson(data); err != nil { + panic(err) + } else { + fmt.Println("John Score:", j.GetFloat32("users.list.1.score")) + } + // Output: + // John Score: 99.5 +} + +func Example_Pattern_CustomSplitChar() { + data := + `{ + "users" : { + "count" : 2, + "list" : [ + {"name" : "Ming", "score" : 60}, + {"name" : "John", "score" : 99.5} + ] + } + }` + if j, err := gjson.DecodeToJson(data); err != nil { + panic(err) + } else { + j.SetSplitChar('#') + fmt.Println("John Score:", j.GetFloat32("users#list#1#score")) + } + // Output: + // John Score: 99.5 +} + +func Example_Pattern_ViolenceCheck() { + data := + `{ + "users" : { + "count" : 100 + }, + "users.count" : 101 + }` + if j, err := gjson.DecodeToJson(data); err != nil { + panic(err) + } else { + j.SetViolenceCheck(true) + fmt.Println("Users Count:", j.GetInt("users.count")) + } + // Output: + // Users Count: 101 +} diff --git a/encoding/gjson/gjson_z_unit_basic_test.go b/encoding/gjson/gjson_z_unit_basic_test.go index 20fc7ab32..aa50f777e 100644 --- a/encoding/gjson/gjson_z_unit_basic_test.go +++ b/encoding/gjson/gjson_z_unit_basic_test.go @@ -400,11 +400,21 @@ func Test_Basic(t *testing.T) { err = j.Remove("1") t.Assert(err, nil) t.Assert(j.Get("0"), 1) + t.Assert(len(j.ToArray()), 2) + + j = gjson.New(`[1,2,3]`) + // If index 0 is delete, its next item will be at index 0. + t.Assert(j.Remove("0"), nil) + t.Assert(j.Remove("0"), nil) + t.Assert(j.Remove("0"), nil) + t.Assert(j.Get("0"), nil) + t.Assert(len(j.ToArray()), 0) j = gjson.New(`[1,2,3]`) err = j.Remove("3") t.Assert(err, nil) t.Assert(j.Get("0"), 1) + t.Assert(len(j.ToArray()), 3) j = gjson.New(`[1,2,3]`) err = j.Remove("0.3") @@ -414,7 +424,7 @@ func Test_Basic(t *testing.T) { j = gjson.New(`[1,2,3]`) err = j.Remove("0.a") t.Assert(err, nil) - t.Assert(len(j.Get("0").(g.Map)), 0) + t.Assert(j.Get("0"), 1) name := struct { Name string