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