PEBL 2.2
Psychology Experiment Building Language - Cross-platform psychological experiment development system
Variant.cpp
Go to the documentation of this file.
1//* -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*- */
3// Name: src/base/Variant.cpp
4// Purpose: Contains the Variant Class
5// Author: Shane T. Mueller, Ph.D.
6// Copyright: (c) 2003-2026 Shane T. Mueller <smueller@obereed.net>
7// License: GPL 2
8//
9//
10//
11// This file is part of the PEBL project.
12//
13// PEBL is free software; you can redistribute it and/or modify
14// it under the terms of the GNU General Public License as published by
15// the Free Software Foundation; either version 2 of the License, or
16// (at your option) any later version.
17//
18// PEBL is distributed in the hope that it will be useful,
19// but WITHOUT ANY WARRANTY; without even the implied warranty of
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21// GNU General Public License for more details.
22//
23// You should have received a copy of the GNU General Public License
24// along with PEBL; if not, write to the Free Software
25// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26// USA
28
29
30#include "Variant.h"
31#include "PComplexData.h"
32#include "../utility/PError.h"
33#include "../utility/Defs.h"
34
35#include <iostream>
36#include <sstream>
37
38#include <math.h>
39#include <string>
40
41#include <stdlib.h>
42#include <cmath>
43#include <cstring>
44
45#ifdef PEBL_EMSCRIPTEN
46#include <emscripten.h>
47#endif
48
49using std::cerr;
50using std::cout;
51using std::endl;
52using std::flush;
53using std::ostream;
54using std::string;
55
56//Constructor
57
59 mDataType(P_DATA_UNDEFINED),
60 mComplexData(NULL),
61 mCreationTime(0)
62{
63
64 mData.iNumber = 0;
65}
66
67
68//Constructor
70 mDataType(P_DATA_NUMBER_INTEGER),
71 mComplexData(NULL),
72 mCreationTime(0)
73{
74
75 mData.iNumber = i;
76
77}
78
79
80#ifndef PEBL_EMSCRIPTEN
81//Constructor
83 mDataType(P_DATA_NUMBER_INTEGER),
84 mComplexData(NULL),
85 mCreationTime(0)
86{
87 mData.iNumber = (pInt)i;
88
89}
90#endif
91
92
93
94//Constructor
95Variant::Variant(const long unsigned int i):
96 mDataType(P_DATA_NUMBER_INTEGER),
97 mComplexData(NULL),
98 mCreationTime(0)
99{
100
101 mData.iNumber = static_cast<pInt>(i);
102
103}
104
105
106
107//Constructor
109 mDataType(P_DATA_NUMBER_FLOAT),
110 mComplexData(NULL),
111 mCreationTime(0)
112
113{
114
115 mData.fNumber = f;
116}
117
118#ifndef PEBL_EMSCRIPTEN
119//Constructor
121 mDataType(P_DATA_NUMBER_FLOAT),
122 mComplexData(NULL),
123 mCreationTime(0)
124{
125 mData.fNumber=(pDouble)f;
126}
127#endif
128
129//Constructor
131 mDataType(P_DATA_NUMBER_FLOAT),
132 mComplexData(NULL),
133 mCreationTime(0)
134
135{
136
137 mData.fNumber = (pDouble)f;
138
139}
140
141
142//String Constructor
143Variant::Variant(const char * mystring):
144 mDataType(P_DATA_STRING),
145 mComplexData(NULL),
146 mCreationTime(0)
147 // mData(NULL)
148{
149
150
151 //cout << P_DATA_STRING << endl;
152 mData.String = strdup(mystring);
153 if(!mData.String)
154 PError::SignalFatalError("Failed to copy string.");
155}
156
157
158//Character Constructor
159Variant::Variant(const char character):
160 mDataType(P_DATA_STRING),
161 mComplexData(NULL),
162 mCreationTime(0)
163
164{
165
166 //Make a dummy string to place the character into.
167 char * dummy = (char*)malloc(2*sizeof(char));
168 dummy[0]=character;
169 dummy[1]='\0';
170 mData.String = dummy;
171
172}
173
174//standard string constructor
175Variant::Variant(std::string mystring):
176 mDataType(P_DATA_STRING),
177 mComplexData(NULL),
178 mCreationTime(0)
179
180{
181
182 const char* dummy = mystring.c_str();
183 mData.String = strdup(dummy);
184
185}
186
187
188Variant::Variant(const char* mystring, VariantDataType type):
189 mDataType(type),
190 mComplexData(NULL),
191// mData((int)0),
192 mCreationTime(0)
193{
194
195 switch(type)
196 {
197 case P_DATA_FUNCTION:
198 mData.Function= strdup(mystring); break;
199 case P_DATA_STRING:
200 mData.String= strdup(mystring); break;
203 mData.Variable= strdup(mystring); break;
204
205 case P_DATA_UNDEFINED:
209 default:
210 //If it isn't one of the above, change it into a string
211 mDataType = P_DATA_STRING;
212 mData.String = strdup(mystring);
213 break;
214 }
215}
216
218 mDataType(P_DATA_COMPLEXDATA),
219 mComplexData(NULL),
220 mCreationTime(0)
221{
222
223 mComplexData = new PComplexData(pcd);
224}
225
226
229 mDataType(P_DATA_STACK_SIGNAL),
230 mComplexData(NULL),
231 // mData((StackSignalType)signal),
232 mCreationTime(0)
233
234{
235 mData.Signal = signal;
236}
237
238
240 mDataType(P_DATA_FUNCTION_POINTER),
241 mComplexData(NULL),
242 mCreationTime(0)
243{
244 mData.pFunction = pfunc;
245}
246
247
248
249//Constructor
251 mDataType(P_DATA_NUMBER_INTEGER),
252 mComplexData(NULL),
253 mCreationTime(0)
254
255{
256
257 mData.iNumber = (pInt)b;
258}
259
260
264
266 mDataType(v.GetDataType()),
267 mComplexData(NULL),
268 mCreationTime(v.GetCreationTime())
269{
270
271 // cout << "creating/copy10:[" << v << "]("<<GetCreationTime()<<")"<< endl;
272
273 //This should behave differently depending on what type of variant v is
274 // mDataType already initialized in initializer list above
275
276#ifdef PEBL_EMSCRIPTEN
277 // Validate that mDataType is within valid range
278 if(mDataType < 0 || mDataType > P_DATA_COMPLEXDATA) {
279 cerr << "ERROR: Variant copy constructor received corrupted source Variant" << endl;
280 cerr << "Invalid mDataType value: " << mDataType << " (expected 0-" << P_DATA_COMPLEXDATA << ")" << endl;
281 cerr << "Source address: " << &v << endl;
282 cerr << "Source mComplexData: " << v.mComplexData << endl;
283 cerr << "Source mCreationTime: " << v.mCreationTime << endl;
284
285 // Print stack trace using Emscripten
286 EM_ASM({
287 console.error("Stack trace at corruption point:");
288 console.trace();
289 });
290
291 cerr << "This indicates memory corruption or uninitialized Variant" << endl;
292 // Set to undefined and continue rather than crash
293 mDataType = P_DATA_UNDEFINED;
294 mData.iNumber = 0;
295 return;
296 }
297#endif
298
299 switch(mDataType)
300 {
301
302 case P_DATA_NUMBER_INTEGER: // an integer
303 mData.iNumber = v.GetInteger();
304 break;
305
306 case P_DATA_NUMBER_FLOAT: // a float
307 mData.fNumber = v.GetFloat();
308 break;
309
310 case P_DATA_STRING:
311 // cout << "testing case string:<" << v << ">"<<endl;
312 mData.String = strdup(v.GetString().c_str());
313 break;
314
315 case P_DATA_LOCALVARIABLE: // a variable name
316 case P_DATA_GLOBALVARIABLE: // a variable name
317 mData.Variable = strdup(v.GetVariableName().c_str());
318 break;
319
320 case P_DATA_FUNCTION:
321 {
322 //Memory problem here, diagnosed by efence:
323 std::string tmpfname = v.GetFunctionName();
324 // const char* tmpfname2 = tmpfname.c_str();
325 char* cstr = new char[tmpfname.length()+1];
326 strcpy(cstr,tmpfname.c_str());
327 mData.Function = cstr;
328
329 }
330
331 break;
332
334 mData.pFunction = v.GetFunctionPointer();
335 break;
336
337
339 mData.Signal = v.GetSignal();
340 break;
341
342 //This needs to make a deep copy
343
345 {
346
347 //cout<<"TYPE:" << v << endl;
348 PComplexData * pcd = v.GetComplexData();
349
350 if(pcd)
351 mComplexData = new PComplexData(*pcd);
352 else
353 mComplexData = NULL;
354
355 }
356 break;
357
358 case P_DATA_UNDEFINED: // undefined, not an error
359 break;
360 default:
361
362 cerr << "Undefined Data Type in Variant copy constructor. Type: " << mDataType << endl;
363 cerr << v << endl;
364 PError::SignalFatalError("Undefined Data Type.");
365 break;
366
367 }
368
369}
370
371
372
377{
378 //This is needed to destroy counted pointers, but it leads to a
379 //crash later.
380 free_mData();
381}
382
383
387{
388 pInt i;
389 pDouble f;
390
391 if(this->IsInteger() && rhs.IsInteger())
392 {
393 i = this->GetInteger() + rhs.GetInteger();
394 return Variant(i);
395 }
396 else if (this->IsNumber() && rhs.IsNumber())
397 {
398 f = this->GetFloat() + rhs.GetFloat();
399 return Variant(f);
400 }
401 else if (this->IsString() || rhs.IsString())
402 {
403 std::string tmp1, tmp2;
404 tmp1 = GetString();
405 tmp2 = rhs.GetString();
406 tmp1 += tmp2;
407 return Variant(tmp1);
408 }
409 else
410 //There should be an error emmitted here
411 i=0;
412 return Variant(i);
413
414}
415
416
419{
420 pInt i;
421 pDouble f;
422
423 if(this->IsInteger() && rhs.IsInteger())
424 {
425 i = this->GetInteger() - rhs.GetInteger();
426 return Variant(i);
427 }
428 else if (this->IsNumber() && rhs.IsNumber())
429 {
430
431 f = this->GetFloat() - rhs.GetFloat();
432 return Variant(f);
433 }
434 else
435 i=0;
436 return Variant(i);
437
438}
439
440
441
442
445{
446 pInt i;
447 pDouble f;
448
449 if(this->IsInteger() && rhs.IsInteger())
450 {
451 i = this->GetInteger() * rhs.GetInteger();
452 return Variant(i);
453 }
454 else if (this->IsNumber() && rhs.IsNumber())
455 {
456
457 f = this->GetFloat() * rhs.GetFloat();
458 return Variant(f);
459 }
460 else
461 i=0;
462 return Variant(i);
463
464}
465
466
467
470{
471 pInt i;
472 pDouble f;
473
474 if(this->IsNumber() && rhs.IsNumber())
475 {
476
477 f = this->GetFloat() / rhs.GetFloat();
478 return Variant(f);
479 }
480 else
481 i=0;
482 return Variant(i);
483
484}
485
486
487
488
491bool Variant::Equal(const Variant & rhs) const
492{
493 //std::cout << "variant equal: "<< *this << "==" << rhs << endl;
494 //If they are both integers, make equality be exact.
495 //If one is a float, make equality be with some tolerance.
496
497 if(this->IsInteger() && rhs.IsInteger())
498 {
499 return (this->GetInteger() == rhs.GetInteger());
500 }
501 else if (this->IsNumber() && rhs.IsNumber())
502 {
503 return (std::abs(this->GetFloat() - rhs.GetFloat()) < .00000000001);
504 }
505 else if (this->IsString() && rhs.IsString())
506 { //If both are strings, compare them
507
508 //Get copies of the strings.
509 std::string str1 = this->GetString();
510 std::string str2 = rhs.GetString();
511
512 //strcmp returns 0 if they are identical, a number otherwise
513 bool b = (str1 == str2);
514 return b;
515 }
516 else if (this->IsStackSignal() && rhs.IsStackSignal())
517 {
518 return (this->GetSignal() == rhs.GetSignal());
519 }
520 else if (this->IsComplexData() && rhs.IsComplexData())
521 {
522 // Compare complex data objects by their underlying pointer addresses
523 // Two Variants are equal if they reference the SAME object instance
524 PComplexData* pcd1 = this->GetComplexData();
525 PComplexData* pcd2 = rhs.GetComplexData();
526
527 if(!pcd1 || !pcd2)
528 return false; // One or both are null
529
530 // Get the underlying object pointers and compare
533
534 // Compare raw pointers - same object instance?
535 return (obj1.get() == obj2.get());
536 }
537 return false;
538}
539
540
543bool Variant::Less(const Variant & rhs) const
544{
545
546 if (this->IsNumber() && rhs.IsNumber())
547 {
548 return ((this->GetFloat()) < (rhs.GetFloat()));
549 }
550 else if (this->IsString() && rhs.IsString())
551 { //If both are strings, compare them
552
553 //Get copies of the strings.
554 std::string str1 = this->GetString();
555 std::string str2 = rhs.GetString();
556
557 return str1 < str2;
558 }
559 else if (this->IsFunction() && rhs.IsFunction())
560 {
561 //Get copies of the strings.
562
563 std::string str1 = this->GetFunctionName();
564 std::string str2 = rhs.GetFunctionName();
565
566 return (str1 < str2);
567 }
568 //This should be handled more elegantly.
569 return false;
570}
571
572
573
574//The following overloaded operators use the above
575//::Equal() and ::Less() methods, and each other.
576bool Variant::operator == ( const Variant & rhs) const
577{ return Equal(rhs); }
578
579
580
581bool Variant::operator != ( const Variant & rhs) const
582{ return ! ((*this) == rhs); }
583
584
585
586bool Variant::operator < ( const Variant & rhs) const
587{ return Less(rhs); }
588
589
590
591bool Variant::operator > ( const Variant & rhs) const
592{ return rhs < (*this); }
593
594
595
596bool Variant::operator <= ( const Variant & rhs) const
597{ return ! ((*this) > rhs); }
598
599
600
601bool Variant::operator >= ( const Variant & rhs) const
602{ return rhs <= (*this); }
603
604
605
606
607
611{
612 // Debug: std::cout << "[VARIANT] Assignment operator called. Old type: " << mDataType
613 // << " (" << GetDataTypeName() << "), New type: " << value.GetDataType()
614 // << " (" << value.GetDataTypeName() << ")" << std::endl;
615
616 //First, clean up 'this' if it contains data on free store
617 // (e.g., a Variable or a string)
618 free_mData();
619
620 mDataType=value.GetDataType();
621 switch(mDataType)
622 {
623 case P_DATA_NUMBER_INTEGER: // an integer
624 mData.iNumber = value.GetInteger();
625 break;
626
627 case P_DATA_NUMBER_FLOAT: // a float
628 mData.fNumber = value.GetFloat();
629 break;
630
631 case P_DATA_STRING:
632 mData.String = strdup(value.GetString().c_str());
633 break;
634
635 case P_DATA_LOCALVARIABLE: // a char* variable name
636 case P_DATA_GLOBALVARIABLE: // a char* variable name
637 mData.Variable = strdup(value.GetVariableName().c_str());
638 break;
639
640 case P_DATA_FUNCTION:
641 mData.Function = strdup(value.GetFunctionName().c_str());
642 break;
643
645 mData.pFunction = value.GetFunctionPointer();
646 break;
647
649 mData.Signal = value.GetSignal();
650 break;
651
653 {
654 PComplexData * tmp = value.GetComplexData();
655 //tmp is a pointer to complex data, which
656 //is just a holder for the object. We want to make a
657 //copy of tmp
658 mComplexData = new PComplexData(*tmp);
659 break;
660 }
661 case P_DATA_UNDEFINED: // undefined, error
662 default:
663 PError::SignalFatalError( "Undefined Variant type in Variant::operator = (Variant).");
664 break;
665 }
666 return (*this);
667}
668
670{
671 //First, clean up 'this' if it contains data on free store
672 // (e.g., a Variable or a string)
673 free_mData();
674
675 mDataType = P_DATA_NUMBER_FLOAT;
676 mData.fNumber = value;
677 return *this;
678}
679
680
682{
683 //First, clean up 'this' if it contains data on free store
684 // (e.g., a Variable or a string)
685 free_mData();
686
687
688 mDataType = P_DATA_NUMBER_INTEGER;
689 mData.iNumber = value;
690 return *this;
691}
692
693
694Variant Variant::operator = (const long unsigned int & value)
695{
696 //First, clean up 'this' if it contains data on free store
697 // (e.g., a Variable or a string)
698 free_mData();
699
700
701 mDataType = P_DATA_NUMBER_INTEGER;
702 mData.iNumber = value;
703 return *this;
704}
705
706#ifndef PEBL_EMSCRIPTEN
708{
709 //First, clean up 'this' if it contains data on free store
710 // (e.g., a Variable or a string)
711 free_mData();
712
713 mDataType = P_DATA_NUMBER_INTEGER;
714 mData.iNumber = (pInt)value;
715 return *this;
716}
717
718Variant Variant::operator = (const double & value)
719{
720 //First, clean up 'this' if it contains data on free store
721 // (e.g., a Variable or a string)
722 free_mData();
723
724 mDataType = P_DATA_NUMBER_FLOAT;
725 mData.fNumber = (pDouble)value;
726 return *this;
727}
728#endif
729
730Variant Variant::operator = (const float & value)
731{
732 //First, clean up 'this' if it contains data on free store
733 // (e.g., a Variable or a string)
734 free_mData();
735
736 mDataType = P_DATA_NUMBER_FLOAT;
737 mData.fNumber = (pDouble)value;
738 return *this;
739}
740
741
742
743
744Variant Variant::operator = (const char * value)
745{
746 //First, clean up 'this' if it contains data on free store
747 // (e.g., a Variable or a string)
748 free_mData();
749
750 mDataType = P_DATA_STRING;
751 mData.String = strdup(value);
752 return *this;
753}
754
755
756
757Variant Variant::operator = (const std::string value)
758{
759 //First, clean up 'this' if it contains data on free store
760 // (e.g., a Variable or a string)
761 free_mData();
762
763 mDataType = P_DATA_STRING;
764 mData.String = strdup(value.c_str());
765 return *this;
766}
767
768
769
771
772ostream & operator << (ostream& out, const Variant& v)
773{
774 switch(v.GetDataType())
775 {
776
777 case P_DATA_NUMBER_INTEGER: // an integer
778 out << v.GetInteger();
779 break;
780
781 case P_DATA_NUMBER_FLOAT: // a float
782 out << v.GetFloat();
783 break;
784
785 case P_DATA_STRING: // a string
786 out << v.GetString();
787 break;
788
789 case P_DATA_LOCALVARIABLE: // a variable
790 case P_DATA_GLOBALVARIABLE: // a variable
791 out << v.GetVariableName();
792 break;
793
794 case P_DATA_FUNCTION: // a function name
795 out << v.GetFunctionName();
796 break;
797
799 out << "Function Pointer" ;
800 break;
801
803 {
804 out << *(v.GetComplexData())<<endl;
805 }
806 break;
807
809 out << v.GetSignalName();
810 break;
811
812
813 case P_DATA_UNDEFINED: // undefined, error
814 default:
815 out << "Trying to print undefined data type in Variant::<<: " << v.GetDataType() << "name: " << v.GetDataTypeName() << endl ;
816 break;
817 }
818
819 return out;
820}
821
822
823//Casting operators
824Variant::operator pInt()
825{
826 return GetInteger();
827}
828
829#ifndef PEBL_EMSCRIPTEN
830Variant::operator int()
831{
832 return static_cast<int>(GetInteger());
833}
834
835#endif
836
837Variant::operator long unsigned int()
838{
839 return static_cast<long unsigned int>(GetInteger());
840}
841
842
843
844Variant::operator pDouble()
845{
846 return GetFloat();
847}
848
849// Variant::operator const char* ()
850// {
851// return GetString();
852// }
853
854
855Variant::operator const std::string () const
856{
857 return GetString();
858}
859
860// Variant::operator char* ()
861// {
862// return strdup(GetString());
863// }
864
865
866Variant::operator bool ()
867{
868 if((*this) == Variant((pInt)0) ||
869 (*this) == Variant((pDouble)0.0) ||
870 (*this) == Variant("") ||
871 (*this) == Variant("F") ||
872 (*this) == Variant("FALSE")
873 )
874
875 return false;
876 else
877 return true;
878}
879
883
886{
887 return mDataType;
888}
889
891std::string Variant::GetDataTypeName() const
892{
893 switch(mDataType)
894 {
896 return "PEBL Integer Type";
897
899 return "PEBL Floating-Point Type";
900
901 case P_DATA_STRING:
902 return "PEBL String Type";
903
905 return "PEBL Local Variable Type";
906
908 return "PEBL Global Variable Type";
909
910 case P_DATA_FUNCTION:
911 return "PEBL Function Type";
912
914 return "PEBL Function Pointer Type";
915
917 return "PEBL Internal Stack Signal Type";
918
920 return "PEBL Complex data within Variant";
921
922 case P_DATA_UNDEFINED:
923 default:
924 return "Undefined PEBL Variant Type";
925 }
926}
927
928
931{
932 return ( mDataType == P_DATA_NUMBER_INTEGER ||
933 mDataType == P_DATA_NUMBER_FLOAT);
934}
935
936
938{
939 return mDataType == P_DATA_NUMBER_FLOAT;
940}
941
943{
944 return mDataType == P_DATA_NUMBER_INTEGER;
945
946}
947
949{
950 return mDataType == P_DATA_STRING;
951}
952
953
955{
956 return( mDataType == P_DATA_LOCALVARIABLE || mDataType == P_DATA_GLOBALVARIABLE);
957}
958
960{
961 return mDataType == P_DATA_LOCALVARIABLE;
962}
963
965{
966 return mDataType == P_DATA_GLOBALVARIABLE;
967}
968
969
971{
972 return mDataType == P_DATA_FUNCTION;
973}
974
975
977{
978 return mDataType == P_DATA_FUNCTION_POINTER;
979}
980
981
982
983
985{
986 return mDataType == P_DATA_COMPLEXDATA;
987}
988
990{
991 return mDataType == P_DATA_STACK_SIGNAL;
992}
993
994
995
996
998{
999 switch(mDataType)
1000 {
1001 case P_DATA_NUMBER_INTEGER: // an integer
1002 return mData.iNumber;
1003
1004 case P_DATA_NUMBER_FLOAT: // a float
1005 return (pInt)mData.fNumber;
1006
1007 case P_DATA_STRING:
1008 return strtol(mData.String,0,10);
1009
1011 case P_DATA_LOCALVARIABLE: //
1012 case P_DATA_GLOBALVARIABLE: //
1013 case P_DATA_FUNCTION: //
1015 case P_DATA_UNDEFINED: // undefined, error
1016 default:
1017 PError::SignalWarning("Erroneous Data type in Variant::GetInteger(); returning 0");
1018 return (pInt)0;
1019 break;
1020 }
1021
1022}
1023
1024
1026{
1027 switch(mDataType)
1028 {
1029 case P_DATA_NUMBER_INTEGER: // an integer
1030 return (pDouble)mData.iNumber;
1031
1032 case P_DATA_NUMBER_FLOAT: // a float
1033 return mData.fNumber;
1034
1035 case P_DATA_STRING:
1036
1037 return PEBLUtility::StringToPDouble(mData.String);
1038
1042 case P_DATA_FUNCTION:
1044 case P_DATA_UNDEFINED: // undefined, error
1045 default:
1046 PError::SignalWarning("Erroneous Data type in Variant::GetFloat(); returning 0");
1047 return (pDouble)0;
1048
1049 }
1050
1051}
1052
1053
1054
1055
1056std::string Variant::GetString() const
1057{
1058
1059 switch(mDataType)
1060 {
1061 case P_DATA_NUMBER_INTEGER: // an integer
1062 {
1063 std::ostringstream o;
1064 o << mData.iNumber;
1065 return o.str();
1066 }
1067
1068 case P_DATA_NUMBER_FLOAT: // a float
1069 {
1070 std::ostringstream o;
1071 o << mData.fNumber;
1072 return o.str();
1073 }
1074
1075 case P_DATA_STRING:
1076 return std::string(mData.String);
1077 case P_DATA_FUNCTION:
1078 return mData.Function;
1079
1080
1083 return std::string(mData.Variable);
1084
1085 case P_DATA_COMPLEXDATA:
1086 {
1087 PComplexData * pcd = GetComplexData();
1089
1090 // cout << *pob << endl;
1091
1092
1093 // std::string tmp = pob->ObjectName();
1094 // return tmp;
1095
1096
1097 std::ostringstream o;
1098 o << *pob << std::flush;
1099
1100 return o.str();
1101
1102// std::stringstream tmp;
1103// tmp << *pob << std::flush;
1104
1105// std::string tmpstring;
1106// tmp >> tmpstring;
1107
1108// return tmpstring.c_str();
1109 // return pcd->GetTypeName().c_str();
1110
1111
1112// cout << *pcd << endl;
1113// cout << "Getting Variant string\n";
1114
1115//
1116// cout << "[[["<< tmpstring << "]]]"<< endl;
1117// cout << "done Getting Variant string\n";
1118// return tmpstring.c_str();
1119
1120 }
1121
1124
1125 case P_DATA_UNDEFINED: // undefined, error
1126 default:
1127 cout << mDataType << endl;
1128 PError::SignalWarning("Erroneous Data type in Variant::GetString");
1129 return "";
1130
1131 }
1132
1133
1134}
1135
1136
1137//This returns a pointer to the name of the variable.
1138std::string Variant::GetVariableName() const
1139{
1140
1141 if( mDataType == P_DATA_LOCALVARIABLE || mDataType == P_DATA_GLOBALVARIABLE)
1142 {
1143 return std::string(mData.Variable);
1144 }
1145 else
1146 {
1147
1148 PError::SignalFatalError("Erroneous Data type in Variant::GetVariableName()");
1149 return NULL;
1150
1151 }
1152}
1153
1154
1155
1156
1157
1158//This returns the name of the variable; if this is a variable.property, it returns
1159//just the first part, and in all caps.
1161{
1162
1163 if( mDataType == P_DATA_LOCALVARIABLE || mDataType == P_DATA_GLOBALVARIABLE)
1164 {
1165
1166 std::string tmp = PEBLUtility::ToUpper(mData.Variable);
1167 std::string::size_type pos = tmp.find(".");
1168 if(pos == std::string::npos)
1169 return tmp;
1170 else
1171 return tmp.substr(0, pos);
1172
1173 }
1174 else
1175 {
1176 PError::SignalFatalError("Erroneous Data type in Variant::GetVariableBaseName()");
1177 return NULL;
1178
1179 }
1180}
1181
1182
1183//This returns the name of the variable; if this is a variable.property, it returns
1184//just the first part.
1186{
1187
1188 if( mDataType == P_DATA_LOCALVARIABLE || mDataType == P_DATA_GLOBALVARIABLE)
1189 {
1190
1191 std::string tmp = PEBLUtility::ToUpper(mData.Variable);
1192 std::string::size_type pos = tmp.find(".");
1193 if(pos == std::string::npos)
1194 return "";
1195 else
1196 return tmp.substr(pos+1,tmp.size());
1197 }
1198 else
1199 {
1200 PError::SignalFatalError("Erroneous Data type in Variant::GetVariablePropertyName()");
1201 return NULL;
1202
1203 }
1204}
1205
1206
1207//This returns the name of the function.
1208std::string Variant::GetFunctionName() const
1209{
1210
1211 if( mDataType == P_DATA_FUNCTION)
1212 {
1213
1214 const char* fname = mData.Function;
1215
1216 //hmm--memory error here in efence.
1217 //may have to do with page allocation stuff,
1218 //affecting NOT pebl itself but PEBL+efence.
1219 //try cat /proc/sys/vm/max_map_count
1220 //and something like
1221 //echo 165535 > /proc/sys/vm/max_map_count
1222 std::string tmp = std::string(fname);
1223 //cout <<"tmp obtained" << tmp << endl;
1224 return tmp;
1225 }
1226 else
1227 {
1228
1229 PError::SignalFatalError("Erroneous Data type in Variant::GetFunctionName()");
1230 return NULL;
1231 }
1232}
1233
1234
1235//This returns a pointer to the name of the function.
1237{
1238
1239 if( mDataType == P_DATA_STACK_SIGNAL)
1240 {
1241
1242 int val = GetSignal();
1243 switch (val)
1244 {
1245 case STACK_LIST_HEAD:
1246 return Variant(val)+Variant("|STACK_LIST_HEAD");
1247 case STACK_RETURN_DUMMY:
1248 return Variant(val)+Variant("|STACK_RETURN_DUMMY");
1250 return Variant(val)+Variant("|STACK_TERMINATE_EVENT_LOOP");
1251 case STACK_BREAK:
1252 return Variant(val)+Variant("|STACK_BREAK");
1253 case STACK_UNDEFINED:
1254 default:
1255 return Variant(val)+Variant("STACK_UNDEFINED");
1256
1257 }
1258 }else{
1259 return STACK_UNDEFINED;
1260 }
1261}
1262
1263
1264
1266{
1267
1268 if( mDataType == P_DATA_STACK_SIGNAL)
1269 {
1270 return mData.Signal;
1271 }else
1272 {
1273 return STACK_UNDEFINED;
1274 }
1275}
1276
1277
1278
1279//This returns a pointer to the name of the function.
1281{
1282
1283 if( mDataType == P_DATA_FUNCTION_POINTER)
1284 {
1285 return mData.pFunction;
1286 }
1287 else
1288 {
1289 return NULL;
1290 }
1291}
1292
1293
1294
1295
1296
1300{
1301 return mComplexData;
1302}
1303
1304
1305
1310{
1311 mComplexData = data;
1312}
1313
1314
1315
1321{
1322 // Debug: std::cout << "[VARIANT] free_mData() called. Type: " << mDataType
1323 // << ", mComplexData: " << mComplexData << std::endl;
1324
1325 if(mComplexData)
1326 {
1327 // Debug: std::cout << "[VARIANT] Deleting PComplexData at: " << mComplexData << std::endl;
1328 delete mComplexData;
1329 mComplexData =NULL;
1330
1331 //mDataType=P_DATA_UNDEFINED;
1332 } else
1333 {
1334
1335 if(mDataType == P_DATA_STRING )
1336 {
1337 if(mData.String)
1338 {
1339 free(mData.String);
1340 mData.String = NULL;
1341 }
1342 }
1343 else if(IsVariable())
1344 {
1345 if(mData.Variable)
1346 {
1347 free(mData.Variable);
1348 mData.Variable = NULL;
1349 }
1350 }
1351 else if(mDataType == P_DATA_FUNCTION)
1352 {
1353 if(mData.Function)
1354 {
1355 free(mData.Function);
1356 mData.Function = NULL;
1357 }
1358 }
1359
1360 else if(mDataType == P_DATA_COMPLEXDATA)
1361 {
1362 }
1363
1364 }
1365
1366 // mDataType = P_DATA_UNDEFINED;
1367}
#define NULL
Definition BinReloc.cpp:317
#define pInt
Definition Defs.h:8
#define pDouble
Definition Defs.h:7
ostream & operator<<(ostream &out, const Variant &v)
overload operator<<
Definition Variant.cpp:772
VariantDataType
Definition Variant.h:40
@ P_DATA_UNDEFINED
Definition Variant.h:41
@ P_DATA_LOCALVARIABLE
Definition Variant.h:48
@ P_DATA_STACK_SIGNAL
Definition Variant.h:42
@ P_DATA_FUNCTION_POINTER
Definition Variant.h:44
@ P_DATA_STRING
Definition Variant.h:47
@ P_DATA_COMPLEXDATA
Definition Variant.h:50
@ P_DATA_NUMBER_INTEGER
Definition Variant.h:45
@ P_DATA_NUMBER_FLOAT
Definition Variant.h:46
@ P_DATA_FUNCTION
Definition Variant.h:43
@ P_DATA_GLOBALVARIABLE
Definition Variant.h:49
StackSignalType
Definition Variant.h:54
@ STACK_UNDEFINED
Definition Variant.h:55
@ STACK_LIST_HEAD
Definition Variant.h:56
@ STACK_BREAK
Definition Variant.h:59
@ STACK_TERMINATE_EVENT_LOOP
Definition Variant.h:58
@ STACK_RETURN_DUMMY
Definition Variant.h:57
Variant(* pFunc)(Variant)
Definition Variant.h:64
counted_ptr< PEBLObjectBase > GetObject() const
Variant operator/(const Variant &rhs) const
This overloads the / operator for Variants.
Definition Variant.cpp:469
bool IsComplexData() const
Definition Variant.cpp:984
pInt GetInteger() const
Definition Variant.cpp:997
bool Less(const Variant &rhs) const
Primitive Comparing Method.
Definition Variant.cpp:543
bool operator!=(const Variant &rhs) const
Definition Variant.cpp:581
bool IsGlobalVariable() const
Definition Variant.cpp:964
std::string GetVariablePropertyName() const
Definition Variant.cpp:1185
bool Equal(const Variant &rhs) const
Definition Variant.cpp:491
Variant operator-(const Variant &rhs) const
This overloads the - operator for Variants.
Definition Variant.cpp:418
bool IsString() const
Definition Variant.cpp:948
pFunc GetFunctionPointer() const
Definition Variant.cpp:1280
bool IsStackSignal() const
Definition Variant.cpp:989
Variant operator=(const Variant &value)
Assignment Operator (overloaded)
Definition Variant.cpp:610
void free_mData()
Definition Variant.cpp:1320
bool IsFunctionPointer() const
Definition Variant.cpp:976
bool operator<=(const Variant &rhs) const
Definition Variant.cpp:596
bool IsFunction() const
Definition Variant.cpp:970
bool IsFloat() const
Definition Variant.cpp:937
std::string GetVariableName() const
Definition Variant.cpp:1138
bool operator>(const Variant &rhs) const
Definition Variant.cpp:591
std::string GetString() const
Definition Variant.cpp:1056
bool IsVariable() const
Definition Variant.cpp:954
bool IsInteger() const
Definition Variant.cpp:942
StackSignalType GetSignal() const
Definition Variant.cpp:1265
bool operator==(const Variant &rhs) const
Definition Variant.cpp:576
PComplexData * GetComplexData() const
Definition Variant.cpp:1299
pDouble GetFloat() const
Definition Variant.cpp:1025
bool IsNumber() const
This tests whether the Variant is a number (i.e., a float or an integer.)
Definition Variant.cpp:930
void SetComplexData(PComplexData *data)
Definition Variant.cpp:1309
Variant GetSignalName() const
Definition Variant.cpp:1236
bool IsLocalVariable() const
Definition Variant.cpp:959
Variant operator*(const Variant &rhs) const
This overloads the * operator for Variants.
Definition Variant.cpp:444
std::string GetDataTypeName() const
This returns the type as a string.
Definition Variant.cpp:891
bool operator>=(const Variant &rhs) const
Definition Variant.cpp:601
std::string GetVariableBaseName() const
Definition Variant.cpp:1160
bool operator<(const Variant &rhs) const
Definition Variant.cpp:586
std::string GetFunctionName() const
Definition Variant.cpp:1208
VariantDataType GetDataType() const
This returns the type as an enum.
Definition Variant.cpp:885
Variant()
Definition Variant.cpp:58
Variant operator+(const Variant &rhs) const
Definition Variant.cpp:386
~Variant()
Standard Destructor.
Definition Variant.cpp:376
X * get() const
Definition rc_ptrs.h:110
pDouble StringToPDouble(const char *mystring)
std::string ToUpper(const std::string &text)
void SignalWarning(const std::string &message)
Definition PError.cpp:119
void SignalFatalError(const std::string &message)