From fbd8bf9d18e96d819937ec4fb74dc8f2bb6f4dbb Mon Sep 17 00:00:00 2001
From: John
Date: Fri, 19 Jan 2018 15:26:28 +0800
Subject: [PATCH 1/4] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?=
=?UTF-8?q?=E7=AE=A1=E7=90=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
g/encoding/gjson/gjson.go | 18 +-
g/encoding/gjson/internal/gjson.go | 443 -----------------------------
g/encoding/gxml/gxml.go | 31 ++
g/frame/gcfg/gcfg.go | 28 +-
geg/database/mysql/mysql.go | 4 +-
geg/other/test.go | 50 +++-
6 files changed, 118 insertions(+), 456 deletions(-)
delete mode 100644 g/encoding/gjson/internal/gjson.go
create mode 100644 g/encoding/gxml/gxml.go
diff --git a/g/encoding/gjson/gjson.go b/g/encoding/gjson/gjson.go
index 98196ad34..96df83bf9 100644
--- a/g/encoding/gjson/gjson.go
+++ b/g/encoding/gjson/gjson.go
@@ -13,6 +13,9 @@ import (
"io/ioutil"
"encoding/json"
"gitee.com/johng/gf/g/util/gconv"
+ "gitee.com/johng/gf/g/os/gfile"
+ "errors"
+ "gitee.com/johng/gf/g/encoding/gxml"
)
// json解析结果存放数组
@@ -39,7 +42,7 @@ func Decode (b []byte) (interface{}, error) {
}
}
-// 解析json字符串为go变量,注意第二个参数为指针
+// 解析json字符串为go变量,注意第二个参数为指针(任意结构的变量)
func DecodeTo (b []byte, v interface{}) error {
return json.Unmarshal(b, v)
}
@@ -53,13 +56,22 @@ func DecodeToJson (b []byte) (*Json, error) {
}
}
-// 加载json文件内容,并转换为json对象
+// 支持多种配置文件类型转换为json格式内容并解析为gjson.Json对象
+// 支持的配置文件格式:xml, json, yml
func Load (path string) (*Json, error) {
+ var result interface{}
data, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
- var result interface{}
+ switch gfile.Ext(path) {
+ case ".xml":
+ data, err = gxml.ToJson(data)
+ if err != nil {
+ return nil, err
+ }
+ case ".yml":
+ }
if err := json.Unmarshal(data, &result); err != nil {
return nil, err
}
diff --git a/g/encoding/gjson/internal/gjson.go b/g/encoding/gjson/internal/gjson.go
deleted file mode 100644
index 362fa1a17..000000000
--- a/g/encoding/gjson/internal/gjson.go
+++ /dev/null
@@ -1,443 +0,0 @@
-// Copyright 2017 gf Author(https://gitee.com/johng/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://gitee.com/johng/gf.
-
-
-package internal
-
-import (
- "fmt"
- "errors"
- "strings"
- "strconv"
-)
-
-// 这是一个自己开发的,使用go进行json语法解析的解析器,效率没有官方的json解析高,仅作学习参考
-
-const (
- gJSON_CHAR_BRACE_LEFT = rune('{')
- gJSON_CHAR_BRACE_RIGHT = rune('}')
- gJSON_CHAR_BRACKET_LEFT = rune('[')
- gJSON_CHAR_BRACKET_RIGHT = rune(']')
- gJSON_CHAR_QUOTATION = rune('\\')
- gJSON_CHAR_COMMA = rune(',')
- gJSON_CHAR_COLON = rune(':')
- gJSON_CHAR_DOUBLE_QUOTE_MARK = rune('"')
-)
-
-const (
- gJSON_TOKEN_BRACE_LEFT = rune('{')
- gJSON_TOKEN_BRACE_RIGHT = rune('}')
- gJSON_TOKEN_BRACKET_LEFT = rune('[')
- gJSON_TOKEN_BRACKET_RIGHT = rune(']')
- gJSON_TOKEN_COMMA = rune(',')
- gJSON_TOKEN_COLON = rune(':')
- gJSON_TOKEN_STRING = rune('"')
- gJSON_TOKEN_NUMBER = rune('0')
-)
-
-// json关联数组(哈希表)
-type JsonMap map[string]interface{}
-// json索引数组(普通数组,从0开始索引)
-type JsonArray []interface{}
-
-// JSON数据对象
-type gJsonNode struct {
- m JsonMap
- a JsonArray
-}
-
-// JSON语义token
-type gJsonToken struct {
- token []rune // token字符串
- tokenType rune // token类型
- tokenindex int // token在原始字符串中的索引位置
-}
-
-// JSON解析结构对象
-type gJsonParser struct {
- content []rune // 需要解析json字符串(通过string转换为[]rune)
- tokens []gJsonToken // 存放解析content后的json token数组
- root *gJsonNode // json根节点
- pointer *gJsonNode // 指向当前正在解析的json节点
-}
-
-// 解析json字符串
-func Decode(j *string) (*gJsonParser, error) {
- p := &gJsonParser{content:[]rune(*j)}
- err := p.parse()
- if err == nil {
- return p, err
- } else {
- return nil, err
- }
-}
-
-// 判断所给字符串是否为数字
-func isNumeric(s string) bool {
- for i :=0; i < len(s); i++ {
- if s[i] < byte('0') || s[i] > byte('9') {
- return false
- }
- }
- return true
-}
-
-// 获得一个键值对关联数组/哈希表,方便操作,不需要自己做类型转换
-// 注意,如果获取的值不存在,或者类型与json类型不匹配,那么将会返回nil
-func (p *gJsonParser) GetMap(pattern string) JsonMap {
- result := p.Get(pattern)
- if result != nil {
- if r, ok := result.(JsonMap); ok {
- return r
- }
- }
- return nil
-}
-
-// 获得一个数组[]interface{},方便操作,不需要自己做类型转换
-// 注意,如果获取的值不存在,或者类型与json类型不匹配,那么将会返回nil
-func (p *gJsonParser) GetArray(pattern string) JsonArray {
- result := p.Get(pattern)
- if result != nil {
- if r, ok := result.(JsonArray); ok {
- return r
- }
- }
- return nil
-}
-
-
-// 根据约定字符串方式访问json解析数据,参数形如: "items.name.first", "list.0"
-// 返回的结果类型的interface{},因此需要自己做类型转换
-// 如果找不到对应节点的数据,返回nil
-func (p *gJsonParser) Get(pattern string) interface{} {
- var result interface{}
- pointer := p.root
- array := strings.Split(pattern, ".")
- length := len(array)
- for i:= 0; i < length; i++ {
- // 优先判断数组
- if isNumeric(array[i]) {
- n, err := strconv.Atoi(array[i])
- if err == nil && len(pointer.a) > n {
- if i == length - 1 {
- result = pointer.a[n]
- break;
- } else {
- if p, ok := pointer.a[n].(*gJsonNode); ok {
- pointer = p
- continue
- }
- }
- }
- }
- // 其次判断哈希表,如果一个键在数组及map中均不存在,直接返回nil
- if v, ok := pointer.m[array[i]]; ok {
- if i == length - 1 {
- result = v
- } else {
- if p, ok := v.(*gJsonNode); ok {
- pointer = p
- continue
- }
- }
- } else {
- return nil
- }
- }
- // 处理结果,如果是gJsonNode类型,那么需要做转换
- if r, ok := result.(*gJsonNode); ok {
- if len(r.m) < 1 {
- return r.a
- } else {
- return r.m
- }
- }
- return result
-}
-
-// 遍历json字符串数组,并且判断转义
-func (p *gJsonParser) getNextChar(c rune, f int) int {
- for i := f + 1; i < len(p.content); i++ {
- if p.content[i] == c {
- if i > 0 && p.content[i - 1] != gJSON_CHAR_QUOTATION {
- return i
- }
- } else {
- switch p.content[i] {
- case gJSON_CHAR_DOUBLE_QUOTE_MARK:
- r := p.getNextChar(gJSON_CHAR_DOUBLE_QUOTE_MARK, i)
- if r > 0 {
- i = r
- }
- }
- }
- }
- return 0
-}
-
-// 判断字符是否为数字
-func (p *gJsonParser) isCharNumber(c rune) bool {
- if c >= rune('0') && c <= rune('9') {
- return true
- }
- return false
-}
-
-// 按照json语法对保存的字符串进行解析
-func (p *gJsonParser) parse() error {
- // 首先将字符串解析成token进行保存
- for i := 0; i < len(p.content); i++ {
- if p.isCharNumber(p.content[i]) {
- j := i + 1
- for ; j < len(p.content); j++ {
- if !p.isCharNumber(p.content[j]) {
- break;
- }
- }
- p.tokens = append(p.tokens, gJsonToken {
- token: p.content[i:j],
- tokenType: gJSON_TOKEN_NUMBER,
- tokenindex: i,
- })
- i = j - 1
- } else {
- switch p.content[i] {
- case gJSON_CHAR_DOUBLE_QUOTE_MARK:
- r := p.getNextChar(gJSON_CHAR_DOUBLE_QUOTE_MARK, i)
- if r > 0 {
- // 注意这里需要去掉字符串两边的双引号
- p.tokens = append(p.tokens, gJsonToken {
- token: p.content[i+1:r],
- tokenType: gJSON_TOKEN_STRING,
- tokenindex: i,
- })
- i = r
- }
- case gJSON_CHAR_COLON:
- p.tokens = append(p.tokens, gJsonToken{token: p.content[i:i+1], tokenType: gJSON_TOKEN_COLON, tokenindex: i})
- case gJSON_CHAR_COMMA:
- p.tokens = append(p.tokens, gJsonToken{token: p.content[i:i+1], tokenType: gJSON_TOKEN_COMMA, tokenindex: i})
- case gJSON_CHAR_BRACE_LEFT:
- p.tokens = append(p.tokens, gJsonToken{token: p.content[i:i+1], tokenType: gJSON_TOKEN_BRACE_LEFT, tokenindex: i})
- case gJSON_CHAR_BRACE_RIGHT:
- p.tokens = append(p.tokens, gJsonToken{token: p.content[i:i+1], tokenType: gJSON_TOKEN_BRACE_RIGHT, tokenindex: i})
- case gJSON_CHAR_BRACKET_LEFT:
- p.tokens = append(p.tokens, gJsonToken{token: p.content[i:i+1], tokenType: gJSON_TOKEN_BRACKET_LEFT, tokenindex: i})
- case gJSON_CHAR_BRACKET_RIGHT:
- p.tokens = append(p.tokens, gJsonToken{token: p.content[i:i+1], tokenType: gJSON_TOKEN_BRACKET_RIGHT, tokenindex: i})
-
- default:
- c := string(p.content[i])
- if c != " " && c != "\r" && c != "\n" && c != "\t" {
- return errors.New(fmt.Sprintf("json parse error: invalid char '%s' at index %d", c, i))
- }
- }
- }
- }
- // 最后对解析后的token转换为go变量
- return p.parseTokenNodeToVar(0, len(p.tokens) - 1)
-}
-
-// 获取json范围字符包含范围最右侧的索引位置
-func (p *gJsonParser)getTokenBorderRightIndex(token rune, from int) int {
- switch token {
- case gJSON_TOKEN_BRACE_LEFT:
- leftCount := 0
- for i := from + 1; i < len(p.tokens); i++ {
- if p.tokens[i].tokenType == gJSON_TOKEN_BRACE_LEFT {
- leftCount ++
- } else if p.tokens[i].tokenType == gJSON_TOKEN_BRACE_RIGHT {
- if leftCount < 1 {
- return i
- } else {
- leftCount--
- }
- }
- }
- case gJSON_CHAR_BRACKET_LEFT:
- leftCount := 0
- for i := from + 1; i < len(p.tokens); i++ {
- if p.tokens[i].tokenType == gJSON_CHAR_BRACKET_LEFT {
- leftCount ++
- } else if p.tokens[i].tokenType == gJSON_CHAR_BRACKET_RIGHT {
- if leftCount < 1 {
- return i
- } else {
- leftCount--
- }
- }
- }
- }
- return 0
-}
-
-// 将解析过后的json token转换为go变量
-func (p *gJsonParser) parseTokenNodeToVar(left int, right int) error {
- //fmt.Println("================================")
- //for i := left; i <= right; i++ {
- // fmt.Println(string(p.tokens[i].token))
- //}
- for i := left; i <= right; i++ {
- //fmt.Println(string(p.tokens[i].token))
- switch p.tokens[i].tokenType {
- case gJSON_TOKEN_BRACE_LEFT:
- fallthrough
- case gJSON_TOKEN_BRACKET_LEFT:
- node := newJsonNode()
- // 判断根节点
- if p.root == nil {
- p.root = node
- p.pointer = node
- }
- // 判断层级关系
- borderRight := p.getTokenBorderRightIndex(p.tokens[i].tokenType, i)
- if borderRight < 1 {
- return errors.New(fmt.Sprintf("json parse error: unclosed tag '%s' at index %d", string(p.tokens[i].token), p.tokens[i].tokenindex))
- }
- if i > 1 && (
- p.tokens[i-1].tokenType == gJSON_TOKEN_COLON &&
- p.tokens[i-2].tokenType == gJSON_TOKEN_STRING) {
- // json赋值操作
- oldptr := p.pointer
- k := string(p.tokens[i-2].token)
- p.pointer.m[k] = node
- p.pointer = node
- err := p.parseTokenNodeToVar(i + 1, borderRight - 1)
- if err != nil {
- return err
- } else {
- i = borderRight
- p.pointer = oldptr
- }
-
- } else if i > 0 && (
- p.tokens[i-1].tokenType == gJSON_TOKEN_COMMA ||
- p.tokens[i-1].tokenType == gJSON_TOKEN_BRACE_LEFT ||
- p.tokens[i-1].tokenType == gJSON_TOKEN_BRACKET_LEFT) {
- // json数组操作
- oldptr := p.pointer
- p.pointer.a = append(p.pointer.a, node)
- p.pointer = node
- err := p.parseTokenNodeToVar(i + 1, borderRight - 1)
- if err != nil {
- return err
- } else {
- i = borderRight
- p.pointer = oldptr
- }
- } else {
- // json层级关系
- p.pointer = node
- err := p.parseTokenNodeToVar(i + 1, borderRight - 1)
- if err != nil {
- return err
- } else {
- i = borderRight
- }
- }
-
- case gJSON_TOKEN_STRING:
- fallthrough
- case gJSON_TOKEN_NUMBER:
- if i > 0 && p.tokens[i-1].tokenType == gJSON_TOKEN_COLON {
- k := string(p.tokens[i-2].token)
- v := string(p.tokens[i].token)
- p.pointer.m[k] = v
- } else if p.tokens[i+1].tokenType != gJSON_TOKEN_COLON {
- p.pointer.a = append(p.pointer.a, string(p.tokens[i].token))
- }
-
- case gJSON_TOKEN_COLON:
- if i < 1 || (p.tokens[i-1].tokenType != gJSON_TOKEN_STRING) {
- return errors.New(fmt.Sprintf("json parse error: invalid charactar '%s' at index %d", string(p.tokens[i].token), p.tokens[i].tokenindex))
- }
-
- case gJSON_TOKEN_COMMA:
- if (p.tokens[i+1].tokenType != gJSON_TOKEN_STRING &&
- p.tokens[i+1].tokenType != gJSON_TOKEN_NUMBER &&
- p.tokens[i+1].tokenType != gJSON_TOKEN_BRACE_LEFT &&
- p.tokens[i+1].tokenType != gJSON_TOKEN_BRACKET_LEFT) ||
- (i < 1 || (
- p.tokens[i-1].tokenType != gJSON_TOKEN_STRING &&
- p.tokens[i-1].tokenType != gJSON_TOKEN_NUMBER &&
- p.tokens[i-1].tokenType != gJSON_TOKEN_BRACE_RIGHT &&
- p.tokens[i-1].tokenType != gJSON_TOKEN_BRACKET_RIGHT)) {
- return errors.New(fmt.Sprintf("json parse error: invalid charactar '%s' at index %d", string(p.tokens[i].token), p.tokens[i].tokenindex))
- }
- }
- }
- return nil
-}
-
-// 打印出所有的token(测试用)
-func (p *gJsonParser)printTokens() {
- for _, v := range p.tokens {
- fmt.Println(string(v.token))
- }
-}
-
-// 格式化打印根节点
-func (p *gJsonParser)Print() {
- if len(p.root.m) > 0 {
- fmt.Println("{")
- } else {
- fmt.Println("[")
- }
- p.printNode(p.pointer, "\t")
- if len(p.root.m) > 0 {
- fmt.Println("}")
- } else {
- fmt.Println("]")
- }
-}
-
-// 格式化打印根节点
-func (p *gJsonParser)printNode(n *gJsonNode, indent string) {
- if len(n.m) > 0 {
- for k, v := range n.m {
- if t, ok := v.(*gJsonNode); ok {
- if len(t.m) > 0 {
- fmt.Printf("%v%v\t: {\n", indent, k)
- p.printNode(t, indent + "\t")
- fmt.Printf("%v}\n", indent)
- } else {
- fmt.Printf("%v%v\t: [\n", indent, k)
- p.printNode(t, indent + "\t")
- fmt.Printf("%v}\n", indent)
- }
- } else {
- fmt.Printf("%v%v\t: %v\n", indent, k, v)
- }
- }
- }
- if len(n.a) > 0 {
- for k, v := range n.a {
- if t, ok := v.(*gJsonNode); ok {
- if len(t.m) > 0 {
- fmt.Printf("%v%v\t: {\n", indent, k)
- p.printNode(t, indent + "\t")
- fmt.Printf("%v}\n", indent)
- } else {
- fmt.Printf("%v%v\t: [\n", indent, k)
- p.printNode(t, indent + "\t")
- fmt.Printf("%v}\n", indent)
- }
- } else {
- fmt.Printf("%v%v : %v\n", indent, k, v)
- }
- }
- }
-}
-
-// 创建一个json数据对象
-func newJsonNode() *gJsonNode {
- return &gJsonNode {
- m: make(map[string]interface{}),
- a: make([]interface{}, 0),
- }
-}
-
diff --git a/g/encoding/gxml/gxml.go b/g/encoding/gxml/gxml.go
new file mode 100644
index 000000000..b54b7916a
--- /dev/null
+++ b/g/encoding/gxml/gxml.go
@@ -0,0 +1,31 @@
+// Copyright 2017 gf Author(https://gitee.com/johng/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://gitee.com/johng/gf.
+
+// XML
+package gxml
+
+import (
+ "github.com/clbanning/mxj"
+)
+
+// 将XML内容解析为map变量
+func Decode(xmlbyte []byte) (map[string]interface{}, error) {
+ return mxj.NewMapXml(xmlbyte)
+}
+
+// 将map变量解析为XML格式内容
+func Encode(v map[string]interface{}) ([]byte, error) {
+ return mxj.Map(v).Xml()
+}
+
+// XML格式内容直接转换为JSON格式内容
+func ToJson(xmlbyte []byte) ([]byte, error) {
+ if mv, err := mxj.NewMapXml(xmlbyte); err == nil {
+ return mv.Json()
+ } else {
+ return nil, err
+ }
+}
\ No newline at end of file
diff --git a/g/frame/gcfg/gcfg.go b/g/frame/gcfg/gcfg.go
index 0c85405c8..aaef0f8f3 100644
--- a/g/frame/gcfg/gcfg.go
+++ b/g/frame/gcfg/gcfg.go
@@ -16,7 +16,7 @@ import (
)
const (
- gDEFAULT_CONFIG_FILE = "config" // 默认的配置管理文件名称
+ gDEFAULT_CONFIG_FILE = "config.json" // 默认的配置管理文件名称
)
// 配置管理对象
@@ -43,7 +43,7 @@ func (c *Config) filePath(files []string) string {
c.mu.RLock()
fpath := c.path + gfile.Separator + file
c.mu.RUnlock()
- return fpath + ".json"
+ return fpath
}
// 设置配置管理器的配置文件存放目录绝对路径
@@ -111,6 +111,14 @@ func (c *Config) GetBool(pattern string, files...string) bool {
return false
}
+// 返回指定json中的float32
+func (c *Config) GetFloat32(pattern string, files...string) float32 {
+ if j := c.getJson(files); j != nil {
+ return j.GetFloat32(pattern)
+ }
+ return 0
+}
+
// 返回指定json中的float64
func (c *Config) GetFloat64(pattern string, files...string) float64 {
if j := c.getJson(files); j != nil {
@@ -121,10 +129,16 @@ func (c *Config) GetFloat64(pattern string, files...string) float64 {
// 返回指定json中的float64->int
func (c *Config) GetInt(pattern string, files...string) int {
- return int(c.GetFloat64(pattern))
+ if j := c.getJson(files); j != nil {
+ return j.GetInt(pattern)
+ }
+ return 0
}
-// 返回指定json中的float64->int64
-func (c *Config) GetInt64(pattern string, files...string) int64 {
- return int64(c.GetFloat64(pattern))
-}
+// 返回指定json中的float64->uint
+func (c *Config) GetUint(pattern string, files...string) uint {
+ if j := c.getJson(files); j != nil {
+ return j.GetUint(pattern)
+ }
+ return 0
+}
\ No newline at end of file
diff --git a/geg/database/mysql/mysql.go b/geg/database/mysql/mysql.go
index cdd7f15c1..172e57292 100644
--- a/geg/database/mysql/mysql.go
+++ b/geg/database/mysql/mysql.go
@@ -17,7 +17,7 @@ func init () {
Port : "3306",
User : "root",
Pass : "123456",
- Name : "test2",
+ Name : "test",
Type : "mysql",
Role : "master",
Charset : "utf8",
@@ -416,7 +416,7 @@ func main() {
//create()
//create()
//insert()
- //query()
+ query()
//replace()
//save()
//batchInsert()
diff --git a/geg/other/test.go b/geg/other/test.go
index 154f87dfc..c614d0644 100644
--- a/geg/other/test.go
+++ b/geg/other/test.go
@@ -2,8 +2,56 @@ package main
import (
"fmt"
+ "gitee.com/johng/gf/g/encoding/gxml"
+ "gitee.com/johng/gf/g/os/gfile"
)
func main() {
- fmt.Printf("%b\n", 123)
+ //json := gfile.GetBinContents("/home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/frame/config.json")
+ //y, err := yaml.JSONToYAML(json)
+ //fmt.Println(err)
+ //fmt.Println(string(y))
+ //
+ //j, err := yaml.YAMLToJSON(y)
+ //fmt.Println(err)
+ //fmt.Println(string(j))
+
+ x := `
+
+
+
+ Comments for 碎言碎语
+
+ http://johng.cn
+
+ Fri, 05 Jan 2018 02:56:11 +0000
+ hourly
+ 1
+ https://wordpress.org/?v=4.7.3
+ -
+ Comment on Go性能优化:string与[ ]byte转换 by John
+ http://johng.cn/go-optimize-string-bytes/#comment-114
+
+ Fri, 05 Jan 2018 02:56:11 +0000
+ http://johng.cn/?p=3435#comment-114
+
+ 这篇文章我转自雨痕,由于string和[]byte之间的转换比较常用,所以这篇文章的性能对比才比较惊人。其他基本类型与[]byte这件的转换性能差别不大,struct与[]byte的转换性能差别主要在数据结构设计上,比如socket通信的话,基本都是自己通过二进制转换来组织需要的数据结构。总得来说,在go开发的时候尽量多用二进制参数([]byte)是好的。
+]]>
+
+
+ -
+ Comment on 层次不同的人,是很难沟通的 by buhuipao
+ http://johng.cn/hard-for-communitication-between-different-levels/#comment-105
+
+ Tue, 19 Sep 2017 09:10:08 +0000
+ http://johng.cn/?p=2854#comment-105
+
+ 博主说得很对,认知很重要。
+]]>
+
+
+`
+
+ j, _ := gxml.ToJson([]byte(x))
+ fmt.Println(string(j))
}
\ No newline at end of file
From 8ecddef8e68ed43a23dfc39e2d4651d488dacfe2 Mon Sep 17 00:00:00 2001
From: John
Date: Fri, 19 Jan 2018 16:19:48 +0800
Subject: [PATCH 2/4] =?UTF-8?q?yaml,xml,json=E6=95=B0=E6=8D=AE=E6=A0=BC?=
=?UTF-8?q?=E5=BC=8F=E5=B0=81=E8=A3=85=E8=A7=A3=E6=9E=90=E6=B5=8B=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
g/encoding/gjson/gjson.go | 54 ++++++++++++++++++++++++++++++---------
g/encoding/gxml/gxml.go | 8 ++++--
g/encoding/gyaml/gyaml.go | 27 ++++++++++++++++++++
g/frame/gcfg/gcfg.go | 3 ++-
geg/frame/config.xml | 1 +
geg/frame/config.yml | 29 +++++++++++++++++++++
geg/other/test.go | 53 +++-----------------------------------
7 files changed, 111 insertions(+), 64 deletions(-)
create mode 100644 g/encoding/gyaml/gyaml.go
create mode 100644 geg/frame/config.xml
create mode 100644 geg/frame/config.yml
diff --git a/g/encoding/gjson/gjson.go b/g/encoding/gjson/gjson.go
index 96df83bf9..3f028fb9f 100644
--- a/g/encoding/gjson/gjson.go
+++ b/g/encoding/gjson/gjson.go
@@ -12,10 +12,10 @@ import (
"strconv"
"io/ioutil"
"encoding/json"
- "gitee.com/johng/gf/g/util/gconv"
"gitee.com/johng/gf/g/os/gfile"
- "errors"
+ "gitee.com/johng/gf/g/util/gconv"
"gitee.com/johng/gf/g/encoding/gxml"
+ "gitee.com/johng/gf/g/encoding/gyaml"
)
// json解析结果存放数组
@@ -57,20 +57,33 @@ func DecodeToJson (b []byte) (*Json, error) {
}
// 支持多种配置文件类型转换为json格式内容并解析为gjson.Json对象
-// 支持的配置文件格式:xml, json, yml
func Load (path string) (*Json, error) {
- var result interface{}
data, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
- switch gfile.Ext(path) {
+ return LoadContent(data, gfile.Ext(path))
+}
+
+// 支持的配置文件格式:xml, json, yml
+func LoadContent (data []byte, t string) (*Json, error) {
+ var err error
+ var result interface{}
+ switch t {
+ case "xml": fallthrough
case ".xml":
data, err = gxml.ToJson(data)
if err != nil {
return nil, err
}
- case ".yml":
+ case "yml": fallthrough
+ case "yaml": fallthrough
+ case ".yml": fallthrough
+ case ".yaml":
+ data, err = gyaml.ToJson(data)
+ if err != nil {
+ return nil, err
+ }
}
if err := json.Unmarshal(data, &result); err != nil {
return nil, err
@@ -201,10 +214,9 @@ func (p *Json) Get(pattern string) interface{} {
// 转换为map[string]interface{}类型,如果转换失败,返回nil
func (p *Json) ToMap() map[string]interface{} {
- pointer := p.value
- switch (*pointer).(type) {
+ switch (*(p.value)).(type) {
case map[string]interface{}:
- return (*pointer).(map[string]interface{})
+ return (*(p.value)).(map[string]interface{})
default:
return nil
}
@@ -212,15 +224,33 @@ func (p *Json) ToMap() map[string]interface{} {
// 转换为[]interface{}类型,如果转换失败,返回nil
func (p *Json) ToArray() []interface{} {
- pointer := p.value
- switch (*pointer).(type) {
+ switch (*(p.value)).(type) {
case []interface{}:
- return (*pointer).([]interface{})
+ return (*(p.value)).([]interface{})
default:
return nil
}
}
+func (p *Json) ToXml(rootTag...string) ([]byte, error) {
+ return gxml.Encode(p.ToMap(), rootTag...)
+}
+
+func (p *Json) ToXmlIndent(rootTag...string) ([]byte, error) {
+ return gxml.EncodeWithIndent(p.ToMap(), rootTag...)
+}
+
+func (p *Json) ToJson() ([]byte, error) {
+ return Encode(*(p.value))
+}
+
+func (p *Json) ToJsonIndent() ([]byte, error) {
+ return json.MarshalIndent(*(p.value), "", "\t")
+}
+
+func (p *Json) ToYaml() ([]byte, error) {
+ return gyaml.Encode(*(p.value))
+}
// 判断所给字符串是否为数字
func isNumeric(s string) bool {
diff --git a/g/encoding/gxml/gxml.go b/g/encoding/gxml/gxml.go
index b54b7916a..4a132546b 100644
--- a/g/encoding/gxml/gxml.go
+++ b/g/encoding/gxml/gxml.go
@@ -17,8 +17,12 @@ func Decode(xmlbyte []byte) (map[string]interface{}, error) {
}
// 将map变量解析为XML格式内容
-func Encode(v map[string]interface{}) ([]byte, error) {
- return mxj.Map(v).Xml()
+func Encode(v map[string]interface{}, rootTag...string) ([]byte, error) {
+ return mxj.Map(v).Xml(rootTag...)
+}
+
+func EncodeWithIndent(v map[string]interface{}, rootTag...string) ([]byte, error) {
+ return mxj.Map(v).XmlIndent("", "\t", rootTag...)
}
// XML格式内容直接转换为JSON格式内容
diff --git a/g/encoding/gyaml/gyaml.go b/g/encoding/gyaml/gyaml.go
new file mode 100644
index 000000000..356e25d26
--- /dev/null
+++ b/g/encoding/gyaml/gyaml.go
@@ -0,0 +1,27 @@
+// Copyright 2017 gf Author(https://gitee.com/johng/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://gitee.com/johng/gf.
+
+// YAML
+package gyaml
+
+import "github.com/ghodss/yaml"
+
+func Encode(v interface{}) ([]byte, error) {
+ return yaml.Marshal(v)
+}
+
+func Decode(v []byte) error {
+ var result interface{}
+ return yaml.Unmarshal(v, &result)
+}
+
+func DecodeTo(v []byte, result interface{}) error {
+ return yaml.Unmarshal(v, &result)
+}
+
+func ToJson(v []byte) ([]byte, error) {
+ return yaml.YAMLToJSON(v)
+}
\ No newline at end of file
diff --git a/g/frame/gcfg/gcfg.go b/g/frame/gcfg/gcfg.go
index aaef0f8f3..75c2aaeb6 100644
--- a/g/frame/gcfg/gcfg.go
+++ b/g/frame/gcfg/gcfg.go
@@ -4,7 +4,8 @@
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
-// 配置管理
+// 配置管理.
+// 配置文件格式支持:json, xml, yml
package gcfg
import (
diff --git a/geg/frame/config.xml b/geg/frame/config.xml
new file mode 100644
index 000000000..42c1bdf97
--- /dev/null
+++ b/geg/frame/config.xml
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/geg/frame/config.yml b/geg/frame/config.yml
new file mode 100644
index 000000000..433dcf4a9
--- /dev/null
+++ b/geg/frame/config.yml
@@ -0,0 +1,29 @@
+{
+ "viewpath" : "/home/www/templates/",
+ "database" : {
+ "default" : [
+ {
+ "host" : "127.0.0.1",
+ "port" : "3306",
+ "user" : "root",
+ "pass" : "123456",
+ "name" : "test",
+ "type" : "mysql",
+ "role" : "master",
+ "charset" : "utf8",
+ "priority" : "1"
+ },
+ {
+ "host" : "127.0.0.1",
+ "port" : "3306",
+ "user" : "root",
+ "pass" : "123456",
+ "name" : "test",
+ "type" : "mysql",
+ "role" : "master",
+ "charset" : "utf8",
+ "priority" : "1"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/geg/other/test.go b/geg/other/test.go
index c614d0644..d04c615bd 100644
--- a/geg/other/test.go
+++ b/geg/other/test.go
@@ -2,56 +2,11 @@ package main
import (
"fmt"
- "gitee.com/johng/gf/g/encoding/gxml"
- "gitee.com/johng/gf/g/os/gfile"
+ "gitee.com/johng/gf/g/encoding/gjson"
)
func main() {
- //json := gfile.GetBinContents("/home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/frame/config.json")
- //y, err := yaml.JSONToYAML(json)
- //fmt.Println(err)
- //fmt.Println(string(y))
- //
- //j, err := yaml.YAMLToJSON(y)
- //fmt.Println(err)
- //fmt.Println(string(j))
-
- x := `
-
-
-
- Comments for 碎言碎语
-
- http://johng.cn
-
- Fri, 05 Jan 2018 02:56:11 +0000
- hourly
- 1
- https://wordpress.org/?v=4.7.3
- -
- Comment on Go性能优化:string与[ ]byte转换 by John
- http://johng.cn/go-optimize-string-bytes/#comment-114
-
- Fri, 05 Jan 2018 02:56:11 +0000
- http://johng.cn/?p=3435#comment-114
-
- 这篇文章我转自雨痕,由于string和[]byte之间的转换比较常用,所以这篇文章的性能对比才比较惊人。其他基本类型与[]byte这件的转换性能差别不大,struct与[]byte的转换性能差别主要在数据结构设计上,比如socket通信的话,基本都是自己通过二进制转换来组织需要的数据结构。总得来说,在go开发的时候尽量多用二进制参数([]byte)是好的。
-]]>
-
-
- -
- Comment on 层次不同的人,是很难沟通的 by buhuipao
- http://johng.cn/hard-for-communitication-between-different-levels/#comment-105
-
- Tue, 19 Sep 2017 09:10:08 +0000
- http://johng.cn/?p=2854#comment-105
-
- 博主说得很对,认知很重要。
-]]>
-
-
-`
-
- j, _ := gxml.ToJson([]byte(x))
- fmt.Println(string(j))
+ j, _ := gjson.Load("/home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/frame/config.json")
+ c, _ := j.ToXmlIndent("config")
+ fmt.Println(string(c))
}
\ No newline at end of file
From 94e859812b469eed75e2ecf12f4eae9e40b90fb4 Mon Sep 17 00:00:00 2001
From: John
Date: Fri, 19 Jan 2018 17:48:40 +0800
Subject: [PATCH 3/4] =?UTF-8?q?gcfg=E5=8A=9F=E8=83=BD=E5=AE=8C=E5=96=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
geg/frame/config.xml | 29 +++++++++++++++++++++++++-
geg/frame/config.yml | 49 ++++++++++++++++++--------------------------
2 files changed, 48 insertions(+), 30 deletions(-)
diff --git a/geg/frame/config.xml b/geg/frame/config.xml
index 42c1bdf97..f0dfbf90f 100644
--- a/geg/frame/config.xml
+++ b/geg/frame/config.xml
@@ -1 +1,28 @@
-
\ No newline at end of file
+
+
+ /home/www/templates/
+
+
+ 127.0.0.1
+ 3306
+ root
+ 123456
+ test
+ master
+ mysql
+ utf8
+ 1
+
+
+ 127.0.0.1
+ 3306
+ root
+ 123456
+ test
+ master
+ mysql
+ utf8
+ 1
+
+
+
\ No newline at end of file
diff --git a/geg/frame/config.yml b/geg/frame/config.yml
index 433dcf4a9..c19de3fc7 100644
--- a/geg/frame/config.yml
+++ b/geg/frame/config.yml
@@ -1,29 +1,20 @@
-{
- "viewpath" : "/home/www/templates/",
- "database" : {
- "default" : [
- {
- "host" : "127.0.0.1",
- "port" : "3306",
- "user" : "root",
- "pass" : "123456",
- "name" : "test",
- "type" : "mysql",
- "role" : "master",
- "charset" : "utf8",
- "priority" : "1"
- },
- {
- "host" : "127.0.0.1",
- "port" : "3306",
- "user" : "root",
- "pass" : "123456",
- "name" : "test",
- "type" : "mysql",
- "role" : "master",
- "charset" : "utf8",
- "priority" : "1"
- }
- ]
- }
-}
\ No newline at end of file
+viewpath: /home/www/templates/
+database:
+ default:
+ - host: 127.0.0.1
+ port: 3306
+ user: root
+ pass: 123456
+ name: test
+ type: mysql
+ role: master
+ priority: 1
+ - host: 127.0.0.1
+ port: 3306
+ user: root
+ pass: 123456
+ name: test
+ type: mysql
+ role: master
+ priority: 1
+
From 6081ac78873c44df97b4949459b81808e462d3e0 Mon Sep 17 00:00:00 2001
From: John
Date: Sat, 20 Jan 2018 11:09:27 +0800
Subject: [PATCH 4/4] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8A=A8=E6=80=81?=
=?UTF-8?q?=E5=A4=A7=E5=B0=8F=E7=9A=84=E5=AE=89=E5=85=A8=E9=98=9F=E5=88=97?=
=?UTF-8?q?gqueue=EF=BC=8C=E5=B9=B6=E4=BF=AE=E6=AD=A3grpool=E5=85=B3?=
=?UTF-8?q?=E9=97=AD=E6=97=B6=E7=9A=84=E6=95=B0=E9=87=8F=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
g/container/gqueue/int_queue.go | 54 ++++++++++++++++++++++++++
g/container/gqueue/interface_queue.go | 55 +++++++++++++++++++++++++++
g/container/gqueue/string_queue.go | 54 ++++++++++++++++++++++++++
g/container/gqueue/uint_queue.go | 54 ++++++++++++++++++++++++++
g/encoding/gjson/gjson.go | 22 ++++++++---
g/encoding/gtoml/gtoml.go | 42 ++++++++++++++++++++
g/encoding/gyaml/gyaml.go | 7 +++-
g/frame/gins/gins.go | 6 +--
g/{frame => os}/gcfg/gcfg.go | 2 +-
g/os/grpool/grpool_api.go | 2 +-
geg/container/gqueue.go | 32 ++++++++++++++++
geg/other/test.go | 13 +++++--
12 files changed, 327 insertions(+), 16 deletions(-)
create mode 100644 g/container/gqueue/int_queue.go
create mode 100644 g/container/gqueue/interface_queue.go
create mode 100644 g/container/gqueue/string_queue.go
create mode 100644 g/container/gqueue/uint_queue.go
create mode 100644 g/encoding/gtoml/gtoml.go
rename g/{frame => os}/gcfg/gcfg.go (98%)
create mode 100644 geg/container/gqueue.go
diff --git a/g/container/gqueue/int_queue.go b/g/container/gqueue/int_queue.go
new file mode 100644
index 000000000..794004ee7
--- /dev/null
+++ b/g/container/gqueue/int_queue.go
@@ -0,0 +1,54 @@
+// Copyright 2017 gf Author(https://gitee.com/johng/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://gitee.com/johng/gf.
+
+package gqueue
+
+import (
+ "math"
+ "sync"
+ "container/list"
+)
+
+type IntQueue struct {
+ mu sync.RWMutex
+ list *list.List
+ events chan struct{}
+}
+
+func NewIntQueue() *IntQueue {
+ return &IntQueue{
+ list : list.New(),
+ events : make(chan struct{}, math.MaxInt64),
+ }
+}
+
+// 将数据压入队列
+func (q *IntQueue) Push(v int) {
+ q.mu.Lock()
+ q.list.PushBack(v)
+ q.mu.Unlock()
+ q.events <- struct{}{}
+}
+
+// 先进先出地从队列取出一项数据,当没有数据可获取时,阻塞等待
+func (q *IntQueue) Pop() int {
+ select {
+ case <- q.events:
+ q.mu.Lock()
+ if elem := q.list.Front(); elem != nil {
+ item := q.list.Remove(elem).(int)
+ q.mu.Unlock()
+ return item
+ }
+ q.mu.Unlock()
+ }
+ return 0
+}
+
+// 获取当前队列大小
+func (q *IntQueue) Size() int {
+ return len(q.events)
+}
\ No newline at end of file
diff --git a/g/container/gqueue/interface_queue.go b/g/container/gqueue/interface_queue.go
new file mode 100644
index 000000000..7c6122f23
--- /dev/null
+++ b/g/container/gqueue/interface_queue.go
@@ -0,0 +1,55 @@
+// Copyright 2017 gf Author(https://gitee.com/johng/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://gitee.com/johng/gf.
+
+// 动态大小的安全队列(dynamic channel).
+package gqueue
+
+import (
+ "math"
+ "sync"
+ "container/list"
+)
+
+type InterfaceQueue struct {
+ mu sync.RWMutex
+ list *list.List
+ events chan struct{}
+}
+
+func NewInterfaceQueue() *InterfaceQueue {
+ return &InterfaceQueue {
+ list : list.New(),
+ events : make(chan struct{}, math.MaxInt64),
+ }
+}
+
+// 将数据压入队列
+func (q *InterfaceQueue) Push(v interface{}) {
+ q.mu.Lock()
+ q.list.PushBack(v)
+ q.mu.Unlock()
+ q.events <- struct{}{}
+}
+
+// 先进先出地从队列取出一项数据,当没有数据可获取时,阻塞等待
+func (q *InterfaceQueue) Pop() interface{} {
+ select {
+ case <- q.events:
+ q.mu.Lock()
+ if elem := q.list.Front(); elem != nil {
+ item := q.list.Remove(elem)
+ q.mu.Unlock()
+ return item
+ }
+ q.mu.Unlock()
+ }
+ return nil
+}
+
+// 获取当前队列大小
+func (q *InterfaceQueue) Size() int {
+ return len(q.events)
+}
\ No newline at end of file
diff --git a/g/container/gqueue/string_queue.go b/g/container/gqueue/string_queue.go
new file mode 100644
index 000000000..fb67c0c0c
--- /dev/null
+++ b/g/container/gqueue/string_queue.go
@@ -0,0 +1,54 @@
+// Copyright 2017 gf Author(https://gitee.com/johng/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://gitee.com/johng/gf.
+
+package gqueue
+
+import (
+ "math"
+ "sync"
+ "container/list"
+)
+
+type StringQueue struct {
+ mu sync.RWMutex
+ list *list.List
+ events chan struct{}
+}
+
+func NewStringQueue() *StringQueue {
+ return &StringQueue{
+ list : list.New(),
+ events : make(chan struct{}, math.MaxInt64),
+ }
+}
+
+// 将数据压入队列
+func (q *StringQueue) Push(v string) {
+ q.mu.Lock()
+ q.list.PushBack(v)
+ q.mu.Unlock()
+ q.events <- struct{}{}
+}
+
+// 先进先出地从队列取出一项数据,当没有数据可获取时,阻塞等待
+func (q *StringQueue) Pop() string {
+ select {
+ case <- q.events:
+ q.mu.Lock()
+ if elem := q.list.Front(); elem != nil {
+ item := q.list.Remove(elem).(string)
+ q.mu.Unlock()
+ return item
+ }
+ q.mu.Unlock()
+ }
+ return ""
+}
+
+// 获取当前队列大小
+func (q *StringQueue) Size() int {
+ return len(q.events)
+}
\ No newline at end of file
diff --git a/g/container/gqueue/uint_queue.go b/g/container/gqueue/uint_queue.go
new file mode 100644
index 000000000..601ffb59e
--- /dev/null
+++ b/g/container/gqueue/uint_queue.go
@@ -0,0 +1,54 @@
+// Copyright 2017 gf Author(https://gitee.com/johng/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://gitee.com/johng/gf.
+
+package gqueue
+
+import (
+ "math"
+ "sync"
+ "container/list"
+)
+
+type UintQueue struct {
+ mu sync.RWMutex
+ list *list.List
+ events chan struct{}
+}
+
+func NewUintQueue() *UintQueue {
+ return &UintQueue{
+ list : list.New(),
+ events : make(chan struct{}, math.MaxInt64),
+ }
+}
+
+// 将数据压入队列
+func (q *UintQueue) Push(v uint) {
+ q.mu.Lock()
+ q.list.PushBack(v)
+ q.mu.Unlock()
+ q.events <- struct{}{}
+}
+
+// 先进先出地从队列取出一项数据,当没有数据可获取时,阻塞等待
+func (q *UintQueue) Pop() uint {
+ select {
+ case <- q.events:
+ q.mu.Lock()
+ if elem := q.list.Front(); elem != nil {
+ item := q.list.Remove(elem).(uint)
+ q.mu.Unlock()
+ return item
+ }
+ q.mu.Unlock()
+ }
+ return 0
+}
+
+// 获取当前队列大小
+func (q *UintQueue) Size() int {
+ return len(q.events)
+}
\ No newline at end of file
diff --git a/g/encoding/gjson/gjson.go b/g/encoding/gjson/gjson.go
index 3f028fb9f..3712459b5 100644
--- a/g/encoding/gjson/gjson.go
+++ b/g/encoding/gjson/gjson.go
@@ -16,6 +16,7 @@ import (
"gitee.com/johng/gf/g/util/gconv"
"gitee.com/johng/gf/g/encoding/gxml"
"gitee.com/johng/gf/g/encoding/gyaml"
+ "gitee.com/johng/gf/g/encoding/gtoml"
)
// json解析结果存放数组
@@ -65,25 +66,32 @@ func Load (path string) (*Json, error) {
return LoadContent(data, gfile.Ext(path))
}
-// 支持的配置文件格式:xml, json, yml
+// 支持的配置文件格式:xml, json, yaml/yml, toml
func LoadContent (data []byte, t string) (*Json, error) {
var err error
var result interface{}
switch t {
- case "xml": fallthrough
+ case "xml": fallthrough
case ".xml":
data, err = gxml.ToJson(data)
if err != nil {
return nil, err
}
- case "yml": fallthrough
- case "yaml": fallthrough
- case ".yml": fallthrough
+ case "yml": fallthrough
+ case "yaml": fallthrough
+ case ".yml": fallthrough
case ".yaml":
data, err = gyaml.ToJson(data)
if err != nil {
return nil, err
}
+
+ case "toml": fallthrough
+ case ".toml":
+ data, err = gtoml.ToJson(data)
+ if err != nil {
+ return nil, err
+ }
}
if err := json.Unmarshal(data, &result); err != nil {
return nil, err
@@ -252,6 +260,10 @@ func (p *Json) ToYaml() ([]byte, error) {
return gyaml.Encode(*(p.value))
}
+func (p *Json) ToToml() ([]byte, error) {
+ return gtoml.Encode(*(p.value))
+}
+
// 判断所给字符串是否为数字
func isNumeric(s string) bool {
for i := 0; i < len(s); i++ {
diff --git a/g/encoding/gtoml/gtoml.go b/g/encoding/gtoml/gtoml.go
new file mode 100644
index 000000000..2e50a4b8a
--- /dev/null
+++ b/g/encoding/gtoml/gtoml.go
@@ -0,0 +1,42 @@
+// Copyright 2017 gf Author(https://gitee.com/johng/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://gitee.com/johng/gf.
+
+// TOML
+package gtoml
+
+import (
+ "bytes"
+ "encoding/json"
+ "github.com/BurntSushi/toml"
+)
+
+func Encode(v interface{}) ([]byte, error) {
+ buffer := bytes.NewBuffer(nil)
+ if err := toml.NewEncoder(buffer).Encode(v); err != nil {
+ return nil, err
+ }
+ return buffer.Bytes(), nil
+}
+
+func Decode(v []byte) (interface{}, error) {
+ var result interface{}
+ if err := toml.Unmarshal(v, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func DecodeTo(v []byte, result interface{}) error {
+ return toml.Unmarshal(v, result)
+}
+
+func ToJson(v []byte) ([]byte, error) {
+ if r, err := Decode(v); err != nil {
+ return nil, err
+ } else {
+ return json.Marshal(r)
+ }
+}
\ No newline at end of file
diff --git a/g/encoding/gyaml/gyaml.go b/g/encoding/gyaml/gyaml.go
index 356e25d26..0371b69ec 100644
--- a/g/encoding/gyaml/gyaml.go
+++ b/g/encoding/gyaml/gyaml.go
@@ -13,9 +13,12 @@ func Encode(v interface{}) ([]byte, error) {
return yaml.Marshal(v)
}
-func Decode(v []byte) error {
+func Decode(v []byte) (interface{}, error) {
var result interface{}
- return yaml.Unmarshal(v, &result)
+ if err := yaml.Unmarshal(v, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
}
func DecodeTo(v []byte, result interface{}) error {
diff --git a/g/frame/gins/gins.go b/g/frame/gins/gins.go
index ef94d27f3..f3288a6b0 100644
--- a/g/frame/gins/gins.go
+++ b/g/frame/gins/gins.go
@@ -4,18 +4,18 @@
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
-// 单例对象管理.
-// 框架内置了一些核心对象,并且可以通过Set和Get方法实现IoC以及对内置核心对象的自定义替换
+// 单例对象管理(耦合了一些框架核心对象获取方法).
+// 框架内置了一些核心对象获取方法,并且可以通过Set和Get方法实现IoC以及对内置核心对象的自定义替换
package gins
import (
"strconv"
+ "gitee.com/johng/gf/g/os/gcfg"
"gitee.com/johng/gf/g/os/gcmd"
"gitee.com/johng/gf/g/os/glog"
"gitee.com/johng/gf/g/os/genv"
"gitee.com/johng/gf/g/os/gview"
"gitee.com/johng/gf/g/os/gfile"
- "gitee.com/johng/gf/g/frame/gcfg"
"gitee.com/johng/gf/g/database/gdb"
"gitee.com/johng/gf/g/container/gmap"
)
diff --git a/g/frame/gcfg/gcfg.go b/g/os/gcfg/gcfg.go
similarity index 98%
rename from g/frame/gcfg/gcfg.go
rename to g/os/gcfg/gcfg.go
index 75c2aaeb6..9f72aa175 100644
--- a/g/frame/gcfg/gcfg.go
+++ b/g/os/gcfg/gcfg.go
@@ -5,7 +5,7 @@
// You can obtain one at https://gitee.com/johng/gf.
// 配置管理.
-// 配置文件格式支持:json, xml, yml
+// 配置文件格式支持:json, xml, toml, yaml/yml
package gcfg
import (
diff --git a/g/os/grpool/grpool_api.go b/g/os/grpool/grpool_api.go
index e3d66bd8f..773fabdb1 100644
--- a/g/os/grpool/grpool_api.go
+++ b/g/os/grpool/grpool_api.go
@@ -56,7 +56,7 @@ func New(expire int, sizes...int) *Pool {
funcs : glist.NewSafeList(),
freeEvents : make(chan struct{}, math.MaxUint32),
funcEvents : make(chan struct{}, math.MaxUint32),
- stopEvents : make(chan struct{}, 1),
+ stopEvents : make(chan struct{}, 2),
}
p.startWorkLoop()
p.startClearLoop()
diff --git a/geg/container/gqueue.go b/geg/container/gqueue.go
new file mode 100644
index 000000000..f85a62ed3
--- /dev/null
+++ b/geg/container/gqueue.go
@@ -0,0 +1,32 @@
+package main
+
+import (
+ "fmt"
+ "gitee.com/johng/gf/g/os/gtime"
+ "gitee.com/johng/gf/g/container/gqueue"
+ "time"
+)
+
+func main() {
+ t := gtime.Microsecond()
+ q := gqueue.NewInterfaceQueue()
+ fmt.Println("queue creation costs(μs):", gtime.Microsecond() - t)
+
+ // 每隔2秒异步打印出当前队列的大小
+ gtime.SetInterval(2*time.Second, func() bool {
+ fmt.Println("queue size:", q.Size())
+ return true
+ })
+
+ // push10条数据
+ for i := 0; i < 10; i++ {
+ q.Push(i)
+ fmt.Println("push:", i)
+ }
+
+ // 每隔1秒pop1条数据
+ for {
+ time.Sleep(time.Second)
+ fmt.Println(" pop:", q.Pop())
+ }
+}
diff --git a/geg/other/test.go b/geg/other/test.go
index d04c615bd..6ebb57f03 100644
--- a/geg/other/test.go
+++ b/geg/other/test.go
@@ -2,11 +2,16 @@ package main
import (
"fmt"
- "gitee.com/johng/gf/g/encoding/gjson"
)
func main() {
- j, _ := gjson.Load("/home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/frame/config.json")
- c, _ := j.ToXmlIndent("config")
- fmt.Println(string(c))
+ c1 := make(chan int, 2)
+ c2 := make(chan int, 5)
+ c1 <- 1
+ c1 <- 2
+ c2 = c1
+ c2 <- 3
+ fmt.Println(<-c2)
+ fmt.Println(<-c2)
+ fmt.Println(<-c2)
}
\ No newline at end of file