q5/xobject.go
aozhiwei e21d2e3b5d 1
2020-10-28 19:18:47 +08:00

214 lines
4.3 KiB
Go

package q5
import (
"encoding/json"
)
const (
XOT_SIMPLE = 0
XOT_ARRAY = iota
XOT_OBJECT = iota
)
type XObject struct {
_type int8
_val interface{}
}
func NewXoFromJsonStr(jsonStr string) *XObject {
p := new(XObject)
if p.readFromJsonString(jsonStr) {
return p
} else {
return nil
}
}
func NewXoString(val string) *XObject {
p := new(XObject)
p._type = XOT_SIMPLE
p._val = NewXString(val)
return p
}
func (this *XObject) Size() int {
if (this._type == XOT_ARRAY) {
array := this._val.([]*XObject)
return len(array)
} else {
panic("XObject.Size type error")
return 0
}
}
func (this *XObject) reset() {
this._type = XOT_SIMPLE
this._val = NewXUndefined()
}
func (this *XObject) GetType() int8 {
return this._type
}
func (this *XObject) IsSimple() bool {
return this.GetType() == XOT_SIMPLE
}
func (this *XObject) IsArray() bool {
return this.GetType() == XOT_ARRAY
}
func (this *XObject) IsObject() bool {
return this.GetType() == XOT_OBJECT
}
func (this *XObject) AsXValue() *XValue {
if this._type == XOT_SIMPLE {
if this._val == nil {
this._val = NewXUndefined()
}
return this._val.(*XValue)
} else {
panic("XObject.AsXValue type error")
return NewXUndefined()
}
}
func (this *XObject) At(key string) *XObject {
if this._type == XOT_OBJECT {
object := this._val.(map[string]*XObject)
val, ok := object[key]
if ok {
return val
} else {
return nil
}
} else {
panic("XObject.At type error")
return nil
}
}
func (this *XObject) Index(index int32) *XObject {
if (this._type == XOT_ARRAY) {
array := this._val.([]*XObject)
return array[index]
} else {
panic("XObject.At type error")
return nil
}
}
func (this *XObject) HasKey(key string) bool {
if (this._type == XOT_OBJECT) {
object := this._val.(map[string]*XObject)
_, ok := object[key]
return ok
} else {
panic("XObject.HasKey type error")
return false
}
}
func (this *XObject) GetSimpleStr(key string, defVal string) string {
if this.IsObject() {
val := this.At(key)
if val != nil {
if val.IsSimple() {
return val.AsXValue().GetString()
} else {
return defVal
}
}
}
return defVal
}
func (this *XObject) readFromJsonString(data string) bool {
jsonType := JsonStrType(data)
if jsonType == JSON_OBJECT {
var rawJson map[string]interface{}
err := json.Unmarshal([]byte(data), &rawJson)
if err != nil {
return false
}
kvObj := make(map[string]*XObject)
for key, val := range rawJson {
xobj := new(XObject).fromInterface(val)
kvObj[key] = xobj
}
this._type = XOT_OBJECT
this._val = kvObj
return true
} else if jsonType == JSON_ARRAY {
var rawJson []interface{}
err := json.Unmarshal([]byte(data), &rawJson)
if err != nil {
return false
}
arrObj := make([]*XObject, len(rawJson))
this._type = XOT_ARRAY
this._val = arrObj
for index, val := range rawJson {
xobj := new(XObject).fromInterface(val)
arrObj[index] = xobj
}
return true
}
return false
}
func (this *XObject) ToJsonStr() string {
if this._type == XOT_ARRAY || this._type == XOT_OBJECT {
jsonObj, _ := json.Marshal(this.ToInterface())
return string(jsonObj)
} else {
return "{}"
}
}
func (this *XObject) ToInterface() interface{} {
if this._type == XOT_ARRAY {
array := this._val.([]*XObject)
arrObj := make([]interface{}, len(array))
for index, val := range array {
arrObj[index] = val.ToInterface()
}
return arrObj
} else if this._type == XOT_OBJECT {
kvObj := this._val.(map[string]*XObject)
object := make(map[string]interface{})
for key, val := range kvObj {
object[key] = val.ToInterface()
}
return object
}
return this.AsXValue().ToJsonInterface()
}
func (this *XObject) fromInterface(iVal interface{}) *XObject {
if array, ok := iVal.([]interface{}); ok {
arrObj := make([]*XObject, len(array))
for index, val := range array {
arrObj[index] = new(XObject).fromInterface(val)
}
this._type = XOT_ARRAY
this._val = arrObj
} else if object, ok := iVal.(map[string]interface{}); ok {
kvObj := make(map[string]*XObject)
for key, val := range object {
kvObj[key] = new(XObject).fromInterface(val)
}
this._type = XOT_OBJECT
this._val = kvObj
} else {
this._type = XOT_SIMPLE
this._val = NewXUndefined()
if !this.AsXValue().TryFromInterface(iVal) {
panic("XObject.fromInterface type error2")
}
}
return this
}