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