energy/pkgs/json/json.go
2023-03-10 14:42:15 +08:00

635 lines
12 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//----------------------------------------
//
// Copyright © yanghy. All Rights Reserved.
//
// Licensed under Apache License Version 2.0, January 2004
//
// https://www.apache.org/licenses/LICENSE-2.0
//
//----------------------------------------
package json
import (
"github.com/energye/energy/common"
. "github.com/energye/energy/consts"
jsoniter "github.com/json-iterator/go"
"reflect"
"strconv"
)
type IBaseJSON interface {
Size() int
Type() GO_VALUE_TYPE
Data() any
String() string
Int() int
UInt() uint
Bytes() []byte
Float() float64
Bool() bool
Map() IJSONMap
Array() IJSONArray
IsString() bool
IsInt() bool
IsUInt() bool
IsBytes() bool
IsFloat() bool
IsBool() bool
IsMap() bool
IsArray() bool
}
type IJSONArray interface {
IBaseJSON
Add(value any)
RemoveByIndex(index int)
StringByIndex(index int) string
IntByIndex(index int) int
UIntByIndex(index int) uint
BytesByIndex(index int) []byte
FloatByIndex(index int) float64
BoolByIndex(index int) bool
ArrayByIndex(index int) IJSONArray
MapByIndex(index int) IJSONMap
GetByIndex(index int) IJSON
}
type IJSONMap interface {
IBaseJSON
Set(key, value string)
RemoveByKey(key string)
StringByKey(key string) string
IntByKey(key string) int
UIntByKey(key string) uint
BytesByKey(key string) []byte
FloatByKey(key string) float64
BoolByKey(key string) bool
ArrayByKey(key string) IJSONArray
MapByKey(key string) IJSONMap
GetByKey(key string) IJSON
Keys() []string
}
// IJSON IPC参数 数组形式
type IJSON interface {
IJSONArray
IJSONMap
}
type JSON struct {
T GO_VALUE_TYPE // type
S int // size
V any // value
}
// NewJSON 返回 JSON 对象IJSONArray or IJSONMap
func NewJSON(data []byte) IJSON {
if data == nil {
return nil
}
var v any
if err := jsoniter.Unmarshal(data, &v); err == nil {
rv := reflect.ValueOf(v)
switch rv.Kind() {
case reflect.Slice:
if v, ok := v.([]any); ok {
return &JSON{T: GO_VALUE_SLICE, V: v, S: len(v)}
}
case reflect.Map:
if v, ok := v.(map[string]any); ok {
return &JSON{T: GO_VALUE_MAP, V: v, S: len(v)}
}
}
}
return nil
}
// NewJSONArray 字节JSONArray/数组/切片 转换
func NewJSONArray(value any) IJSONArray {
if value != nil {
// 如果 []byte 就必须是 字节JSONArray
switch value.(type) {
case []byte:
if v := NewJSON(value.([]byte)); v != nil {
return v.Array()
} else {
return nil
}
}
rv := reflect.ValueOf(value)
if rv.Kind() != reflect.Slice && rv.Kind() != reflect.Array {
return nil
}
//目的是为了转为any类型
if byt, err := jsoniter.Marshal(value); err == nil {
var v []any
if err = jsoniter.Unmarshal(byt, &v); err == nil {
return &JSON{T: GO_VALUE_SLICE, V: v, S: len(v)}
}
}
}
return nil
}
// NewJSONMap 字节JSONObject/结构/Map 转换
func NewJSONMap(value any) IJSONMap {
if value != nil {
// 如果 []byte 就必须是 字节JSONObject
switch value.(type) {
case []byte:
if v := NewJSON(value.([]byte)); v != nil {
return v.Map()
} else {
return nil
}
}
rv := reflect.ValueOf(value)
kind := rv.Kind()
if kind != reflect.Map && kind != reflect.Struct {
return nil
}
//目的是为了转为any类型
if byt, err := jsoniter.Marshal(value); err == nil {
var v map[string]any
if err = jsoniter.Unmarshal(byt, &v); err == nil {
return &JSON{T: GO_VALUE_MAP, V: v, S: len(v)}
}
}
}
return nil
}
func (m *JSON) Size() int {
return m.S
}
func (m *JSON) Type() GO_VALUE_TYPE {
return m.T
}
func (m *JSON) Data() any {
return m.V
}
func (m *JSON) Add(value any) {
if m.IsArray() {
m.V = append(m.V.([]any), value)
m.S++
}
}
func (m *JSON) RemoveByIndex(index int) {
if m.IsArray() && index >= 0 && index < m.S {
v := m.V.([]any)
m.V = append(v[:index], v[index+1:]...)
m.S--
}
}
func (m *JSON) StringByIndex(index int) string {
if m.IsArray() && index < m.S {
if r, ok := m.V.([]any)[index].(string); ok {
return r
}
}
return ""
}
func (m *JSON) IntByIndex(index int) int {
if m.IsArray() && index < m.S {
return m.toInt(m.V.([]any)[index])
}
return 0
}
func (m *JSON) UIntByIndex(index int) uint {
if m.IsArray() && index < m.S {
return m.toUInt(m.V.([]any)[index])
}
return 0
}
func (m *JSON) BytesByIndex(index int) []byte {
if m.IsArray() && index < m.S {
return m.toBytes(m.V.([]any)[index])
}
return nil
}
func (m *JSON) FloatByIndex(index int) float64 {
if m.IsArray() && index < m.S {
return m.toFloat64(m.V.([]any)[index])
}
return 0
}
func (m *JSON) BoolByIndex(index int) bool {
if m.IsArray() && index < m.S {
s := m.V.([]any)[index]
switch s.(type) {
case bool:
return s.(bool)
}
}
return false
}
func (m *JSON) ArrayByIndex(index int) IJSONArray {
if m.IsArray() && index < m.S {
if v, ok := m.V.([]any)[index].([]any); ok {
return &JSON{T: GO_VALUE_SLICE, V: v, S: len(v)}
}
}
return nil
}
func (m *JSON) MapByIndex(index int) IJSONMap {
if m.IsArray() && index < m.S {
if v, ok := m.V.([]any)[index].(map[string]any); ok {
return &JSON{T: GO_VALUE_MAP, V: v, S: len(v)}
}
}
return nil
}
func (m *JSON) GetByIndex(index int) IJSON {
if m.IsArray() && index < m.S {
s := m.V.([]any)[index]
switch s.(type) {
case string:
if r, ok := s.(string); ok {
return &JSON{T: GO_VALUE_STRING, V: r, S: len(r)}
}
case int, int8, int16, int32, int64:
if s := m.IntByIndex(index); s != 0 {
return &JSON{T: GO_VALUE_INT, V: s, S: strconv.IntSize}
}
case uint, uint8, uint16, uint32, uint64:
if s := m.UIntByIndex(index); s != 0 {
return &JSON{T: GO_VALUE_UINT, V: s, S: strconv.IntSize}
}
case []byte:
if s := m.BytesByIndex(index); s != nil {
return &JSON{T: GO_VALUE_SLICE_BYTE, V: s, S: len(s)}
}
case float32, float64:
if s := m.FloatByIndex(index); s != 0 {
return &JSON{T: GO_VALUE_FLOAT64, V: s, S: 8}
}
case bool:
return &JSON{T: GO_VALUE_BOOL, V: m.BoolByIndex(index), S: 1}
case []any:
if index < m.S {
if v, ok := m.V.([]any)[index].([]any); ok {
return &JSON{T: GO_VALUE_SLICE, V: v, S: len(v)}
}
}
case map[string]any:
if v, ok := s.(map[string]any); ok {
return &JSON{T: GO_VALUE_MAP, V: v, S: len(v)}
}
}
}
return nil
}
func (m *JSON) Set(key, value string) {
if m.IsMap() {
m.V.(map[string]any)[key] = value
m.S++
}
}
func (m *JSON) RemoveByKey(key string) {
if m.IsMap() {
if _, ok := m.V.(map[string]any)[key]; ok {
delete(m.V.(map[string]any), key)
m.S--
}
}
}
func (m *JSON) StringByKey(key string) string {
if m.IsMap() {
if r, ok := m.V.(map[string]any)[key].(string); ok {
return r
}
}
return ""
}
func (m *JSON) IntByKey(key string) int {
if m.IsMap() {
return m.toInt(m.V.(map[string]any)[key])
}
return 0
}
func (m *JSON) UIntByKey(key string) uint {
if m.IsMap() {
return m.toUInt(m.V.(map[string]any)[key])
}
return 0
}
func (m *JSON) BytesByKey(key string) []byte {
if m.IsMap() {
return m.toBytes(m.V.(map[string]any)[key])
}
return nil
}
func (m *JSON) FloatByKey(key string) float64 {
if m.IsMap() {
return m.toFloat64(m.V.(map[string]any)[key])
}
return 0
}
func (m *JSON) BoolByKey(key string) bool {
if m.IsMap() {
if s, ok := m.V.(map[string]any)[key].(bool); ok {
return s
}
}
return false
}
func (m *JSON) ArrayByKey(key string) IJSONArray {
if m.IsMap() {
if v, ok := m.V.(map[string]any)[key].([]any); ok {
return &JSON{T: GO_VALUE_SLICE, V: v, S: len(v)}
}
}
return nil
}
func (m *JSON) MapByKey(key string) IJSONMap {
if m.IsMap() {
if v, ok := m.V.(map[string]any)[key].(map[string]any); ok {
return &JSON{T: GO_VALUE_MAP, V: v, S: len(v)}
}
}
return nil
}
func (m *JSON) GetByKey(key string) IJSON {
if m.IsMap() {
s := m.V.(map[string]any)[key]
switch s.(type) {
case string:
if r, ok := s.(string); ok {
return &JSON{T: GO_VALUE_STRING, V: r, S: len(r)}
}
case int, int8, int16, int32, int64:
if s := m.IntByKey(key); s != 0 {
return &JSON{T: GO_VALUE_INT, V: s, S: strconv.IntSize}
}
case uint, uint8, uint16, uint32, uint64:
if s := m.UIntByKey(key); s != 0 {
return &JSON{T: GO_VALUE_UINT, V: s, S: strconv.IntSize}
}
case []byte:
if s := m.BytesByKey(key); s != nil {
return &JSON{T: GO_VALUE_SLICE_BYTE, V: s, S: len(s)}
}
case float32, float64:
if s := m.FloatByKey(key); s != 0 {
return &JSON{T: GO_VALUE_FLOAT64, V: s, S: 8}
}
case bool:
return &JSON{T: GO_VALUE_BOOL, V: m.BytesByKey(key), S: 1}
case []any:
if v, ok := m.V.(map[string]any)[key].([]any); ok {
return &JSON{T: GO_VALUE_SLICE, V: v, S: len(v)}
}
case map[string]any:
if v, ok := s.(map[string]any); ok {
return &JSON{T: GO_VALUE_MAP, V: v, S: len(v)}
}
}
}
return nil
}
func (m *JSON) String() string {
if m.IsString() {
return m.V.(string)
}
return ""
}
func (m *JSON) Int() int {
return m.toInt(m.V)
}
func (m *JSON) UInt() uint {
return m.toUInt(m.V)
}
func (m *JSON) Bytes() []byte {
if m.IsBytes() {
return m.V.([]byte)
}
return nil
}
func (m *JSON) Float() float64 {
return m.toFloat64(m.V)
}
func (m *JSON) Bool() bool {
if m.IsBool() {
return m.V.(bool)
}
return false
}
func (m *JSON) Map() IJSONMap {
if m.IsMap() {
return m
}
return nil
}
func (m *JSON) Array() IJSONArray {
if m.IsArray() {
return m
}
return nil
}
func (m *JSON) toBytes(s any) []byte {
switch s.(type) {
case []byte:
return s.([]byte)
case string:
return []byte(s.(string))
case bool:
return []byte{common.BoolToByte(s.(bool))}
case float32:
return common.Float32ToBytes(s.(float32))
case float64:
return common.Float64ToBytes(s.(float64))
case int:
return common.IntToBytes(s.(int))
case int8:
return common.Int8ToBytes(s.(int8))
case int16:
return common.Int16ToBytes(s.(int16))
case int32:
return common.Int32ToBytes(s.(int32))
case int64:
return common.Int64ToBytes(s.(int64))
case uint:
return common.UIntToBytes(s.(uint))
case uint8:
return common.UInt8ToBytes(s.(uint8))
case uint16:
return common.UInt16ToBytes(s.(uint16))
case uint32:
return common.UInt32ToBytes(s.(uint32))
case uint64:
return common.UInt64ToBytes(s.(uint64))
default: // slice or map or other
if r, err := jsoniter.Marshal(s); err == nil {
return r
}
}
return nil
}
func (m *JSON) Keys() []string {
if m.IsMap() {
var result []string
for key, _ := range m.V.(map[string]any) {
result = append(result, key)
}
return result
}
return nil
}
func (m *JSON) IsString() bool {
return m.T == GO_VALUE_STRING
}
func (m *JSON) IsInt() bool {
return m.T == GO_VALUE_INT
}
func (m *JSON) IsUInt() bool {
return m.T == GO_VALUE_UINT
}
func (m *JSON) IsBytes() bool {
return m.T == GO_VALUE_SLICE_BYTE
}
func (m *JSON) IsFloat() bool {
return m.T == GO_VALUE_FLOAT64
}
func (m *JSON) IsBool() bool {
return m.T == GO_VALUE_BOOL
}
func (m *JSON) IsMap() bool {
return m.T == GO_VALUE_MAP
}
func (m *JSON) IsArray() bool {
return m.T == GO_VALUE_SLICE
}
func (m *JSON) toFloat64(s any) float64 {
switch s.(type) {
case float32:
return float64(s.(float32))
case float64:
return s.(float64)
case int:
return float64(s.(int))
case int8:
return float64(s.(int8))
case int16:
return float64(s.(int16))
case int32:
return float64(s.(int32))
case int64:
return float64(s.(int64))
case uint:
return float64(s.(uint))
case uint8:
return float64(s.(uint8))
case uint16:
return float64(s.(uint16))
case uint32:
return float64(s.(uint32))
case uint64:
return float64(s.(uint64))
}
return 0
}
func (m *JSON) toInt(s any) int {
switch s.(type) {
case float32:
return int(s.(float32))
case float64:
return int(s.(float64))
case int:
return s.(int)
case int8:
return int(s.(int8))
case int16:
return int(s.(int16))
case int32:
return int(s.(int32))
case int64:
return int(s.(int64))
case uint:
return int(s.(uint))
case uint8:
return int(s.(uint8))
case uint16:
return int(s.(uint16))
case uint32:
return int(s.(uint32))
case uint64:
return int(s.(uint64))
}
return 0
}
func (m *JSON) toUInt(s any) uint {
switch s.(type) {
case float32:
return uint(s.(float32))
case float64:
return uint(s.(float64))
case int:
return uint(s.(int))
case int8:
return uint(s.(int8))
case int16:
return uint(s.(int16))
case int32:
return uint(s.(int32))
case int64:
return uint(s.(int64))
case uint:
return s.(uint)
case uint8:
return uint(s.(uint8))
case uint16:
return uint(s.(uint16))
case uint32:
return uint(s.(uint32))
case uint64:
return uint(s.(uint64))
}
return 0
}