2023-03-28 18:58:39 +08:00
|
|
|
|
// Package tree ...
|
|
|
|
|
//
|
|
|
|
|
// Description : tree ...
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 2023-03-28 18:42
|
|
|
|
|
package tree
|
|
|
|
|
|
2023-03-29 14:40:59 +08:00
|
|
|
|
import (
|
2023-03-29 22:06:28 +08:00
|
|
|
|
"fmt"
|
2023-03-29 14:40:59 +08:00
|
|
|
|
"strings"
|
2023-03-29 22:06:28 +08:00
|
|
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
2023-03-29 14:40:59 +08:00
|
|
|
|
)
|
2023-03-28 23:56:13 +08:00
|
|
|
|
|
2023-03-28 18:58:39 +08:00
|
|
|
|
// New 生成一棵JSON树
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 18:42 2023/3/28
|
2023-03-29 22:06:28 +08:00
|
|
|
|
func New(jsonData string) (*Generate, error) {
|
2023-03-28 23:56:13 +08:00
|
|
|
|
jsonData = strings.TrimSpace(jsonData)
|
|
|
|
|
g := &Generate{
|
2023-03-29 14:40:59 +08:00
|
|
|
|
jsonData: jsonData,
|
|
|
|
|
jsonDataByte: []byte(jsonData),
|
2023-03-28 23:56:13 +08:00
|
|
|
|
}
|
2023-03-29 14:40:59 +08:00
|
|
|
|
g.root = NewVirtualNode()
|
|
|
|
|
g.currentNode = g.root
|
2023-03-29 22:06:28 +08:00
|
|
|
|
err := g.init()
|
|
|
|
|
return g, err
|
2023-03-28 23:56:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generate ...
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 22:46 2023/3/28
|
|
|
|
|
type Generate struct {
|
2023-03-29 22:06:28 +08:00
|
|
|
|
root *Node // 根节点
|
|
|
|
|
currentNode *Node // 当前节点
|
|
|
|
|
currentParentNode *Node // 当前节点的父节点
|
|
|
|
|
jsonData string
|
|
|
|
|
jsonDataByte []byte
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// init 初始化
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 21:23 2023/3/29
|
|
|
|
|
func (g *Generate) init() error {
|
|
|
|
|
startIndex := 0
|
|
|
|
|
var (
|
|
|
|
|
jsonKey string
|
|
|
|
|
err error
|
|
|
|
|
valueType string
|
2023-03-30 12:26:17 +08:00
|
|
|
|
jsonValue string
|
2023-03-29 22:06:28 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 获取类型
|
|
|
|
|
if valueType, startIndex, err = g.getValueType(startIndex); nil != err {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g.root.ValueType = valueType
|
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
if startIndex >= len(g.jsonDataByte) {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取字段
|
|
|
|
|
if jsonKey, startIndex, err = g.getKey(startIndex); nil != err {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
// 获取类型
|
|
|
|
|
if valueType, startIndex, err = g.getValueType(startIndex); nil != err {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2023-03-30 12:26:17 +08:00
|
|
|
|
// 获取值
|
2023-03-30 13:59:27 +08:00
|
|
|
|
if jsonValue, startIndex, err = g.getValue(startIndex); nil != err {
|
2023-03-30 12:26:17 +08:00
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
fmt.Println(jsonKey, valueType, jsonValue, startIndex)
|
2023-03-29 22:06:28 +08:00
|
|
|
|
}
|
|
|
|
|
return nil
|
2023-03-29 14:40:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getKey 获取jsonKey TODO : 转义符识别
|
|
|
|
|
//
|
|
|
|
|
// Author : zhangdeman001@ke.com<张德满>
|
|
|
|
|
//
|
|
|
|
|
// Date : 11:36 2023/3/29
|
|
|
|
|
func (g *Generate) getKey(startIndex int) (string, int, error) {
|
|
|
|
|
keyCharList := []string{}
|
|
|
|
|
hasStart := false
|
|
|
|
|
for startIndex < len(g.jsonDataByte) {
|
|
|
|
|
charStr := string(g.jsonDataByte[startIndex])
|
|
|
|
|
if charStr == KeywordSpace {
|
|
|
|
|
// 跳过空格
|
2023-03-29 22:06:28 +08:00
|
|
|
|
startIndex++
|
2023-03-29 14:40:59 +08:00
|
|
|
|
continue
|
|
|
|
|
}
|
2023-03-30 13:59:27 +08:00
|
|
|
|
|
2023-03-29 14:40:59 +08:00
|
|
|
|
if charStr == KeywordDoubleQuote && !hasStart {
|
|
|
|
|
// 第一次遇见双引号
|
2023-03-29 22:06:28 +08:00
|
|
|
|
startIndex++
|
2023-03-29 14:40:59 +08:00
|
|
|
|
hasStart = true
|
2023-03-29 22:06:28 +08:00
|
|
|
|
continue
|
2023-03-29 14:40:59 +08:00
|
|
|
|
}
|
|
|
|
|
if charStr == KeywordDoubleQuote && hasStart {
|
|
|
|
|
// 第二次遇见双引号,key探寻结束
|
2023-03-29 22:06:28 +08:00
|
|
|
|
startIndex++
|
2023-03-29 14:40:59 +08:00
|
|
|
|
break
|
|
|
|
|
}
|
2023-03-30 12:02:40 +08:00
|
|
|
|
|
2023-03-30 13:59:27 +08:00
|
|
|
|
if !hasStart {
|
|
|
|
|
if charStr == KeywordDoubleQuote || charStr == KeywordObjectStart || charStr == KeywordArrayStart || charStr == KeywordComma {
|
|
|
|
|
startIndex++
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
return "", startIndex, errors.New("parse key : format is invalid")
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-30 12:02:40 +08:00
|
|
|
|
if charStr == KeywordEscapeSymbol {
|
|
|
|
|
// 转义符
|
|
|
|
|
startIndex++
|
|
|
|
|
if startIndex >= len(g.jsonDataByte) {
|
|
|
|
|
// 转义符后面没东西了
|
|
|
|
|
return "", startIndex, errors.New("escape symbol without any data")
|
|
|
|
|
}
|
|
|
|
|
charStr = string(g.jsonDataByte[startIndex])
|
|
|
|
|
}
|
2023-03-29 14:40:59 +08:00
|
|
|
|
keyCharList = append(keyCharList, charStr)
|
|
|
|
|
startIndex++
|
|
|
|
|
}
|
|
|
|
|
jsonKey := strings.Join(keyCharList, "")
|
|
|
|
|
|
|
|
|
|
return jsonKey, startIndex, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getValueType 获取数据类型
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 14:37 2023/3/29
|
|
|
|
|
func (g *Generate) getValueType(startIndex int) (string, int, error) {
|
2023-03-29 22:06:28 +08:00
|
|
|
|
if startIndex == 0 {
|
|
|
|
|
// 初始对象特殊处理
|
|
|
|
|
if string(g.jsonDataByte[0]) == KeywordArrayStart {
|
|
|
|
|
return ValueTypeArray, 1, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初始对象特殊处理
|
|
|
|
|
if string(g.jsonDataByte[0]) == KeywordObjectStart {
|
|
|
|
|
return ValueTypeMap, 1, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return "", 0, errors.New("root data parse : value is invalid")
|
|
|
|
|
}
|
2023-03-29 14:40:59 +08:00
|
|
|
|
// 指针向后, 探寻到冒号之后第一个非空格字符串
|
|
|
|
|
hasFindColon := false
|
|
|
|
|
for startIndex < len(g.jsonDataByte) {
|
|
|
|
|
charStr := string(g.jsonDataByte[startIndex])
|
|
|
|
|
if !hasFindColon {
|
|
|
|
|
if charStr == KeywordSpace {
|
|
|
|
|
// 跳过空格
|
|
|
|
|
startIndex++
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if charStr != KeywordSpace {
|
|
|
|
|
// 非空格
|
|
|
|
|
if charStr != KeywordColon {
|
|
|
|
|
return "", startIndex, errors.New("value is invalid")
|
|
|
|
|
}
|
|
|
|
|
startIndex++
|
|
|
|
|
hasFindColon = true
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !hasFindColon {
|
2023-03-29 22:06:28 +08:00
|
|
|
|
return "", startIndex, errors.New("check json value type : value is invalid")
|
2023-03-29 14:40:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
keyValType := ""
|
|
|
|
|
// 冒号后面探寻值的类型
|
|
|
|
|
for startIndex < len(g.jsonDataByte) {
|
|
|
|
|
charStr := string(g.jsonDataByte[startIndex])
|
|
|
|
|
if charStr == KeywordSpace {
|
|
|
|
|
// 跳过空格
|
|
|
|
|
startIndex++
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 非空
|
|
|
|
|
switch charStr {
|
|
|
|
|
case KeywordMinus:
|
|
|
|
|
fallthrough
|
|
|
|
|
case KeywordOne:
|
|
|
|
|
fallthrough
|
|
|
|
|
case KeywordTwo:
|
|
|
|
|
fallthrough
|
|
|
|
|
case KeywordThree:
|
|
|
|
|
fallthrough
|
|
|
|
|
case KeywordFour:
|
|
|
|
|
fallthrough
|
|
|
|
|
case KeywordFive:
|
|
|
|
|
fallthrough
|
|
|
|
|
case KeywordSix:
|
|
|
|
|
fallthrough
|
|
|
|
|
case KeywordSeven:
|
|
|
|
|
fallthrough
|
|
|
|
|
case KeywordEight:
|
|
|
|
|
fallthrough
|
|
|
|
|
case KeywordNine:
|
|
|
|
|
keyValType = ValueTypeNumber
|
|
|
|
|
case KeywordDoubleQuote:
|
|
|
|
|
keyValType = ValueTypeString
|
|
|
|
|
case KeywordArrayStart:
|
|
|
|
|
keyValType = ValueTypeArray
|
|
|
|
|
case KeywordObjectStart:
|
|
|
|
|
keyValType = ValueTypeMap
|
|
|
|
|
default:
|
2023-03-29 22:06:28 +08:00
|
|
|
|
return "", startIndex, errors.New("validate json value type : value type is invalid")
|
2023-03-29 14:40:59 +08:00
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
return keyValType, startIndex, nil
|
2023-03-28 23:56:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-03-30 12:26:17 +08:00
|
|
|
|
// getValue 获取JSON值
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 12:09 2023/3/30
|
2023-03-30 13:59:27 +08:00
|
|
|
|
func (g *Generate) getValue(startIndex int) (string, int, error) {
|
2023-03-30 12:26:17 +08:00
|
|
|
|
valArr := make([]string, 0)
|
|
|
|
|
isStart := false
|
|
|
|
|
for startIndex < len(g.jsonDataByte) {
|
|
|
|
|
str := string(g.jsonDataByte[startIndex])
|
|
|
|
|
if str == KeywordSpace {
|
|
|
|
|
startIndex++
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if !isStart {
|
|
|
|
|
if str == KeywordArrayEnd || str == KeywordObjectEnd || str == KeywordComma {
|
|
|
|
|
startIndex++
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if isStart {
|
|
|
|
|
if str == KeywordDoubleQuote || str == KeywordArrayEnd || str == KeywordObjectEnd || str == KeywordComma {
|
|
|
|
|
// 值的拼接已结束
|
|
|
|
|
startIndex++
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if str == KeywordDoubleQuote {
|
|
|
|
|
if isStart {
|
|
|
|
|
startIndex++
|
|
|
|
|
break
|
|
|
|
|
} else {
|
|
|
|
|
startIndex++
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
isStart = true
|
2023-03-30 14:13:09 +08:00
|
|
|
|
if str == KeywordEscapeSymbol {
|
|
|
|
|
// 转义符
|
|
|
|
|
startIndex++
|
|
|
|
|
if startIndex >= len(g.jsonDataByte) {
|
|
|
|
|
// 转义符后面没东西了
|
|
|
|
|
return "", startIndex, errors.New("escape symbol without any data")
|
|
|
|
|
}
|
|
|
|
|
str = string(g.jsonDataByte[startIndex])
|
|
|
|
|
}
|
2023-03-30 12:26:17 +08:00
|
|
|
|
valArr = append(valArr, str)
|
|
|
|
|
startIndex++
|
|
|
|
|
}
|
2023-03-30 13:59:27 +08:00
|
|
|
|
return strings.Join(valArr, ""), startIndex, nil
|
2023-03-30 12:26:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-03-28 23:56:13 +08:00
|
|
|
|
// isObject 整体是否为对象
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 22:51 2023/3/28
|
|
|
|
|
func (g *Generate) isObject() bool {
|
|
|
|
|
return strings.HasPrefix(g.jsonData, KeywordObjectStart)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// isArray 整体是否为数组
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 22:51 2023/3/28
|
|
|
|
|
func (g *Generate) isArray() bool {
|
|
|
|
|
return strings.HasPrefix(g.jsonData, KeywordArrayStart)
|
2023-03-28 18:58:39 +08:00
|
|
|
|
}
|