mirror of
https://gitee.com/energye/energy.git
synced 2024-12-05 05:08:17 +08:00
635 lines
12 KiB
Go
635 lines
12 KiB
Go
//----------------------------------------
|
||
//
|
||
// 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
|
||
}
|