diff --git a/mutable_xobject.go b/mutable_xobject.go index 41f89af..101ed7e 100644 --- a/mutable_xobject.go +++ b/mutable_xobject.go @@ -5,32 +5,40 @@ type MutableXObject struct { } func NewMxoArray() *MutableXObject { - p:= new(MutableXObject) + p := new(MutableXObject) return p } func NewMxoObject() *MutableXObject { - p:= new(MutableXObject) + p := new(MutableXObject) return p } func (this *MutableXObject) PushXValue(val *XValue) *MutableXObject{ + this.PushXObject(val.AsXObject()) return this } -func (this *MutableXObject) PushMutableXObject(val MutableXObject) *MutableXObject{ +func (this *MutableXObject) PushXObject(val *XObject) *MutableXObject{ + if this.XObject.GetType() != XOT_ARRAY { + panic("MutableXObject.PushXvalue type error") + } + array := this.XObject._val.(*[]*XObject) + this.XObject._val = append(*array, val) return this } func (this *MutableXObject) SetXValue(key string, val *XValue) *MutableXObject{ + this.SetXObject(key, val.AsXObject()) return this } func (this *MutableXObject) SetXObject(key string, val *XObject) *MutableXObject{ - return this -} - -func (this *MutableXObject) SetMutableXObject(key string, val *MutableXObject) *MutableXObject{ + if this.XObject.GetType() != XOT_OBJECT { + panic("MutableXObject.PushXvalue type error") + } + kvObj := this.XObject._val.(*(map[string]*XObject)) + (*kvObj)[key] = val return this } diff --git a/xobject.go b/xobject.go index 2122b76..3fb1aaa 100644 --- a/xobject.go +++ b/xobject.go @@ -1,5 +1,9 @@ package q5 +import ( + "encoding/json" +) + const ( XOT_SIMPLE = 0 XOT_ARRAY = iota @@ -11,11 +15,19 @@ type XObject struct { _val interface{} } -func (this *XObject) Size(key interface{}) int32 { - return 0 +func (this *XObject) Size(key interface{}) 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 = nil } func (this *XObject) GetType() int8{ @@ -23,23 +35,52 @@ func (this *XObject) GetType() int8{ } func (this *XObject) AsXValue() *XValue { - return nil + 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 interface{}) *XObject { - return nil +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) Get(key interface{}) *XValue { - 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 interface{}) bool { - return false -} - -func (this *XObject) ReadFromFile(fileName string) bool { - return false +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) ReadFromJsonFile(fileName string) bool { @@ -47,25 +88,71 @@ func (this *XObject) ReadFromJsonFile(fileName string) bool { } func (this *XObject) ReadFromJsonString(data string) bool { - return false -} - -func (this *XObject) ReadFromXmlFile(fileName string) bool { - return false -} - -func (this *XObject) ReadFromXmlString(data string) bool { - return false -} - -func (this *XObject) ReadFromUrlQueryString(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 + } 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 false } func (this *XObject) ToJsonStr() string { - return "" + if this._type == XOT_ARRAY || this._type == XOT_OBJECT { + jsonObj, _ := json.Marshal(this.ToInterface()) + return string(jsonObj) + } else { + return "{}" + } } -func (this *XObject) ToUrlEncodeSr() string { - 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(val interface{}) *XObject { + if this._type != XOT_SIMPLE { + panic("XObject.fromInterface type error1") + } + if !this.AsXValue().TryFromInterface(val) { + panic("XObject.fromInterface type error2") + } + return this } diff --git a/xvalue.go b/xvalue.go index 5b2ae7a..04befc8 100644 --- a/xvalue.go +++ b/xvalue.go @@ -13,12 +13,18 @@ const ( XVT_USERDATA = iota ) -type XValue struct -{ +type XValue struct { _type int8 _val interface{} } +func NewXUndefined() *XValue { + p := new(XValue) + p._type = XVT_UNDEFINED + p._val = nil + return p +} + func NewXInt32(val int32) *XValue { p := new(XValue) p.SetInt32(val) @@ -212,3 +218,59 @@ func (this *XValue) GetUserData() interface{} { return nil } } + +func (this *XValue) ToJsonInterface() interface{} { + switch this._type { + case XVT_INT: + int64Val := this.GetInt64() + if uint64(int64Val) > (1 << 60) { + return this.GetString() + } else { + return this.GetInt64() + } + case XVT_FLOAT: + return this.GetFloat64() + case XVT_STRING: + return this.GetString() + case XVT_BYTES: + return this.GetString() + default: + panic("XValue.ToJsonInterface type error") + return "" + } +} + +func (this *XValue) TryFromInterface(val interface{}) bool { + switch val.(type) { + case int8: + this.SetInt8(val.(int8)) + case int16: + this.SetInt16(val.(int16)) + case int32: + this.SetInt32(val.(int32)) + case int64: + this.SetInt64(val.(int64)) + case uint8: + this.SetUInt8(val.(uint8)) + case uint16: + this.SetUInt16(val.(uint16)) + case uint32: + this.SetUInt32(val.(uint32)) + case float32: + this.SetFloat32(val.(float32)) + case float64: + this.SetFloat64(val.(float64)) + case string: + this.SetString(val.(string)) + default: + return false + } + return true +} + +func (this *XValue) AsXObject() *XObject { + xobj := new(XObject) + xobj._type = XOT_SIMPLE + xobj._val = this + return xobj +}