Merge pull request #19 from tripzero/master
[profile/ivi/automotive-message-broker.git] / lib / mappropertytype.hpp
1 #ifndef _MAPPROPERTYTYPE_H_
2 #define _MAPPROPERTYTYPE_H_
3
4
5 #include "abstractpropertytype.h"
6
7 #include <map>
8 #include <debugout.h>
9 #include <json/json.h>
10
11 template <class T, class N>
12 class MapPropertyType: public AbstractPropertyType
13 {
14 public:
15         MapPropertyType(std::string propertyName):AbstractPropertyType(propertyName){}
16
17         void append(T  key, N  value)
18         {
19                 appendPriv(key,value);
20         }
21
22         AbstractPropertyType* copy()
23         {
24                 MapPropertyType<T,N> *t = new MapPropertyType<T,N>(name);
25
26                 t->setMap(mMap);
27                 t->timestamp = timestamp;
28                 t->sequence = sequence;
29                 t->sourceUuid = sourceUuid;
30                 t->name = name;
31                 t->zone = zone;
32
33                 return t;
34         }
35
36         std::string toString() const
37         {
38                 std::stringstream str;
39
40                 str<<"{";
41
42                 for(auto itr = mMap.begin(); itr != mMap.end(); itr++)
43                 {
44                         if(str.str() != "{")
45                                 str << ", ";
46
47                          auto t = *itr;
48
49                          str <<"'"<< t.first.toString() <<"':'"<<t.second.toString()<<"'";
50                 }
51
52                 str << "}";
53
54                 return str.str();
55         }
56
57         void fromString(std::string str)
58         {
59                 json_object *rootobject;
60                 json_tokener *tokener = json_tokener_new();
61                 enum json_tokener_error err;
62                 do
63                 {
64                         rootobject = json_tokener_parse_ex(tokener, str.c_str(),str.length());
65                 } while ((err = json_tokener_get_error(tokener)) == json_tokener_continue);
66                 if (err != json_tokener_success)
67                 {
68                         fprintf(stderr, "Error: %s\n", json_tokener_error_desc(err));
69                         // Handle errors, as appropriate for your application.
70                 }
71                 if (tokener->char_offset < str.length()) // XXX shouldn't access internal fields
72                 {
73                         // Handle extra characters after parsed object as desired.
74                         // e.g. issue an error, parse another object from that point, etc...
75                 }
76                 //Good!
77
78                 clear();
79
80                 json_object_object_foreach(rootobject, key, val)
81                 {
82                         T one("", key);
83                         N two("", std::string(json_object_get_string(val)));
84                         append(one,two);
85
86                 }
87                 json_object_put(rootobject);
88                 json_tokener_free(tokener);
89
90         }
91
92         GVariant* toVariant()
93         {
94                 GVariantBuilder params;
95                 g_variant_builder_init(&params, G_VARIANT_TYPE_DICTIONARY);
96                 for(auto itr = mMap.begin(); itr != mMap.end(); itr++)
97                 {
98                         auto &foo = (*itr).first;
99                         g_variant_builder_add(&params,"{?*}",const_cast<T&>(foo).toVariant(),(*itr).second.toVariant());
100                 }
101
102                 GVariant* var =  g_variant_builder_end(&params);
103                 g_assert(var);
104                 return var;
105         }
106
107         void fromVariant(GVariant* variant)
108         {
109                 clear();
110                 /// TODO: fill this in
111                 gsize dictsize = g_variant_n_children(variant);
112                 for (int i=0;i<dictsize;i++)
113                 {
114                         GVariant *childvariant = g_variant_get_child_value(variant,i);
115                         gsize dictvalsize = g_variant_n_children(childvariant);
116                         if (dictvalsize == 2)
117                         {
118                                 //It is a dictionary entry
119                                 GVariant *keyvariant = g_variant_get_child_value(childvariant,0);
120                                 GVariant *valvariant = g_variant_get_child_value(childvariant,1);
121                                 T t = T();
122                                 t.fromVariant(keyvariant);
123                                 N n = N();
124                                 n.fromVariant(valvariant);
125                                 appendPriv(t,n);
126                         }
127                 }
128                 
129         }
130
131         void setMap(std::map<T, N> m)
132         {
133                 mMap = m;
134         }
135
136 private:
137
138         void clear()
139         {
140                 mMap.clear();
141         }
142
143         void appendPriv(T  key, N  value)
144         {
145                 mMap[key] = value;
146         }
147
148         std::map<T, N> mMap;
149 };
150
151
152 #endif