Data.h
Go to the documentation of this file.
1 
20 #ifndef DATA_H_09E4D8E5
21 #define DATA_H_09E4D8E5
22 
23 #include <list>
24 #include <map>
25 #include <memory>
26 #include <type_traits>
27 
28 #include "uscxml/Common.h"
30 #include "uscxml/messages/Blob.h"
31 
32 //#include <xercesc/dom/DOMDocument.hpp>
33 
34 // forward declare
35 namespace XERCESC_NS {
36 class DOMDocument;
37 class DOMNode;
38 }
39 
40 namespace uscxml {
41 
42 static unsigned int _dataIndentation = 1;
43 
44 class USCXML_API Data {
45 public:
46  enum Type {
47  VERBATIM,
48  INTERPRETED,
49  };
50 
51  Data() : node(NULL), type(INTERPRETED) {
52  // silence stupid not used error for statics in gcc
53  (void)_dataIndentation;
54  }
55 
56  explicit Data(const char* data, size_t size, const std::string& mimeType, bool adopt = false);
57 
58  // convenience constructors
59 // explicit Data(bool atom) : node(NULL), type(VERBATIM) {
60 // if (atom) {
61 // this->atom = "true";
62 // } else {
63 // this->atom = "false";
64 // }
65 // }
66 
67  explicit Data(XERCESC_NS::DOMNode* node_) : node(node_) {}
68 
69  explicit Data(const std::string& value) : node(NULL), atom(toStr(value)), type(VERBATIM) {}
70 
71 
72 #ifndef SWIGIMPORTED
73  // swig barfs on this one, have them explictly
74  template <
75  typename T,
76  typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type
77  >
78  explicit Data(T value)
79  : node(NULL), atom(toStr(value)), type(INTERPRETED) {}
80 #endif
81 
82  template <typename T>
83  explicit Data(T value, Type type) : node(NULL), atom(toStr(value)), type(type) {}
84 
85  ~Data() {
86  }
87 
88  void clear() {
89  type = VERBATIM;
90  compound.clear();
91  array.clear();
92  atom.clear();
93  binary = Blob();
94  node = NULL;
95  }
96 
97  bool empty() const {
98  bool hasContent = (atom.length() > 0 || !compound.empty() || !array.empty() || binary || node);
99  return !hasContent;
100  }
101 
102  bool operator<(const Data& other) const {
103  if (other.atom != atom)
104  return other.atom < atom;
105  if (other.array != array)
106  return other.array < array;
107  if (other.compound != compound)
108  return other.compound < compound;
109  if (other.node != node)
110  return other.node < node;
111  if (other.binary != binary)
112  return other.binary < binary;
113  if (other.type != type)
114  return other.type < type;
115 
116  return false;
117  }
118 
119  void merge(const Data& other);
120 
121  bool hasKey(const std::string& key) const {
122  return (!compound.empty() && compound.find(key) != compound.end());
123  }
124 
125 #ifndef SWIGIMPORTED
126 
127  Data& operator[](const std::string& key) {
128  return compound[key];
129  }
130 
131  Data& operator[](const char* key) {
132  return compound[key];
133  }
134 
135  const Data& operator[](const std::string& key) const {
136  return compound.at(key);
137  }
138 
139  const Data& operator[](const char* key) const {
140  return compound.at(key);
141  }
142 
143  Data& operator[](const size_t index) {
144  while(array.size() < index) {
145  array.push_back(Data("", Data::VERBATIM));
146  }
147  std::list<Data>::iterator arrayIter = array.begin();
148  for (size_t i = 0; i < index; i++, arrayIter++) {}
149  return *arrayIter;
150  }
151 #endif
152 
153  const Data at(const std::string& key) const {
154  return at(key.c_str());
155  }
156 
157  const Data at(const char* key) const {
158  if (hasKey(key))
159  return compound.at(key);
160  Data data;
161  return data;
162  }
163 
164  const Data item(const size_t index) const {
165  if (array.size() > index) {
166  std::list<Data>::const_iterator arrayIter = array.begin();
167  for (size_t i = 0; i < index; i++, arrayIter++) {}
168  return *arrayIter;
169  }
170  Data data;
171  return data;
172  }
173 
174  void put(std::string key, const Data& data) {
175  compound[key] = data;
176  }
177 
178  void put(size_t index, const Data& data) {
179  this[index] = data;
180  }
181 
182  bool operator==(const Data &other) const {
183  return !(*this != other);
184  }
185 
186  bool operator!=(const Data &other) const {
187  return (*this < other || other < *this);
188  }
189 
190  operator std::string() const {
191  return atom;
192  }
193 
194  operator std::map<std::string, Data>() {
195  return compound;
196  }
197 
198  operator std::list<Data>() {
199  return array;
200  }
201 
202  static Data fromJSON(const std::string& jsonString);
203  static std::string toJSON(const Data& data);
204  std::string asJSON() const;
205 
206  std::list<Data> getArray() {
207  return array;
208  }
209  void setArray(const std::list<Data>& array) {
210  this->array = array;
211  }
212 
213  std::string getAtom() const {
214  return atom;
215  }
216  void setAtom(const std::string& atom) {
217  this->atom = atom;
218  }
219 
220  Blob getBinary() {
221  return this->binary;
222  }
223  void setBinary(const Blob& binary) {
224  this->binary = binary;
225  }
226 
227  Type getType() {
228  return type;
229  }
230  void setType(const Type type) {
231  this->type = type;
232  }
233 
234  // Bug in SWIG 3.0.8 Python: Data in a map has to be fully qualified!
235  std::map<std::string, uscxml::Data> getCompound() {
236  return compound;
237  }
238 
239  void setCompound(const std::map<std::string, uscxml::Data>& compound) {
240  this->compound = compound;
241  }
242 
243 #ifdef SWIGIMPORTED
244 protected:
245 #endif
246 
247  XERCESC_NS::DOMNode* node;
248 // std::shared_ptr<XERCESC_NS::DOMDocument> adoptedDoc;
249  std::map<std::string, Data> compound;
250  std::list<Data> array;
251  std::string atom;
252  Blob binary;
253  Type type;
254 
255 protected:
256  static std::string jsonEscape(const std::string& expr);
257  static std::string jsonUnescape(const std::string& expr);
258  friend USCXML_API std::ostream& operator<< (std::ostream& os, const Data& data);
259 
260 };
261 
262 USCXML_API std::ostream& operator<< (std::ostream& os, const Data& data);
263 
264 }
265 
266 #endif /* end of include guard: DATA_H_09E4D8E5 */
Definition: Breakpoint.cpp:26
Definition: Breakpoint.h:30
Definition: Blob.h:65
Definition: Data.h:44