diff --git a/sig.go b/sig.go index 6b9cadb..5829f57 100644 --- a/sig.go +++ b/sig.go @@ -1,6 +1,9 @@ package dbus import ( + "bytes" + "encoding/gob" + "encoding/json" "fmt" "reflect" "strings" @@ -164,6 +167,33 @@ func (s Signature) String() string { return s.str } +// MarshalJSON is to implement the interface json.Marshal +func (s Signature) MarshalJSON() ([]byte, error) { + return json.Marshal(s.String()) +} + +// UnmarshalJSON is to implement the interface json.Unmarshal +func (s *Signature) UnmarshalJSON(bytes []byte) error { + s.str = string(bytes) + return nil +} + +// GobEncode is to implement the interface Encode in gob +func (s Signature) GobEncode() ([]byte, error) { + var buffer bytes.Buffer + encoder := gob.NewEncoder(&buffer) + if err := encoder.Encode(s.String()); err != nil { + return nil, err + } + return buffer.Bytes(), nil +} + +// GobDecode is to implement the interface Decode in gob +func (s *Signature) GobDecode(bytes []byte) error { + s.str = string(bytes) + return nil +} + // A SignatureError indicates that a signature passed to a function or received // on a connection is not a valid signature. type SignatureError struct { diff --git a/variant.go b/variant.go index f1e81f3..fd98918 100644 --- a/variant.go +++ b/variant.go @@ -2,6 +2,8 @@ package dbus import ( "bytes" + "encoding/gob" + "encoding/json" "fmt" "reflect" "sort" @@ -148,3 +150,73 @@ func (v Variant) Value() interface{} { func (v Variant) Store(value interface{}) error { return storeInterfaces(v.value, value) } + +// toMap trans the Variant to a map +func (v Variant) toMap() map[string]string { + mapstr := map[string]string{} + mapstr["sig"] = v.sig.String() + + s, _ := v.format() + mapstr["value"] = s + + return mapstr +} + +// parseMap parses a Variant from a map +func (v *Variant) parseMap(mapstr map[string]string) error { + if sigStr, ok := mapstr["sig"]; ok { + sig := Signature{sigStr} + + if vstr, ok := mapstr["value"]; ok { + v1, err := ParseVariant(vstr, sig) + if err != nil { + return err + } + v.sig = v1.sig + v.value = v1.value + } + } + return nil +} + +// MarshalJSON is to implement the interface json.Marshal +func (v Variant) MarshalJSON() ([]byte, error) { + mapstr := v.toMap() + return json.Marshal(mapstr) +} + +// UnmarshalJSON is to implement the interface json.Unmarshal +func (v *Variant) UnmarshalJSON(bytes []byte) error { + var mapstr map[string]string + if err := json.Unmarshal(bytes, &mapstr); err != nil { + return err + } + return v.parseMap(mapstr) +} + +// GobEncode is to implement the interface Encode in gob +func (v Variant) GobEncode() ([]byte, error) { + var buffer bytes.Buffer + encoder := gob.NewEncoder(&buffer) + + mapstr := v.toMap() + + if err := encoder.Encode(mapstr); err != nil { + return nil, err + } + + return buffer.Bytes(), nil +} + +// GobDecode is to implement the interface Decode in gob +func (v *Variant) GobDecode(jsonBytes []byte) error { + buffer := bytes.NewBuffer(jsonBytes) + decoder := gob.NewDecoder(buffer) + + var mapstr map[string]string + if err := decoder.Decode(&mapstr); err != nil { + return err + } + + return v.parseMap(mapstr) +} diff --git a/variant_test.go b/variant_test.go index c9dce3e..08dda1a 100644 --- a/variant_test.go +++ b/variant_test.go @@ -1,7 +1,14 @@ package dbus -import "reflect" -import "testing" +import ( + "bytes" + "encoding/gob" + "encoding/json" + "fmt" + "reflect" + "strings" + "testing" +) var variantFormatTests = []struct { v interface{} @@ -90,3 +97,174 @@ func TestVariantStore(t *testing.T) { } } + +func TestJson(t *testing.T) { + str := "uint64 123456789" + v, err := ParseVariant(str, Signature{}) + if err != nil { + t.Fatal(err) + } + bytes, err := json.Marshal(v) + if err != nil { + t.Fatal(err) + } + if string(bytes) == "{}" { + t.Fatal("Can't marshal the variant value!") + } + + var v1 Variant + err = json.Unmarshal(bytes, &v1) + if err != nil { + t.Fatal(err) + } + if v1.value == nil { + t.Fatal("Can't unmarshal the variant value!") + } + if v1.value != v.value { + t.Fatalf("expected %s, got %s\n", v.value, v1.value) + } +} + +func TestJsonSimple(t *testing.T) { + cases := []struct { + name string + val interface{} + }{ + { + name: "int", + val: 100, + }, + { + name: "float", + val: 100.3, + }, + { + name: "string", + val: "lfbzhm", + }, + { + name: "byte", + val: 'l', + }, + } + for _, tc := range cases { + val := tc.val + v := MakeVariant(val) + bytes, err := json.Marshal(v) + if err != nil { + t.Fatal(err) + } + if string(bytes) == "{}" { + t.Fatal("Can't marshal the variant value!") + } + + var v1 Variant + err = json.Unmarshal(bytes, &v1) + if err != nil { + t.Fatal(err) + } + if v1.value == nil { + t.Fatal("Can't unmarshal the variant value!") + } + + str, _ := v1.format() + valstr := fmt.Sprintf("%v", val) + if !strings.Contains(str, valstr) { + t.Fatalf("expected %v, got %v\n", valstr, str) + } + } +} + +func TestJsonArray(t *testing.T) { + arr := []string{"lfb", "zhm", "nn", "tt", "hello"} + v := MakeVariant(arr) + bytes, err := json.Marshal(v) + if err != nil { + t.Fatal(err) + } + if string(bytes) == "{}" { + t.Fatal("Can't marshal the variant value!") + } + + var v1 Variant + err = json.Unmarshal(bytes, &v1) + if err != nil { + t.Fatal(err) + } + if v1.value == nil { + t.Fatal("Can't unmarshal the variant value!") + } + + var arr1 []string + err = v1.Store(&arr1) + if err != nil { + t.Fatal(err) + } + if len(arr1) != len(arr) { + t.Fatalf("expected %v, got %v\n", v.value, v1.value) + } +} + +func TestJsonMap(t *testing.T) { + mapstr := map[string]string{ + "lfb": "zhm", + "nn": "tt", + } + v := MakeVariant(mapstr) + bytes, err := json.Marshal(v) + if err != nil { + t.Fatal(err) + } + if string(bytes) == "{}" { + t.Fatal("Can't marshal the variant value!") + } + + var v1 Variant + err = json.Unmarshal(bytes, &v1) + if err != nil { + t.Fatal(err) + } + if v1.value == nil { + t.Fatal("Can't unmarshal the variant value!") + } + + var map1 map[string]string + err = v1.Store(&map1) + if err != nil { + t.Fatal(err) + } + if len(map1) != len(mapstr) { + t.Fatalf("expected %v, got %v\n", v.value, v1.value) + } +} + +func TestGob(t *testing.T) { + str := "uint64 123456789" + v, err := ParseVariant(str, Signature{}) + if err != nil { + t.Fatal(err) + } + + var buffer bytes.Buffer + encoder := gob.NewEncoder(&buffer) + err = encoder.Encode(v) + if err != nil { + t.Fatal(err) + } + if string(buffer.Bytes()) == "{}" { + t.Fatal("Can't marshal the variant value!") + } + + decoder := gob.NewDecoder(&buffer) + var v1 Variant + err = decoder.Decode(&v1) + if err != nil { + t.Fatal(err) + } + if v1.value == nil { + t.Fatal("Can't unmarshal the variant value!") + } + if v1.value != v.value { + t.Fatalf("expected %s, got %s\n", v.value, v1.value) + } +}