added automatic timeout for get() and set() commands
[profile/ivi/automotive-message-broker.git] / lib / abstractpropertytype.h
1 /*
2         Copyright (C) 2012  Intel Corporation
3
4         This library is free software; you can redistribute it and/or
5         modify it under the terms of the GNU Lesser General Public
6         License as published by the Free Software Foundation; either
7         version 2.1 of the License, or (at your option) any later version.
8
9         This library is distributed in the hope that it will be useful,
10         but WITHOUT ANY WARRANTY; without even the implied warranty of
11         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12         Lesser General Public License for more details.
13
14         You should have received a copy of the GNU Lesser General Public
15         License along with this library; if not, write to the Free Software
16         Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19 #ifndef _ABSTRACTPROPERTYTYPE_H_
20 #define _ABSTRACTPROPERTYTYPE_H_
21
22 #include <string>
23 #include <sstream>
24 #include <stdexcept>
25 #include <vector>
26 #include <iostream>
27 #include <boost/any.hpp>
28 #include <boost/lexical_cast.hpp>
29 #include <boost/utility.hpp>
30 #include <type_traits>
31 #include <glib.h>
32 #include <list>
33 #include "timestamp.h"
34 #include <debugout.h>
35 #include <boost/algorithm/string.hpp>
36
37 namespace Zone {
38 enum Type {
39         None = 0,
40         Driver = 1,
41         FrontMiddle = 1 << 1,
42         Passenger = 1 << 2,
43         LeftRear = 1 << 3,
44         MiddleRear = 1 << 4,
45         RightRear = 1 << 5
46 };
47 }
48
49 class AbstractPropertyType
50 {
51 public:
52         //AbstractPropertyType(): timestamp(-1), sequence(-1), zone(Zone::None), index(0) {}
53
54         AbstractPropertyType(std::string property): name(property), timestamp(-1), sequence(-1), zone(Zone::None), index(0) {}
55
56         virtual std::string toString() const = 0;
57
58         virtual void fromString(std::string)= 0;
59
60         virtual GVariant* toVariant() = 0;
61
62         virtual void fromVariant(GVariant*) = 0;
63
64         virtual AbstractPropertyType* copy() = 0;
65
66         bool operator == (AbstractPropertyType &other)
67         {
68                 std::string one = toString();
69                 std::string two = other.toString();
70                 return one == two;
71         }
72
73         bool operator != (AbstractPropertyType &other)
74         {
75                 std::string one = toString();
76                 std::string two = other.toString();
77                 return one != two;
78         }
79
80         std::string name;
81
82         double timestamp;
83
84         int32_t sequence;
85
86         std::string sourceUuid;
87
88         Zone::Type zone;
89
90         int index;
91
92         void setValue(boost::any val)
93         {
94                 mValue = val;
95                 timestamp = amb::currentTime();
96         }
97
98         template <typename T>
99         T value() const
100         {
101                 return boost::any_cast<T>(mValue);
102         }
103
104         boost::any anyValue()
105         {
106                 return mValue;
107         }
108
109 protected:
110
111         boost::any mValue;
112
113 };
114
115 template <typename T>
116 class GVS;
117
118 template <>
119 class GVS<int>
120 {
121 public:
122         static const char* signature() { return "i"; }
123
124         static char value(GVariant* v)
125         {
126                 return g_variant_get_int32(v);
127         }
128
129         static std::string stringize(std::string v)
130         {
131                 return v;
132         }
133 };
134
135 template <>
136 class GVS<double>
137 {
138 public:
139         static const char* signature() { return "d"; }
140
141         static double value(GVariant* v)
142         {
143                 return g_variant_get_double(v);
144         }
145         static std::string stringize(std::string v)
146         {
147                 return v;
148         }
149 };
150
151 template <>
152 class GVS<uint16_t>
153 {
154 public:
155         static const char* signature() { return "q"; }
156
157         static uint16_t value(GVariant* v)
158         {
159                 return g_variant_get_uint16(v);
160         }
161         static std::string stringize(std::string v)
162         {
163                 return v;
164         }
165 };
166
167 template <>
168 class GVS<int16_t>
169 {
170 public:
171         static const char* signature() { return "n"; }
172
173         static int16_t value(GVariant* v)
174         {
175                 return g_variant_get_int16(v);
176         }
177         static std::string stringize(std::string v)
178         {
179                 return v;
180         }
181 };
182
183 template <>
184 class GVS<char>
185 {
186 public:
187         static const char* signature() { return "y"; }
188
189         static char value(GVariant* v)
190         {
191                 return g_variant_get_byte(v);
192         }
193         static std::string stringize(std::string v)
194         {
195                 return v;
196         }
197 };
198
199 template <>
200 class GVS<uint32_t>
201 {
202 public:
203         static const char* signature() { return "u"; }
204
205         static uint32_t value(GVariant* v)
206         {
207                 return g_variant_get_uint32(v);
208         }
209         static std::string stringize(std::string v)
210         {
211                 return v;
212         }
213 };
214
215 template <>
216 class GVS<int64_t>
217 {
218 public:
219         static const char* signature() { return "x"; }
220
221         static int64_t value(GVariant* v)
222         {
223                 return g_variant_get_int64(v);
224         }
225         static std::string stringize(std::string v)
226         {
227                 return v;
228         }
229 };
230
231 template <>
232 class GVS<uint64_t>
233 {
234 public:
235         static const char* signature() { return "t"; }
236
237         static uint64_t value(GVariant* v)
238         {
239                 g_variant_get_uint64(v);
240         }
241         static std::string stringize(std::string v)
242         {
243                 return v;
244         }
245 };
246
247 template <>
248 class GVS<bool>
249 {
250 public:
251         static const char* signature() { return "b"; }
252
253         static bool value(GVariant *v)
254         {
255                 return g_variant_get_boolean(v);
256         }
257         static std::string stringize(std::string v)
258         {
259                 boost::algorithm::to_lower(v);
260                 return v == "true" ? "1":"0";
261         }
262 };
263
264
265 template <typename T>
266 class BasicPropertyType: public AbstractPropertyType
267 {
268 public:
269         BasicPropertyType(): AbstractPropertyType("")
270         {
271                 mValue = T();
272         }
273         BasicPropertyType(BasicPropertyType const &other)
274                 :AbstractPropertyType(other.name)
275         {
276                 setValue(other.value<T>());
277                 timestamp = other.timestamp;
278                 sequence = other.sequence;
279                 sourceUuid = other.sourceUuid;
280                 index = other.index;
281                 name = other.name;
282         }
283
284         BasicPropertyType & operator = (BasicPropertyType const & other)
285         {
286                 setValue(other.value<T>());
287                 timestamp = other.timestamp;
288                 sequence = other.sequence;
289                 sourceUuid = other.sourceUuid;
290                 index = other.index;
291                 name = other.name;
292
293                 return *this;
294         }
295
296         bool operator < (const BasicPropertyType<T>& other) const
297         {
298                 return value<T>() < other.value<T>();
299         }
300
301         bool operator > (const BasicPropertyType<T>& other) const
302         {
303                 return value<T>() > other.value<T>();
304         }
305
306         BasicPropertyType( T val)
307                 :AbstractPropertyType("")
308         {
309                 setValue(val);
310         }
311
312         BasicPropertyType( std::string propertyName, T val)
313                 :AbstractPropertyType(propertyName)
314         {
315                 setValue(val);
316         }
317
318         BasicPropertyType( std::string propertyName, std::string val)
319                 :AbstractPropertyType(propertyName)
320         {
321                 if(!val.empty() && val != "")
322                 {
323                         serialize<T>(val);
324                 }
325                 else setValue(T());
326         }
327
328         BasicPropertyType(std::string val)
329                 :AbstractPropertyType("")
330         {
331                 if(!val.empty() && val != "")
332                 {
333                         serialize<T>(val);
334                 }
335                 else setValue(T());
336         }
337
338         AbstractPropertyType* copy()
339         {
340                 return new BasicPropertyType<T>(*this);
341         }
342
343         void fromString(std::string val)
344         {
345                 if(!val.empty() && val != "")
346                 {
347                         serialize<T>(val);
348                 }
349         }
350
351         std::string toString() const
352         {
353                 std::stringstream stream;
354                 stream.precision(10);
355                 stream<<value<T>();
356
357                 return stream.str();
358         }
359
360         GVariant* toVariant()
361         {
362                 return serializeVariant<T>(value<T>());
363         }
364
365         void fromVariant(GVariant *v)
366         {
367                 setValue(deserializeVariant<T>(v));
368         }
369
370 private:
371
372         //GVariant* mVariant;
373
374         template <class N>
375         void serialize(std::string val,  typename std::enable_if<std::is_enum<N>::value, N>::type* = 0)
376         {
377                 int someTemp;
378
379                 std::stringstream stream(val);
380
381                 stream>>someTemp;
382                 setValue((N)someTemp);
383         }
384
385         template <class N>
386         void serialize(std::string  val,  typename std::enable_if<!std::is_enum<N>::value, N>::type* = 0)
387         {
388                 std::stringstream stream(GVS<T>::stringize(val));
389                 N someTemp;
390                 stream>>someTemp;
391                 setValue(someTemp);
392         }
393
394         template <class N>
395         GVariant* serializeVariant(T val, typename std::enable_if<std::is_enum<N>::value, N>::type* = 0)
396         {
397                 //mVariant = Glib::VariantBase(Glib::Variant<gint16>::create((int)val).gobj());
398
399                 return (g_variant_new("i",(int)val));
400         }
401
402         template <class N>
403         GVariant* serializeVariant(T val, typename std::enable_if<!std::is_enum<N>::value, N>::type* = 0)
404         {
405                 //mVariant = Glib::Variant<T>::create(val);
406                 //mVariant = g_variant_ref(g_variant_new(GVS<T>::signature(),val));
407                 return g_variant_new(GVS<T>::signature(),val);
408         }
409
410         template <class N>
411         T deserializeVariant(GVariant* v, typename std::enable_if<std::is_enum<N>::value, N>::type* = 0)
412         {
413 //              return (T)((Glib::Variant<int>::cast_dynamic<Glib::Variant<int> >(*v)).get());
414
415                 return (T)GVS<int>::value(v);
416         }
417
418         template <class N>
419         T deserializeVariant(GVariant* v, typename std::enable_if<!std::is_enum<N>::value, N>::type* = 0)
420         {
421                 //      return Glib::VariantBase::cast_dynamic<Glib::Variant<T> >(*v).get();
422                 return GVS<T>::value(v);
423         }
424 };
425
426 class StringPropertyType: public AbstractPropertyType
427 {
428 public:
429         StringPropertyType(std::string propertyName)
430                 :AbstractPropertyType(propertyName)
431         {
432
433         }
434
435         StringPropertyType(std::string propertyName, std::string val)
436                 :AbstractPropertyType(propertyName)
437         {
438                 setValue(val);
439         }
440
441         StringPropertyType(StringPropertyType const & other)
442         :AbstractPropertyType(other.name)
443         {
444                 setValue(other.value<std::string>());
445                 timestamp = other.timestamp;
446                 sequence = other.sequence;
447                 sourceUuid = other.sourceUuid;
448                 index = other.index;
449                 name = other.name;
450         }
451
452         StringPropertyType & operator = (StringPropertyType const & other)
453         {
454                 setValue(other.value<std::string>());
455                 timestamp = other.timestamp;
456                 sequence = other.sequence;
457                 sourceUuid = other.sourceUuid;
458                 index = other.index;
459                 name = other.name;
460
461                 return *this;
462         }
463
464         void fromString(std::string val)
465         {
466                 setValue(val);
467         }
468
469         AbstractPropertyType* copy()
470         {
471                 return new StringPropertyType(*this);
472         }
473
474         std::string toString() const
475         {
476                 return value<std::string>();
477         }
478
479         GVariant* toVariant()
480         {
481                 //mVariant = Glib::Variant<std::string>::create(toString());
482
483                 return g_variant_new_string(toString().c_str());
484
485         }
486
487         void fromVariant(GVariant *v)
488         {
489                 setValue(std::string(g_variant_get_string(v,NULL)));
490         }
491 };
492
493 template <class T>
494 class ListPropertyType: public AbstractPropertyType
495 {
496 public:
497
498         ListPropertyType(std::string propertyName)
499                 : AbstractPropertyType(propertyName), initialized(false)
500         {
501
502         }
503
504         ListPropertyType(std::string propertyName, AbstractPropertyType *value)
505                 : AbstractPropertyType(propertyName), initialized(false)
506         {
507                 appendPriv(value->copy());
508         }
509
510         ListPropertyType(ListPropertyType & other)
511                 :AbstractPropertyType(other.name),initialized(false)
512         {
513                 std::list<AbstractPropertyType*> l = other.list();
514                 for(auto itr = l.begin(); itr != l.end(); itr++)
515                 {
516                         append(*itr);
517                 }
518
519                 timestamp = other.timestamp;
520                 sequence = other.sequence;
521                 sourceUuid = other.sourceUuid;
522                 index = other.index;
523                 name = other.name;
524         }
525
526         ~ListPropertyType()
527         {
528                 for(auto itr = mList.begin(); itr != mList.end(); itr++)
529                 {
530                         delete *itr;
531                 }
532         }
533
534         /** append - appends a property to the list
535          * @arg property - property to be appended.  Property will be copied and owned by ListPropertyType.
536          * You are responsible for freeing property after append is called.
537          **/
538         void append(AbstractPropertyType* property)
539         {
540                 if(!initialized)
541                 {
542                         for(auto itr = mList.begin(); itr != mList.end(); itr++)
543                         {
544                                 AbstractPropertyType *p = *itr;
545                                 delete p;
546                         }
547                         mList.clear();
548                         initialized = true;
549                 }
550
551                 appendPriv(property->copy());
552         }
553
554         uint count()
555         {
556                 return mList.size();
557         }
558
559         AbstractPropertyType* copy()
560         {
561                 return new ListPropertyType(*this);
562         }
563
564         std::string toString() const
565         {
566                 std::string str = "[";
567
568                 for(auto itr = mList.begin(); itr != mList.end(); itr++)
569                 {
570                         if(str != "[")
571                                 str += ",";
572
573                         AbstractPropertyType* t = *itr;
574
575                         str += t->toString();
576                 }
577
578                 str += "]";
579
580                 return str;
581         }
582
583
584         void fromString(std::string str )
585         {
586                 if(!str.length())
587                         return;
588
589                 if(str[0] != '[' && str[str.length()-1] != ']')
590                 {
591                         return;
592                 }
593
594                 str = str.substr(1,str.length() - 2);
595
596                 std::vector<std::string> elements;
597
598                 std::istringstream f(str);
599
600                 std::string element;
601                 while(std::getline(f,element,','))
602                 {
603                         T *foo = new T(element);
604                         append (foo);
605
606                         delete foo;
607                 }
608         }
609
610
611         GVariant* toVariant()
612         {
613
614                 GVariantBuilder params;
615                 g_variant_builder_init(&params, ((const GVariantType *) "av"));
616
617                 for(auto itr = mList.begin(); itr != mList.end(); itr++)
618                 {
619                         AbstractPropertyType* t = *itr;
620                         GVariant *var = t->toVariant();
621                         GVariant *newvar = g_variant_new("v",var);
622                         g_variant_builder_add_value(&params, newvar);
623                         
624                 }
625
626                 GVariant* var =  g_variant_builder_end(&params);
627                 g_assert(var);
628                 return var;
629
630         }
631
632         void fromVariant(GVariant* v)
633         {
634                 /// TODO: fill this in
635                 gsize dictsize = g_variant_n_children(v);
636                 for (int i=0;i<dictsize;i++)
637                 {
638                         GVariant *childvariant = g_variant_get_child_value(v,i);
639                         GVariant *innervariant = g_variant_get_variant(childvariant);
640                         T *t = new T();
641                         t->fromVariant(innervariant);
642                         appendPriv(t);
643                 }
644         }
645
646         std::list<AbstractPropertyType*> list() { return mList; }
647
648 private:
649         void appendPriv(AbstractPropertyType* i)
650         {
651                 mList.push_back(i);
652         }
653
654         bool initialized;
655
656         std::list<AbstractPropertyType*> mList;
657 };
658
659 #endif