Visualization Library 2.1.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
VisitorExportToVLT.hpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #ifndef VLXVisitorExportToVLT_INCLUDE_ONCE
33 #define VLXVisitorExportToVLT_INCLUDE_ONCE
34 
35 #include <vlX/Visitor.hpp>
36 #include <vlX/Value.hpp>
37 #include <cstdarg>
38 
39 namespace vlX
40 {
43  {
45 
46  public:
48  {
49  mIndent = 0;
50  mAssign = false;
51  mIDSet = NULL;
52  mFormatBuffer.resize(4096);
53  }
54 
55  bool isUsed(const std::string& uid)
56  {
57  if (mIDSet)
58  {
59  std::map< std::string, int >::iterator it = mIDSet->find(uid);
60  if (it != mIDSet->end())
61  return it->second > 1;
62  else
63  {
64  // should not happen
65  VL_TRAP()
66  return false;
67  }
68  }
69  else
70  return true;
71  }
72 
73  void indent()
74  {
75  if (mAssign)
76  mAssign = false;
77  else
78  {
79  switch(mIndent)
80  {
81  case 0: break;
82  case 1: output("\t"); break;
83  case 2: output("\t\t"); break;
84  case 3: output("\t\t\t"); break;
85  case 4: output("\t\t\t\t"); break;
86  case 5: output("\t\t\t\t\t"); break;
87  case 6: output("\t\t\t\t\t\t"); break;
88  case 7: output("\t\t\t\t\t\t\t"); break;
89  case 8: output("\t\t\t\t\t\t\t\t"); break;
90  case 9: output("\t\t\t\t\t\t\t\t\t"); break;
91  default:
92  output("\t\t\t\t\t\t\t\t\t");
93  for(int i=9; i<mIndent; ++i)
94  output("\t");
95  }
96  }
97  }
98 
99  void format(const char* fmt, ...)
100  {
101  mFormatBuffer[0] = 0;
102 
103  va_list ap;
104  va_start(ap, fmt);
105  vsnprintf(&mFormatBuffer[0], mFormatBuffer.size(), fmt, ap);
106  va_end(ap);
107 
108  output(&mFormatBuffer[0]);
109  }
110 
111  void visitValue(VLXValue& value)
112  {
113  switch(value.type())
114  {
115  case VLXValue::Structure:
116  value.getStructure()->acceptVisitor(this);
117  break;
118 
119  case VLXValue::List:
120  value.getList()->acceptVisitor(this);
121  break;
122 
124  value.getArrayInteger()->acceptVisitor(this);
125  break;
126 
127  case VLXValue::ArrayReal:
128  value.getArrayReal()->acceptVisitor(this);
129  break;
130 
131  /*
132  case VLXValue::ArrayString:
133  value.getArrayString()->acceptVisitor(this);
134  break;
135 
136  case VLXValue::ArrayIdentifier:
137  value.getArrayIdentifier()->acceptVisitor(this);
138  break;
139 
140  case VLXValue::ArrayID:
141  value.getArrayID()->acceptVisitor(this);
142  break;
143  */
144 
146  {
147  VLXRawtextBlock* fblock = value.getRawtextBlock();
148  if (!fblock->tag().empty())
149  format("%s", fblock->tag().c_str());
150  output("\n"); indent(); format("{<\n%s>}\n", rawtextEncode(fblock->value().c_str()).c_str());
151  }
152  break;
153 
154  case VLXValue::String:
155  indent(); format("\"%s\"\n", stringEncode( value.getString().c_str() ).c_str() );
156  break;
157 
159  indent(); format("%s\n", value.getIdentifier().c_str() ); VL_CHECK( !value.getIdentifier().empty() )
160  break;
161 
162  case VLXValue::ID:
163  indent(); format("%s\n", value.getID().c_str()); VL_CHECK( !value.getID().empty() )
164  break;
165 
166  case VLXValue::Bool:
167  indent(); format("%s\n", value.getBool() ? "true" : "false");
168  break;
169 
170  case VLXValue::Integer:
171  indent(); format("%lld\n", value.getInteger());
172  break;
173 
174  case VLXValue::Real:
175  indent(); format("%f\n", value.getReal());
176  break;
177  }
178  }
179 
180  virtual void visitStructure(VLXStructure* obj)
181  {
182  if (isVisited(obj))
183  {
184  indent(); format("%s\n", obj->uid().c_str());
185  return;
186  }
187 
188  // header tag
189  if (obj->tag().empty())
190  {
191  if (mAssign)
192  {
193  mAssign = false;
194  output("\n");
195  }
196  }
197  else
198  {
199  indent();
200  format("%s", obj->tag().c_str());
201  output("\n");
202  }
203  indent();
204  output("{\n");
205 
206  mIndent++;
207  if ( obj->uid().length() && obj->uid() != "#NULL" && isUsed(obj->uid()) )
208  {
209  indent(); format("ID = %s\n", obj->uid().c_str());
210  }
211 
212  for(size_t i=0; i<obj->value().size(); ++i)
213  {
214  indent(); format("%s = ", obj->value()[i].key().c_str());
215  mAssign = true;
216  visitValue(obj->value()[i].value());
217  }
218  mIndent--;
219  indent(); output("}\n");
220  }
221 
222  virtual void visitList(VLXList* list)
223  {
224  // this should happen only if the user manually creates loops
225  if (isVisited(list))
226  {
227  vl::Log::warning("VisitorExportToVLT: cycle detected on VLXList.\n");
228  return;
229  }
230 
231  if (list->value().size() == 0)
232  {
233  indent(); output("[ ]\n");
234  return;
235  }
236 
237  // header tag
238  if (list->tag().empty())
239  {
240  if (mAssign)
241  {
242  mAssign = false;
243  output("\n");
244  }
245  }
246  else
247  {
248  indent();
249  format("%s", list->tag().c_str());
250  output("\n");
251  }
252  indent();
253  output("[\n");
254 
255  mIndent++;
256  for(size_t i=0; i<list->value().size(); ++i)
257  visitValue(list->value()[i]);
258  mIndent--;
259  indent(); output("]\n");
260  }
261 
262  virtual void visitArray(VLXArrayInteger* arr)
263  {
264  indent(); if (!arr->tag().empty()) format("%s ", arr->tag().c_str()); output("( ");
265  // output in chunks of 10 numbers
266  int i = 0;
267  int size = (int)arr->value().size() - 10;
268  for( ; i < size; i += 10)
269  {
270  format("%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld ",
271  arr->value()[i+0], arr->value()[i+1], arr->value()[i+2], arr->value()[i+3], arr->value()[i+4],
272  arr->value()[i+5], arr->value()[i+6], arr->value()[i+7], arr->value()[i+8], arr->value()[i+9] );
273  }
274  for( ; i < (int)arr->value().size(); ++i )
275  format("%lld ", arr->value()[i]);
276  VL_CHECK( i == (int)arr->value().size() )
277  output(")\n");
278  }
279 
280  virtual void visitArray(VLXArrayReal* arr)
281  {
282  indent(); if (!arr->tag().empty()) format("%s ", arr->tag().c_str()); output("( ");
283  // output in chunks of 10 numbers
284  int i = 0;
285  int size = (int)arr->value().size() - 10;
286  for( ; i < size; i += 10)
287  {
288  format("%f %f %f %f %f %f %f %f %f %f ",
289  arr->value()[i+0], arr->value()[i+1], arr->value()[i+2], arr->value()[i+3], arr->value()[i+4],
290  arr->value()[i+5], arr->value()[i+6], arr->value()[i+7], arr->value()[i+8], arr->value()[i+9] );
291  }
292  for( ; i < (int)arr->value().size(); ++i )
293  format("%f ", arr->value()[i]);
294  VL_CHECK( i == (int)arr->value().size() )
295  output(")\n");
296  }
297 
298  /*
299  virtual void visitArray(VLXArrayString* arr)
300  {
301  indent(); if (!arr->tag().empty()) format("%s ", arr->tag().c_str()); output("( ");
302  for(size_t i=0 ;i<arr->value().size(); ++i)
303  output(std::string("\"") + stringEncode(arr->value()[i].c_str()) + "\" ");
304  output(")\n");
305  }
306 
307  virtual void visitArray(VLXArrayIdentifier* arr)
308  {
309  indent(); if (!arr->tag().empty()) format("%s ", arr->tag().c_str()); output("( ");
310  for(size_t i=0 ;i<arr->value().size(); ++i)
311  format("%s ", arr->value()[i].c_str());
312  output(")\n");
313  }
314 
315  virtual void visitArray(VLXArrayID* arr)
316  {
317  indent(); if (!arr->tag().empty()) format("%s ", arr->tag().c_str()); output("( ");
318  for(size_t i=0 ;i<arr->value().size(); ++i)
319  format("%s ", arr->value()[i].uid());
320  output(")\n");
321  }
322  */
323 
324  std::string rawtextEncode(const char* str)
325  {
326  std::string out;
327  out.reserve(32);
328 
329  for(size_t i=0; str[i]; ++i)
330  {
331  if ( str[i] == '}' && !out.empty() && out[ out.size()-1 ] == '>')
332  {
333  out.resize( out.size() - 1 );
334  out += "\\>}";
335  }
336  else
337  out.push_back( str[i] );
338  }
339  return out;
340  }
341 
342  // mic fixme: support \xHH hex notation both input and output.
343  std::string stringEncode(const char* str)
344  {
345  std::string out;
346  for(size_t i=0; str[i]; ++i)
347  {
348  if (str[i] == '"')
349  out += "\\\"";
350  else
351  if (str[i] == '\\')
352  out += "\\\\";
353  else
354  if (str[i] == '\b')
355  out += "\\b";
356  else
357  if (str[i] == '\f')
358  out += "\\f";
359  else
360  if (str[i] == '\n')
361  out += "\\n";
362  else
363  if (str[i] == '\r')
364  out += "\\r";
365  else
366  if (str[i] == '\t')
367  out += "\\t";
368  else
369  out += str[i];
370  }
371  return out;
372  }
373 
374  const std::string& text() const { return mText; }
375 
376  std::string& text() { return mText; }
377 
378  virtual void output(const std::string& str)
379  {
380  output(str.c_str());
381  }
382 
383  virtual void output(const char* str)
384  {
385  // printf(str);
386  mText += str;
387  }
388 
389  void writeHeader()
390  {
391  mText = vl::String::printf("VLX version=%d encoding=ascii\n\n", VL_SERIALIZER_VERSION).toStdString();
392  }
393 
394  void setIDSet(std::map< std::string, int >* uids) { mIDSet = uids; }
395 
396  std::map< std::string, int >* uidSet() { return mIDSet; }
397 
398  const std::map< std::string, int >* uidSet() const { return mIDSet; }
399 
400  private:
401  int mIndent;
402  bool mAssign;
403  std::string mText;
404  std::map< std::string, int >* mIDSet;
405  std::vector<char> mFormatBuffer;
406  };
407 }
408 
409 #endif
VLXRawtextBlock * getRawtextBlock()
Definition: Value.hpp:418
Wrapper for all VLX value types.
Definition: Value.hpp:240
virtual void acceptVisitor(Visitor *v)
Definition: Value.hpp:151
static void warning(const String &message)
Use this function to provide information about situations that might lead to errors or loss of data...
Definition: Log.cpp:155
VLXList * getList()
Definition: Value.hpp:410
virtual void output(const std::string &str)
std::string & value()
Definition: Value.hpp:84
bool isUsed(const std::string &uid)
An array of 64 bits floating point numbers, can also have a tag.
Definition: Value.hpp:144
double getReal() const
Definition: Value.hpp:506
const std::string & text() const
const std::string & getID() const
Definition: Value.hpp:484
virtual void acceptVisitor(Visitor *v)
Definition: Value.hpp:650
VLXStructure * getStructure()
Definition: Value.hpp:402
#define VL_INSTRUMENT_CLASS(ClassName, BaseClass)
Definition: TypeInfo.hpp:122
std::vector< VLXValue > & value()
Definition: Value.hpp:652
void setIDSet(std::map< std::string, int > *uids)
long long getInteger() const
Definition: Value.hpp:495
A list of key/VLXValue pairs, can also have a tag.
Definition: Value.hpp:541
virtual void visitStructure(VLXStructure *obj)
void format(const char *fmt,...)
#define VL_TRAP()
Definition: checks.hpp:70
A simple sequence of VLXValue objects, can also have a tag.
Definition: Value.hpp:634
#define VL_SERIALIZER_VERSION
Definition: Defines.hpp:35
const std::string & tag() const
Definition: Value.hpp:63
std::string stringEncode(const char *str)
virtual void acceptVisitor(Visitor *v)
Definition: Value.hpp:566
std::vector< KeyValue > & value()
Definition: Value.hpp:607
#define NULL
Definition: OpenGLDefs.hpp:81
An array of 64 bits integers, can also have a tag.
Definition: Value.hpp:133
A block of raw text.
Definition: Value.hpp:71
virtual void visitArray(VLXArrayInteger *arr)
virtual void visitArray(VLXArrayReal *arr)
std::vector< T > & value()
Definition: Value.hpp:116
Base class for all visitors visiting a VLX hierarchy.
Definition: Visitor.hpp:53
const std::map< std::string, int > * uidSet() const
const std::string & uid() const
Definition: Value.hpp:605
bool getBool() const
Definition: Value.hpp:517
void visitValue(VLXValue &value)
VLXArrayInteger * getArrayInteger()
Definition: Value.hpp:444
static String printf(const char *fmt,...)
Returns a formatted string using the legacy printf syntax. The resulting string can be maximum 1024 +...
Definition: String.cpp:1510
EType type() const
Definition: Value.hpp:396
std::string toStdString() const
Returns a UTF8 encoded std::string.
Definition: String.cpp:1156
bool isVisited(void *node)
Definition: Visitor.hpp:69
virtual void visitList(VLXList *list)
const std::string & getString() const
Definition: Value.hpp:460
virtual void output(const char *str)
virtual void acceptVisitor(Visitor *v)
Definition: Value.hpp:140
Translates a VLX hierarchy into VLT notation.
#define VL_CHECK(expr)
Definition: checks.hpp:73
std::map< std::string, int > * uidSet()
VLXArrayReal * getArrayReal()
Definition: Value.hpp:447
std::string rawtextEncode(const char *str)
const std::string & getIdentifier() const
Definition: Value.hpp:472