package q5 import ( "reflect" "net/url" "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 if (this._type == XOT_OBJECT) { object := this._val.(map[string]*XObject) return len(object) } 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) ToUrlEncodedStr() string { if this.IsObject() { u := url.Values{} kvObj := this._val.(map[string]*XObject) for key, val := range kvObj { u.Set(key, val.AsXValue().GetString()) } return u.Encode() } 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 type" + reflect.TypeOf(iVal).String()) } } return this }