StateVariable.cc Source File

Back to the index.

StateVariable.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2010 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <assert.h>
29 #include <math.h>
30 
31 #include "EscapedString.h"
32 #include "StateVariable.h"
33 #include "StringHelper.h"
34 
35 
36 StateVariable::StateVariable(const string& name, string* ptrToString)
37  : m_name(name)
38  , m_type(String)
39 {
40  m_value.pstr = ptrToString;
41 }
42 
43 
44 StateVariable::StateVariable(const string& name, bool* ptrToVar)
45  : m_name(name)
46  , m_type(Bool)
47 {
48  m_value.pbool = ptrToVar;
49 }
50 
51 
52 StateVariable::StateVariable(const string& name, double* ptrToVar)
53  : m_name(name)
54  , m_type(Double)
55 {
56  m_value.pdouble = ptrToVar;
57 }
58 
59 
60 StateVariable::StateVariable(const string& name, uint8_t* ptrToVar)
61  : m_name(name)
62  , m_type(UInt8)
63 {
64  m_value.puint8 = ptrToVar;
65 }
66 
67 
68 StateVariable::StateVariable(const string& name, uint16_t* ptrToVar)
69  : m_name(name)
70  , m_type(UInt16)
71 {
72  m_value.puint16 = ptrToVar;
73 }
74 
75 
76 StateVariable::StateVariable(const string& name, uint32_t* ptrToVar)
77  : m_name(name)
78  , m_type(UInt32)
79 {
80  m_value.puint32 = ptrToVar;
81 }
82 
83 
84 StateVariable::StateVariable(const string& name, uint64_t* ptrToVar)
85  : m_name(name)
86  , m_type(UInt64)
87 {
88  m_value.puint64 = ptrToVar;
89 }
90 
91 
92 StateVariable::StateVariable(const string& name, int8_t* ptrToVar)
93  : m_name(name)
94  , m_type(SInt8)
95 {
96  m_value.psint8 = ptrToVar;
97 }
98 
99 
100 StateVariable::StateVariable(const string& name, int16_t* ptrToVar)
101  : m_name(name)
102  , m_type(SInt16)
103 {
104  m_value.psint16 = ptrToVar;
105 }
106 
107 
108 StateVariable::StateVariable(const string& name, int32_t* ptrToVar)
109  : m_name(name)
110  , m_type(SInt32)
111 {
112  m_value.psint32 = ptrToVar;
113 }
114 
115 
116 StateVariable::StateVariable(const string& name, int64_t* ptrToVar)
117  : m_name(name)
118  , m_type(SInt64)
119 {
120  m_value.psint64 = ptrToVar;
121 }
122 
123 
124 StateVariable::StateVariable(const string& name, CustomStateVariableHandler* ptrToHandler)
125  : m_name(name)
126  , m_type(Custom)
127 {
128  m_value.phandler = ptrToHandler;
129 }
130 
131 
133 {
134  return m_type;
135 }
136 
137 
138 const string& StateVariable::GetName() const
139 {
140  return m_name;
141 }
142 
143 
144 string StateVariable::GetTypeString() const
145 {
146  switch (m_type) {
147  case String:
148  return "string";
149  case Bool:
150  return "bool";
151  case Double:
152  return "double";
153  case UInt8:
154  return "uint8";
155  case UInt16:
156  return "uint16";
157  case UInt32:
158  return "uint32";
159  case UInt64:
160  return "uint64";
161  case SInt8:
162  return "sint8";
163  case SInt16:
164  return "sint16";
165  case SInt32:
166  return "sint32";
167  case SInt64:
168  return "sint64";
169  case Custom:
170  return "custom";
171  default:
172  return "unknown";
173  }
174 }
175 
176 
177 bool StateVariable::CopyValueFrom(const StateVariable& otherVariable)
178 {
179  if (m_type != otherVariable.m_type)
180  return false;
181 
182  switch (m_type) {
183  case String:
184  *m_value.pstr = *otherVariable.m_value.pstr;
185  break;
186  case Bool:
187  *m_value.pbool = *otherVariable.m_value.pbool;
188  break;
189  case Double:
190  *m_value.pdouble = *otherVariable.m_value.pdouble;
191  break;
192  case UInt8:
193  *m_value.puint8 = *otherVariable.m_value.puint8;
194  break;
195  case UInt16:
196  *m_value.puint16 = *otherVariable.m_value.puint16;
197  break;
198  case UInt32:
199  *m_value.puint32 = *otherVariable.m_value.puint32;
200  break;
201  case UInt64:
202  *m_value.puint64 = *otherVariable.m_value.puint64;
203  break;
204  case SInt8:
205  *m_value.psint8 = *otherVariable.m_value.psint8;
206  break;
207  case SInt16:
208  *m_value.psint16 = *otherVariable.m_value.psint16;
209  break;
210  case SInt32:
211  *m_value.psint32 = *otherVariable.m_value.psint32;
212  break;
213  case SInt64:
214  *m_value.psint64 = *otherVariable.m_value.psint64;
215  break;
216  case Custom:
217  m_value.phandler->CopyValueFrom(otherVariable.m_value.phandler);
218  break;
219  default:
220  // Unknown type?
221  assert(false);
222  return false;
223  }
224 
225  return true;
226 }
227 
228 
230 {
231  stringstream sstr;
232 
233  switch (m_type) {
234  case String:
235  return m_value.pstr == NULL? "" : *m_value.pstr;
236  case Bool:
237  sstr << (*m_value.pbool? "true" : "false");
238  return sstr.str();
239  case Double:
240  sstr << *m_value.pdouble;
241  return sstr.str();
242  case UInt8:
243  sstr << (int) *m_value.puint8;
244  return sstr.str();
245  case UInt16:
246  sstr.flags(std::ios::hex | std::ios::showbase);
247  sstr << *m_value.puint16;
248  return sstr.str();
249  case UInt32:
250  sstr.flags(std::ios::hex | std::ios::showbase);
251  sstr << *m_value.puint32;
252  return sstr.str();
253  case UInt64:
254  sstr.flags(std::ios::hex | std::ios::showbase);
255  sstr << *m_value.puint64;
256  return sstr.str();
257  case SInt8:
258  sstr << (int) *m_value.psint8;
259  return sstr.str();
260  case SInt16:
261  sstr << *m_value.psint16;
262  return sstr.str();
263  case SInt32:
264  sstr << *m_value.psint32;
265  return sstr.str();
266  case SInt64:
267  sstr << *m_value.psint64;
268  return sstr.str();
269  case Custom:
270  return "(custom)";
271  }
272 
273  // Unimplemented type?
274  assert(false);
275 
276  return "";
277 }
278 
279 
280 uint64_t StateVariable::ToInteger() const
281 {
282  switch (m_type) {
283  case String:
284  {
285  uint64_t tmp;
286  stringstream ss;
287  ss << *m_value.pstr;
288  ss >> tmp;
289  return tmp;
290  }
291  case Bool:
292  return (*m_value.pbool)? 1 : 0;
293  case Double:
294  return (uint64_t) *m_value.pdouble;
295  case UInt8:
296  return *m_value.puint8;
297  case UInt16:
298  return *m_value.puint16;
299  case UInt32:
300  return *m_value.puint32;
301  case UInt64:
302  return *m_value.puint64;
303  case SInt8:
304  return *m_value.psint8;
305  case SInt16:
306  return *m_value.psint16;
307  case SInt32:
308  return *m_value.psint32;
309  case SInt64:
310  return *m_value.psint64;
311  case Custom:
312  return 0;
313  }
314 
315  // Unimplemented type. Let's abort.
316  std::cerr << "StateVariable::ToDouble(): Unimplemented type.\n";
317  throw std::exception();
318 }
319 
320 
322 {
323  switch (m_type) {
324  case String:
325  {
326  double tmp;
327  stringstream ss;
328  ss << *m_value.pstr;
329  ss >> tmp;
330  return tmp;
331  }
332  case Bool:
333  return (*m_value.pbool)? 1.0 : 0.0;
334  case Double:
335  return *m_value.pdouble;
336  case UInt8:
337  return *m_value.puint8;
338  case UInt16:
339  return *m_value.puint16;
340  case UInt32:
341  return *m_value.puint32;
342  case UInt64:
343  return *m_value.puint64;
344  case SInt8:
345  return *m_value.psint8;
346  case SInt16:
347  return *m_value.psint16;
348  case SInt32:
349  return *m_value.psint32;
350  case SInt64:
351  return *m_value.psint64;
352  case Custom:
353  return 0.0;
354  }
355 
356  // Unimplemented type. Let's abort.
357  std::cerr << "StateVariable::ToDouble(): Unimplemented type.\n";
358  throw std::exception();
359 }
360 
361 
362 void StateVariable::SerializeValue(ostream& ss) const
363 {
364  switch (m_type) {
365 
366  case String:
367  {
368  EscapedString escaped(ToString());
369  ss << escaped.Generate();
370  }
371  break;
372 
373  case Custom:
374  m_value.phandler->Serialize(ss);
375  break;
376 
377  default:
378  ss << ToString();
379  }
380 }
381 
382 
383 void StateVariable::Serialize(ostream& ss, SerializationContext& context) const
384 {
385  ss << context.Tabs() << GetTypeString() << " " << m_name + " ";
386  SerializeValue(ss);
387  ss << "\n";
388 }
389 
390 
391 string StateVariable::EvaluateExpression(const string& expression,
392  bool& success) const
393 {
394  success = false;
395 
396  string result = expression;
397 
398  // Remove leading and trailing spaces:
399  while (result.size() > 0 && result[0] == ' ')
400  result.erase((size_t) 0);
401  while (result.size() > 0 && result[result.size() - 1] == ' ')
402  result.erase(result.size()-1);
403 
404 // TODO
405 success = true;
406 return result;
407 
408  return "";
409 }
410 
411 
412 bool StateVariable::SetValue(const string& expression)
413 {
414  // Nothing to assign to?
415  if (m_value.pstr == NULL)
416  return false;
417 
418  // Reduce the expression to a single value.
419  bool success = false;
420  string value = EvaluateExpression(expression, success);
421  if (!success)
422  return false;
423 
424  switch (m_type) {
425 
426  case String:
427  {
428  success = false;
429  string newStr = EscapedString(value).Decode(success);
430  if (success)
431  *m_value.pstr = newStr;
432  else
433  return false;
434  }
435  return true;
436 
437  case Bool:
438  {
439  if (value == "true")
440  *m_value.pbool = true;
441  else if (value == "false")
442  *m_value.pbool = false;
443  else
444  return false;
445  }
446  return true;
447 
448  case Double:
449  {
450  double doubleTmp;
451  stringstream sstr;
452  sstr << value;
453  sstr >> doubleTmp;
454  if (isnan(doubleTmp) || isinf(doubleTmp))
455  return false;
456  *m_value.pdouble = doubleTmp;
457  }
458  return true;
459 
460  case UInt8:
461  {
462  bool error = true;
463  uint64_t tmp64 = StringHelper::ParseNumber(value.c_str(), error);
464  uint8_t tmp = tmp64;
465  if (tmp == tmp64 && !error)
466  *m_value.puint8 = tmp;
467  else
468  return false;
469  }
470  return true;
471 
472  case UInt16:
473  {
474  bool error = true;
475  uint64_t tmp64 = StringHelper::ParseNumber(value.c_str(), error);
476  uint16_t tmp = tmp64;
477  if (tmp == tmp64 && !error)
478  *m_value.puint16 = tmp;
479  else
480  return false;
481  }
482  return true;
483 
484  case UInt32:
485  {
486  bool error = true;
487  uint64_t tmp64 = StringHelper::ParseNumber(value.c_str(), error);
488  uint32_t tmp = tmp64;
489  if (tmp == tmp64 && !error)
490  *m_value.puint32 = tmp;
491  else
492  return false;
493  }
494  return true;
495 
496  case UInt64:
497  {
498  bool error = true;
499  uint64_t tmp64 = StringHelper::ParseNumber(value.c_str(), error);
500  if (!error)
501  *m_value.puint64 = tmp64;
502  else
503  return false;
504  }
505  return true;
506 
507  case SInt8:
508  {
509  bool error = true;
510  int64_t tmp64 = StringHelper::ParseNumber(value.c_str(), error);
511  int8_t tmp = tmp64;
512  if (tmp == tmp64 && !error)
513  *m_value.psint8 = tmp;
514  else
515  return false;
516  }
517  return true;
518 
519  case SInt16:
520  {
521  bool error = true;
522  int64_t tmp64 = StringHelper::ParseNumber(value.c_str(), error);
523  int16_t tmp = tmp64;
524  if (tmp == tmp64 && !error)
525  *m_value.psint16 = tmp;
526  else
527  return false;
528  }
529  return true;
530 
531  case SInt32:
532  {
533  bool error = true;
534  int64_t tmp64 = StringHelper::ParseNumber(value.c_str(), error);
535  int32_t tmp = tmp64;
536  if (tmp == tmp64 && !error)
537  *m_value.psint32 = tmp;
538  else
539  return false;
540  }
541  return true;
542 
543  case SInt64:
544  {
545  bool error = true;
546  int64_t tmp64 = StringHelper::ParseNumber(value.c_str(), error);
547  if (!error)
548  *m_value.psint64 = tmp64;
549  else
550  return false;
551  }
552  return true;
553 
554  case Custom:
555  return m_value.phandler->Deserialize(value);
556 
557  default:
558  // Unimplemented type. Let's abort.
559  std::cerr << "StateVariable::SetValue: Unimplemented type.\n";
560  throw std::exception();
561  }
562 }
563 
564 
565 bool StateVariable::SetValue(uint64_t value)
566 {
567  // Nothing to assign to?
568  if (m_value.pstr == NULL)
569  return false;
570 
571  switch (m_type) {
572 
573  case String:
574  {
575  stringstream ss;
576  ss << value;
577  *m_value.pstr = ss.str();
578  }
579  return true;
580 
581  case Bool:
582  *m_value.pbool = value != 0;
583  return true;
584 
585  case Double:
586  *m_value.pdouble = value;
587  return true;
588 
589  case UInt8:
590  *m_value.puint8 = value;
591  return true;
592 
593  case UInt16:
594  *m_value.puint16 = value;
595  return true;
596 
597  case UInt32:
598  *m_value.puint32 = value;
599  return true;
600 
601  case UInt64:
602  *m_value.puint64 = value;
603  return true;
604 
605  case SInt8:
606  *m_value.psint8 = value;
607  return true;
608 
609  case SInt16:
610  *m_value.psint16 = value;
611  return true;
612 
613  case SInt32:
614  *m_value.psint32 = value;
615  return true;
616 
617  case SInt64:
618  *m_value.psint64 = value;
619  return true;
620 
621  case Custom:
622  return false;
623 
624  default:
625  // Unimplemented type. Let's abort.
626  std::cerr << "StateVariable::SetValue: Unimplemented type.\n";
627  throw std::exception();
628  }
629 }
630 
631 
632 /*****************************************************************************/
633 
634 
635 #ifdef WITHUNITTESTS
636 
637 static void Test_StateVariable_String_Construct()
638 {
639  string myString = "hi";
640 
641  StateVariable var("hello", &myString);
642 
643  UnitTest::Assert("name should be hello",
644  var.GetName(), "hello");
645  UnitTest::Assert("type should be String",
646  var.GetType() == StateVariable::String);
647  UnitTest::Assert("value should be hi",
648  var.ToString(), "hi");
649 }
650 
651 static void Test_StateVariable_String_SetValue()
652 {
653  string myString = "hi";
654 
655  StateVariable var("hello", &myString);
656 
657  UnitTest::Assert("setting string value without quotes should not work",
658  var.SetValue("value2") == false);
659  UnitTest::Assert("setting string value with quotes should work",
660  var.SetValue("\"value2\"") == true);
661 
662  UnitTest::Assert("type should still be String",
663  var.GetType() == StateVariable::String);
664  UnitTest::Assert("value should now be value2",
665  var.ToString(), "value2");
666  UnitTest::Assert("myString should have been updated",
667  myString, "value2");
668 }
669 
670 static void Test_StateVariable_String_CopyValueFrom()
671 {
672  string myString1 = "hi";
673  string myString2 = "something";
674 
675  StateVariable var1("hello", &myString1);
676  StateVariable var2("world", &myString2);
677 
678  UnitTest::Assert("value should initially be hi",
679  var1.ToString(), "hi");
680 
681  var1.CopyValueFrom(var2);
682 
683  UnitTest::Assert("name should still be hello",
684  var1.GetName(), "hello");
685  UnitTest::Assert("type should still be String",
686  var1.GetType() == StateVariable::String);
687  UnitTest::Assert("value should be changed to something",
688  var1.ToString(), "something");
689  UnitTest::Assert("myString1 should have been updated",
690  myString1, "something");
691 }
692 
693 static void Test_StateVariable_String_Serialize()
694 {
695  string hi = "value world";
696  StateVariable var("hello", &hi);
697 
698  SerializationContext dummyContext;
699  stringstream ss;
700 
701  var.Serialize(ss, dummyContext);
702  UnitTest::Assert("variable serialization mismatch?",
703  ss.str(), "string hello \"value world\"\n");
704 }
705 
706 static void Test_StateVariable_String_Serialize_WithEscapes()
707 {
708  string s = "a\\b\tc\nd\re\bf\"g'h";
709  StateVariable var("hello", &s);
710 
711  SerializationContext dummyContext;
712  stringstream ss;
713 
714  var.Serialize(ss, dummyContext);
715  UnitTest::Assert("variable serialization mismatch?",
716  ss.str(),
717  "string hello " + EscapedString(s).Generate() + "\n");
718 }
719 
720 static void Test_StateVariable_Bool_Construct()
721 {
722  bool myBool = true;
723 
724  StateVariable var("hello", &myBool);
725 
726  UnitTest::Assert("name should be hello",
727  var.GetName(), "hello");
728  UnitTest::Assert("type should be Bool",
729  var.GetType() == StateVariable::Bool);
730  UnitTest::Assert("value should be true",
731  var.ToString(), "true");
732 }
733 
734 static void Test_StateVariable_Bool_SetValue()
735 {
736  bool myBool = true;
737 
738  StateVariable var("hello", &myBool);
739 
740  UnitTest::Assert("changing to false should be possible",
741  var.SetValue("false") == true);
742 
743  UnitTest::Assert("type should still be Bool",
744  var.GetType() == StateVariable::Bool);
745  UnitTest::Assert("value should now be changed",
746  var.ToString(), "false");
747  UnitTest::Assert("myBool should have been updated",
748  myBool == false);
749 
750  UnitTest::Assert("changing to true should be possible",
751  var.SetValue("true") == true);
752 
753  UnitTest::Assert("value should now be changed again",
754  var.ToString(), "true");
755  UnitTest::Assert("myBool should have been updated again",
756  myBool == true);
757 
758  UnitTest::Assert("changing to non-bool value should not be possible",
759  var.SetValue("hello") == false);
760 
761  UnitTest::Assert("value should not be changed",
762  var.ToString(), "true");
763 }
764 
765 static void Test_StateVariable_Bool_CopyValueFrom()
766 {
767  bool myBool1 = false;
768  bool myBool2 = true;
769 
770  StateVariable var1("hello", &myBool1);
771  StateVariable var2("world", &myBool2);
772 
773  UnitTest::Assert("copying from bool to bool should be possible",
774  var1.CopyValueFrom(var2) == true);
775 
776  UnitTest::Assert("name should still be hello",
777  var1.GetName(), "hello");
778  UnitTest::Assert("type should still be Bool",
779  var1.GetType() == StateVariable::Bool);
780  UnitTest::Assert("value should be changed to true",
781  var1.ToString(), "true");
782  UnitTest::Assert("myBool1 should have been updated",
783  myBool1 == true);
784 
785  string myString = "hm";
786  StateVariable var3("test", &myString);
787 
788  UnitTest::Assert("copying from string to bool should not be possible",
789  var1.CopyValueFrom(var3) == false);
790 }
791 
792 static void Test_StateVariable_Bool_Serialize()
793 {
794  bool myBool = true;
795  StateVariable var("hello", &myBool);
796 
797  SerializationContext dummyContext;
798  stringstream ss;
799 
800  var.Serialize(ss, dummyContext);
801  UnitTest::Assert("variable serialization mismatch (1)",
802  ss.str(), "bool hello true\n");
803 
804  myBool = false;
805  stringstream ss2;
806  var.Serialize(ss2, dummyContext);
807 
808  UnitTest::Assert("variable serialization mismatch (2)",
809  ss2.str(), "bool hello false\n");
810 }
811 
812 static void Test_StateVariable_Numeric_Construct()
813 {
814  double varDouble = -12.345;
815  uint8_t varUInt8 = 223;
816  uint16_t varUInt16 = 55000;
817  uint32_t varUInt32 = 3000000001UL;
818  uint64_t varUInt64 = ((uint64_t) 0xfedc0102 << 32) | 0x03040506;
819  int8_t varSInt8 = -120;
820  int16_t varSInt16 = -22000;
821  int32_t varSInt32 = -1000000001;
822  int64_t varSInt64 = ((uint64_t) 0xfedc0102 << 32) | 0x03040506;
823 
824  StateVariable vdouble("vdouble", &varDouble);
825  StateVariable vuint8 ("vuint8", &varUInt8);
826  StateVariable vuint16("vuint16", &varUInt16);
827  StateVariable vuint32("vuint32", &varUInt32);
828  StateVariable vuint64("vuint64", &varUInt64);
829  StateVariable vsint8 ("vsint8", &varSInt8);
830  StateVariable vsint16("vsint16", &varSInt16);
831  StateVariable vsint32("vsint32", &varSInt32);
832  StateVariable vsint64("vsint64", &varSInt64);
833 
834  // Types
835  UnitTest::Assert("Double", vdouble.GetType() == StateVariable::Double);
836  UnitTest::Assert("UInt8", vuint8.GetType() == StateVariable::UInt8);
837  UnitTest::Assert("UInt16", vuint16.GetType() == StateVariable::UInt16);
838  UnitTest::Assert("UInt32", vuint32.GetType() == StateVariable::UInt32);
839  UnitTest::Assert("UInt64", vuint64.GetType() == StateVariable::UInt64);
840  UnitTest::Assert("SInt8", vsint8.GetType() == StateVariable::SInt8);
841  UnitTest::Assert("SInt16", vsint16.GetType() == StateVariable::SInt16);
842  UnitTest::Assert("SInt32", vsint32.GetType() == StateVariable::SInt32);
843  UnitTest::Assert("SInt64", vsint64.GetType() == StateVariable::SInt64);
844 
845  // Values
846  UnitTest::Assert("value Double", vdouble.ToString(), "-12.345");
847  UnitTest::Assert("value UInt8", vuint8.ToString(), "223");
848  UnitTest::Assert("value UInt16", vuint16.ToString(), "0xd6d8");
849  UnitTest::Assert("value UInt32", vuint32.ToString(), "0xb2d05e01");
850  UnitTest::Assert("value UInt64", vuint64.ToString(),
851  "0xfedc010203040506");
852  UnitTest::Assert("value SInt8", vsint8.ToString(), "-120");
853  UnitTest::Assert("value SInt16", vsint16.ToString(), "-22000");
854  UnitTest::Assert("value SInt32", vsint32.ToString(), "-1000000001");
855  UnitTest::Assert("value SInt64", vsint64.ToString(),
856  "-82189585047354106");
857 }
858 
859 static void Test_StateVariable_Numeric_SetValue()
860 {
861  double varDouble = -12.345;
862  uint8_t varUInt8 = 223;
863  uint16_t varUInt16 = 55000;
864  uint32_t varUInt32 = 3000000001UL;
865  uint64_t varUInt64 = ((uint64_t) 0xfedc0102 << 32) | 0x03040506;
866  int8_t varSInt8 = -120;
867  int16_t varSInt16 = -22000;
868  int32_t varSInt32 = -1000000001;
869  int64_t varSInt64 = ((uint64_t) 0xfedc0102 << 32) | 0x03040506;
870 
871  StateVariable vdouble("vdouble", &varDouble);
872  StateVariable vuint8 ("vuint8", &varUInt8);
873  StateVariable vuint16("vuint16", &varUInt16);
874  StateVariable vuint32("vuint32", &varUInt32);
875  StateVariable vuint64("vuint64", &varUInt64);
876  StateVariable vsint8 ("vsint8", &varSInt8);
877  StateVariable vsint16("vsint16", &varSInt16);
878  StateVariable vsint32("vsint32", &varSInt32);
879  StateVariable vsint64("vsint64", &varSInt64);
880 
881  UnitTest::Assert("changing to 'hello' should not be possible",
882  vuint8.SetValue("hello") == false);
883 
884  // Double
885  UnitTest::Assert("changing to 100 should be possible",
886  vdouble.SetValue("100") == true);
887  UnitTest::Assert("varDouble should have been updated",
888  varDouble == 100);
889  UnitTest::Assert("changing to -210.42 should be possible",
890  vdouble.SetValue("-210.42") == true);
891  UnitTest::Assert("varDouble should not have been updated",
892  varDouble == -210.42);
893  UnitTest::Assert("changing to 1e-100 should be possible (2)",
894  vdouble.SetValue("1e-100") == true);
895  UnitTest::Assert("varDouble should have been updated (2)",
896  varDouble == 1e-100);
897 
898  // UInt8
899  UnitTest::Assert("changing to 100 should be possible",
900  vuint8.SetValue("100") == true);
901  UnitTest::Assert("varUInt8 should have been updated",
902  varUInt8, 100);
903  UnitTest::Assert("changing to 0x2f should be possible",
904  vuint8.SetValue("0x2f") == true);
905  UnitTest::Assert("varUInt8 should have been updated to 0x2f",
906  varUInt8, 0x2f);
907  UnitTest::Assert("changing to 300 should not be possible",
908  vuint8.SetValue("300") == false);
909  UnitTest::Assert("varUInt8 should not have been updated",
910  varUInt8, 0x2f);
911  UnitTest::Assert("changing to -110 should not be possible",
912  vuint8.SetValue("-110") == false);
913  UnitTest::Assert("varUInt8 should not have been updated",
914  varUInt8, 0x2f);
915 
916  // SInt8
917  UnitTest::Assert("changing to 100 should be possible",
918  vsint8.SetValue("100") == true);
919  UnitTest::Assert("varSInt8 should have been updated",
920  varSInt8, 100);
921  UnitTest::Assert("changing to 200 should not be possible",
922  vsint8.SetValue("200") == false);
923  UnitTest::Assert("varSInt8 should not have been updated",
924  varSInt8, 100);
925  UnitTest::Assert("changing to -210 should not be possible",
926  vsint8.SetValue("-210") == false);
927  UnitTest::Assert("varSInt8 should not have been updated",
928  varSInt8, 100);
929  UnitTest::Assert("changing to -110 should be possible",
930  vsint8.SetValue("-110") == true);
931  UnitTest::Assert("varSInt8 should have been updated",
932  varSInt8, (uint64_t) -110);
933  UnitTest::Assert("changing to -0x1a should be possible",
934  vsint8.SetValue("-0x1a") == true);
935  UnitTest::Assert("varSInt8 should have been updated",
936  varSInt8, (uint64_t) -0x1a);
937 
938  // Tests for other numeric types: TODO
939 }
940 
942 {
943  // String tests
944  UNITTEST(Test_StateVariable_String_Construct);
945  UNITTEST(Test_StateVariable_String_SetValue);
946  UNITTEST(Test_StateVariable_String_CopyValueFrom);
947  UNITTEST(Test_StateVariable_String_Serialize);
948  UNITTEST(Test_StateVariable_String_Serialize_WithEscapes);
949 
950  // Bool tests
951  UNITTEST(Test_StateVariable_Bool_Construct);
952  UNITTEST(Test_StateVariable_Bool_SetValue);
953  UNITTEST(Test_StateVariable_Bool_CopyValueFrom);
954  UNITTEST(Test_StateVariable_Bool_Serialize);
955 
956  // Numeric tests
957  UNITTEST(Test_StateVariable_Numeric_Construct);
958  UNITTEST(Test_StateVariable_Numeric_SetValue);
959  //UNITTEST(Test_StateVariable_Numeric_CopyValueFrom);
960  //UNITTEST(Test_StateVariable_Numeric_Serialize);
961 
962  // TODO: ToInteger tests.
963 
964  // TODO: Custom tests.
965 }
966 
967 #endif
968 
bool CopyValueFrom(const StateVariable &otherVariable)
Copy the value from another variable into this variable.
CustomStateVariableHandler * phandler
const string & GetName() const
Gets the name of the variable.
string Tabs() const
Generates a string of Tab characters, based on the indentation level.
int16_t * psint16
uint32_t * puint32
int32_t * psint32
string Generate() const
Generates an escaped string, from the original string.
static uint64_t ParseNumber(const char *str, bool &error)
Parses a string into a 64-bit number.
Definition: StringHelper.cc:34
#define UNITTESTS(class)
Helper for unit test case execution.
Definition: UnitTest.h:184
bool SetValue(const string &expression)
Set the variable&#39;s value, using a string expression.
uint8_t * puint8
double ToDouble() const
Returns the variable as a double value.
enum Type GetType() const
Gets the type of the variable.
string ToString() const
Returns the variable as a readable string.
A context used during serialization of objects.
uint64_t * puint64
string Decode(bool &success) const
Decodes an escaped string, from the original string.
Type
An enumeration of the possible types of a StateVariable.
Definition: StateVariable.h:74
int8_t * psint8
uint64_t ToInteger() const
Returns the variable as an unsignedinteger value.
StateVariables make up the persistent state of Component objects.
Definition: StateVariable.h:67
A helper class for escaping strings using C-style escapes.
Definition: EscapedString.h:42
static void Assert(const string &strFailMessage, bool condition)
Asserts that a boolean condition is correct.
Definition: UnitTest.cc:40
double * pdouble
uint16_t * puint16
void Serialize(ostream &ss, SerializationContext &context) const
Serializes the variable into a string.
#define UNITTEST(functionname)
Helper for unit test case execution.
Definition: UnitTest.h:217
int64_t * psint64
void SerializeValue(ostream &ss) const
Serializes the variable value into a string.

Generated on Sun Sep 30 2018 16:05:18 for GXemul by doxygen 1.8.13