]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/cpp/DataBoardTest/DataBoard/RecordValue.cpp
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.databoard / cpp / DataBoardTest / DataBoard / RecordValue.cpp
1 #include "RecordValue.h"
2
3 #include "RecordType.h"
4 #include "OptionalType.h"
5
6 #include "Component.h"
7
8 #include "Constants.h"
9
10 #include <sstream>
11
12 namespace Databoard {
13         namespace Value {
14                 RecordValue::RecordValue(Databoard::Type::DataType* dataBoard) : Value(dataBoard), fieldCount(0)
15                 {
16                         Databoard::Type::RecordType* recordType = dynamic_cast<Databoard::Type::RecordType*>(dataBoard);
17
18                         if(recordType != NULL)
19                         {
20                                 fieldCount = recordType->count();
21
22                                 if(fieldCount > 0)
23                                 {
24                                         fields = new Value*[fieldCount];
25
26                                         for(int i = 0; i < fieldCount; ++i)
27                                         {
28                                                 fields[i] = NULL;
29                                         }
30                                 }
31                         }
32                 }
33
34                 RecordValue::~RecordValue()
35                 {
36                         for(int i = 0; i < fieldCount; ++i)
37                         {
38                                 delete fields[i];
39                         }
40
41                         delete[] fields;
42                 }
43
44                 void RecordValue::setField(int fieldIndex, Value* value)
45                 {
46                         if(fieldIndex >= 0 && fieldIndex < fieldCount)
47                         {
48                                 fields[fieldIndex] = value;
49                         }
50                 }
51
52                 int RecordValue::count()
53                 {
54                         return fieldCount;
55                 }
56
57                 Value* RecordValue::getField(int fieldIndex)
58                 {
59                         if(fieldIndex >= 0 && fieldIndex < fieldCount)
60                         {
61                                 return fields[fieldIndex];
62                         }
63                         else
64                         {
65                                 return NULL;
66                         }
67                 }
68
69                 std::string RecordValue::writeOut(int indent)
70                 {
71                         Databoard::Type::RecordType* recordType = dynamic_cast<Databoard::Type::RecordType*>(dataBoard);
72
73                         bool isTuple = true;
74
75                         for(int i = 0; i < (int)recordType->count(); ++i)
76                         {
77                                 std::istringstream oss(recordType->getComponent(i)->getName());
78
79                                 int name;
80
81                                 oss >> name;
82
83                                 if(name != i)
84                                 {
85                                         isTuple = false;
86
87                                         break;
88                                 }
89                         }
90
91                         std::string s;
92
93                         if(isTuple == false)
94                         {
95                                 s += "{\n";
96                         }
97                         else
98                         {
99                                 s += "( ";
100                         }
101
102                         indent += 1;
103
104                         for(int i = 0; i < fieldCount; ++i)
105                         {
106                                 if(isTuple == false)
107                                 {
108                                         s.append(indent * 2, ' ');
109
110                                         s += recordType->getComponent(i)->getName() + " = ";
111                                 }
112
113                                 if(fields[i] != NULL)
114                                 {
115                                         s += fields[i]->writeOut(indent);
116
117                                         if(i != (fieldCount-1))
118                                         {
119                                                 s += ",";
120                                         }
121                                 }
122
123                                 if(isTuple == false)
124                                 {
125                                         s += "\n";
126                                 }
127                                 else
128                                 {
129                                         s += " ";
130                                 }
131                         }
132
133                         indent -= 1;
134
135                         if(isTuple == false)
136                         {
137                                 s.append(indent * 2, ' ');
138
139                                 s += "}";
140                         }
141                         else
142                         {
143                                 s += ")";
144                         }
145
146                         return s;
147                 }
148
149                 bool RecordValue::equals(const Value* other)
150                 {
151                         RecordValue* o = (RecordValue*)other;
152
153                         if(this->count() < o->count())
154                         {
155                                 return true;
156                         }
157                         else if(this->count() > o->count())
158                         {
159                                 return false;
160                         }
161
162                         for(int i = 0; i <(int)this->count(); ++i)
163                         {
164                                 if(this->getField(i) < o->getField(i))
165                                 {
166                                         return true;
167                                 }
168                         }
169
170                         return true;
171
172                 }
173
174                 std::string RecordValue::isValid()
175                 {
176                         Databoard::Type::RecordType* recordType = dynamic_cast<Databoard::Type::RecordType*>(dataBoard);
177
178                         if(recordType == NULL)
179                         {
180                                 return "RecordValue: Type is not record.";
181                         }
182
183                         if(fieldCount != recordType->count())
184                         {
185                                 return "RecordValue: field count mismatch.";
186                         }
187
188                         for(int i = 0; i < fieldCount; ++i)
189                         {
190                                 if(fields[i] == NULL)
191                                 {
192                                         Databoard::Type::OptionalType* optionalType = dynamic_cast<Databoard::Type::OptionalType*>(recordType->getComponent(i)->getDataBoard());
193
194                                         if(optionalType == NULL)
195                                         {
196                                                 return "RecordValue: Required field is missing.";
197                                         }
198                                 }
199                                 else
200                                 {
201                                         std::string fieldValidity = fields[i]->isValid();
202
203                                         if(fieldValidity.length() > 0)
204                                         {
205                                                 return fieldValidity;
206                                         }
207                                 }
208                         }
209
210                         return STR_EMPTY;
211                 }
212         }
213 }