package jsonpack import ( "errors" "fmt" "reflect" "strconv" "strings" ) type JsonDecode struct { dictionaries []any tokenIndex int } func (oJsonDecode *JsonDecode) astBuilder(packed string) (string, error) { aStr := strings.Split(packed, "^") if len(aStr) != 4 { return "", errors.New("jsonpack 解析错误") } if aStr[0] != "" { for _, v := range strings.Split(aStr[0], "|") { oJsonDecode.dictionaries = append(oJsonDecode.dictionaries, astDecode(v)) } } if aStr[1] != "" { for _, v := range strings.Split(aStr[1], "|") { oJsonDecode.dictionaries = append(oJsonDecode.dictionaries, astBase36to10(v)) } } if aStr[2] != "" { for _, v := range strings.Split(aStr[2], "|") { if value, err := strconv.ParseFloat(v, 64); err == nil { oJsonDecode.dictionaries = append(oJsonDecode.dictionaries, value) } else { return "", fmt.Errorf("jsonpack 浮点数转换失败 %#v", v) } } } return aStr[3], nil } func (oJsonDecode *JsonDecode) astParser(tokens *[]rune) (string, error) { len := len(*tokens) symbol := (*tokens)[oJsonDecode.tokenIndex] oJsonDecode.tokenIndex = oJsonDecode.tokenIndex + 1 if symbol == '@' { node := []string{} for ; oJsonDecode.tokenIndex < len; oJsonDecode.tokenIndex++ { value := rune((*tokens)[oJsonDecode.tokenIndex]) if value == ']' { return "[" + strings.Join(node, ",") + "]", nil } if value == '@' || value == '$' { // 递归解析 if res, err := oJsonDecode.astParser(tokens); err == nil { node = append(node, res) } else { return "", errors.New("jsonpack 递归解析错误") } } else { // 解析成员 if res, err := oJsonDecode.astParserValue(value); err == nil { node = append(node, res) } else { return "", errors.New("jsonpack 解析成员错误") } } } return "[" + strings.Join(node, ",") + "]", nil } if symbol == '$' { node := []string{} for ; oJsonDecode.tokenIndex < len; oJsonDecode.tokenIndex++ { var key string kIndex := rune((*tokens)[oJsonDecode.tokenIndex]) if kIndex == ']' { return "{" + strings.Join(node, ",") + "}", nil } if kIndex == TOKEN_EMPTY_STRING { key = "" } else { key = strconv.Quote(oJsonDecode.dictionaries[kIndex].(string)) } oJsonDecode.tokenIndex++ value := rune((*tokens)[oJsonDecode.tokenIndex]) if value == '@' || value == '$' { // 递归解析 if res, err := oJsonDecode.astParser(tokens); err == nil { node = append(node, key+":"+res) } else { return "", err } } else { // 解析成员 if res, err := oJsonDecode.astParserValue(value); err == nil { node = append(node, key+":"+res) } else { return "", err } } } return "{" + strings.Join(node, ",") + "}", nil } return "", errors.New("jsonpack 解析错误, 未知符号") } func (oJsonDecode *JsonDecode) astParserValue(value rune) (string, error) { switch value { case TOKEN_TRUE: return "true", nil case TOKEN_FALSE: return "false", nil case TOKEN_NULL: return "null", nil case TOKEN_EMPTY_STRING: return `""`, nil default: item := oJsonDecode.dictionaries[value] switch reflect.ValueOf(item).Kind() { case reflect.String: return strconv.Quote(item.(string)), nil case reflect.Int, reflect.Float64: return fmt.Sprintf("%v", item), nil } } return "", errors.New("jsonpack 未知数据类型") } func (oJsonDecode *JsonDecode) toString(token string) (string, error) { var number36 strings.Builder var tokens []rune len := len(token) for i := 0; i < len; i++ { symbol := rune(token[i]) if symbol == '|' || symbol == '$' || symbol == '@' || symbol == ']' { if number36.Len() > 0 { tokens = append(tokens, rune(astBase36to10(number36.String()))) number36.Reset() } if symbol != '|' { tokens = append(tokens, symbol) } } else { number36.WriteRune(symbol) } } return oJsonDecode.astParser(&tokens) } // func (oJsonDecode *JsonDecode) astParser(tokens *[]rune) (any, error) { // len := len(*tokens) // symbol := (*tokens)[oJsonDecode.tokenIndex] // oJsonDecode.tokenIndex = oJsonDecode.tokenIndex + 1 // if symbol == '@' { // node := []any{} // for ; oJsonDecode.tokenIndex < len; oJsonDecode.tokenIndex++ { // value := rune((*tokens)[oJsonDecode.tokenIndex]) // if value == ']' { // return node, nil // } // if value == '@' || value == '$' { // if resp, err := oJsonDecode.astParser(tokens); err == nil { // node = append(node, resp) // } else { // return nil, errors.New("jsonpack 解析失败") // } // } else { // switch value { // case TOKEN_TRUE: // node = append(node, true) // case TOKEN_FALSE: // node = append(node, false) // case TOKEN_NULL: // node = append(node, nil) // case TOKEN_EMPTY_STRING: // node = append(node, "") // default: // node = append(node, oJsonDecode.dictionaries[value]) // } // } // } // return node, nil // } // if symbol == '$' { // node := map[string]any{} // for ; oJsonDecode.tokenIndex < len; oJsonDecode.tokenIndex++ { // var key string // kIndex := rune((*tokens)[oJsonDecode.tokenIndex]) // if kIndex == ']' { // return node, nil // } // if kIndex == TOKEN_EMPTY_STRING { // key = "" // } else { // key = oJsonDecode.dictionaries[kIndex].(string) // } // oJsonDecode.tokenIndex++ // value := rune((*tokens)[oJsonDecode.tokenIndex]) // if value == '@' || value == '$' { // if res, err := oJsonDecode.astParser(tokens); err == nil { // node[key] = res // } else { // return nil, errors.New("jsonpack 递归解析 数组或对象 错误") // } // } else { // switch value { // case TOKEN_TRUE: // node[key] = true // case TOKEN_FALSE: // node[key] = false // case TOKEN_NULL: // node[key] = nil // case TOKEN_EMPTY_STRING: // node[key] = "" // default: // node[key] = oJsonDecode.dictionaries[value] // } // } // } // return node, nil // } // return nil, errors.New("jsonpack 解析错误, 未知符号") // }