Visualization Library 2.0.0

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

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
VisitorExportToVLB.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 VLXVisitorExportToVLB_INCLUDE_ONCE
33 #define VLXVisitorExportToVLB_INCLUDE_ONCE
34 
35 #include <vlX/Visitor.hpp>
36 #include <vlX/Value.hpp>
37 #include <vlX/BinaryDefs.hpp>
38 #include <vlCore/VirtualFile.hpp>
39 
40 namespace vlX
41 {
44  {
46 
47  public:
49  {
50  mIDSet = NULL;
51  setOutputFile(file);
52  }
53 
54  bool isUsed(const std::string& uid)
55  {
56  if (mIDSet)
57  {
58  std::map< std::string, int >::iterator it = mIDSet->find(uid);
59  if (it != mIDSet->end())
60  return it->second > 1;
61  else
62  {
63  // should not happen
64  VL_TRAP()
65  return false;
66  }
67  }
68  else
69  return true;
70  }
71 
72  void writeValue(VLXValue& value)
73  {
74  switch(value.type())
75  {
76 
78  value.getStructure()->acceptVisitor(this);
79  break;
80 
81  case VLXValue::List:
82  value.getList()->acceptVisitor(this);
83  break;
84 
85  /*
86  case VLXValue::ArrayString:
87  break;
88 
89  case VLXValue::ArrayIdentifier:
90  break;
91 
92  case VLXValue::ArrayID:
93  break;
94  */
95 
97  value.getArrayInteger()->acceptVisitor(this);
98  break;
99 
100  case VLXValue::ArrayReal:
101  value.getArrayReal()->acceptVisitor(this);
102  break;
103 
105  {
106  VLXRawtextBlock* fblock = value.getRawtextBlock();
107  // header
108  mOutputFile->writeUInt8( VLB_ChunkRawtext );
109  // tag
110  writeString( fblock->tag().c_str() );
111  // value
112  writeString( fblock->value().c_str() ); // no decoding needed
113  }
114  break;
115 
116  case VLXValue::String:
117  // header
118  mOutputFile->writeUInt8( VLB_ChunkString );
119  // value
120  writeString( value.getString().c_str() );
121  break;
122 
124  // header
125  mOutputFile->writeUInt8( VLB_ChunkIdentifier );
126  // value
127  writeString( value.getIdentifier().c_str() );
128  break;
129 
130  case VLXValue::ID:
131  // header
132  mOutputFile->writeUInt8( VLB_ChunkID );
133  // value
134  writeString( value.getID().c_str() );
135  break;
136 
137  case VLXValue::Bool:
138  // header
139  mOutputFile->writeUInt8( VLB_ChunkBool );
140  // value
141  mOutputFile->writeUInt8( value.getBool() );
142  break;
143 
144  case VLXValue::Integer:
145  // header
146  mOutputFile->writeUInt8( VLB_ChunkInteger);
147  // value
148  writeInteger( value.getInteger() );
149  break;
150 
151  case VLXValue::Real:
152  // header
153  mOutputFile->writeUInt8( VLB_ChunkRealDouble);
154  // value
155  mOutputFile->writeDouble( value.getReal() );
156  break;
157  }
158  }
159 
160  virtual void visitStructure(VLXStructure* obj)
161  {
162  if (isVisited(obj))
163  {
164  mOutputFile->writeUInt8( VLB_ChunkID );
165  writeString( obj->uid().c_str() );
166  return;
167  }
168 
169  // header
170  mOutputFile->writeUInt8( VLB_ChunkStructure );
171 
172  // tag
173  writeString( obj->tag().c_str() );
174 
175  // ID
176  writeString( obj->uid().c_str() );
177 
178  // key/value count
179  writeInteger( obj->value().size() );
180 
181  // values
182  for(size_t i=0; i<obj->value().size(); ++i)
183  {
184  // key
185  writeString(obj->value()[i].key().c_str());
186 
187  // value
188  writeValue(obj->value()[i].value());
189  }
190  }
191 
192  virtual void visitList(VLXList* list)
193  {
194  // this should happen only if the user manually creates loops
195  if (isVisited(list))
196  {
197  vl::Log::warning("VisitorExportToVLT: cycle detected on VLXList.\n");
198  return;
199  }
200 
201  // header
202  mOutputFile->writeUInt8( VLB_ChunkList );
203 
204  // tag
205  writeString( list->tag().c_str() );
206 
207  // value count
208  writeInteger( list->value().size() );
209 
210  // values
211  for(size_t i=0; i<list->value().size(); ++i)
212  writeValue(list->value()[i]);
213  }
214 
215  virtual void visitArray(VLXArrayInteger* arr)
216  {
217  // header
218  mOutputFile->writeUInt8( VLB_ChunkArrayInteger );
219 
220  // tag
221  writeString(arr->tag().c_str());
222 
223  // value count
224  writeInteger(arr->value().size());
225 
226  // value
227  if (arr->value().size() > 0)
228  {
229  std::vector<unsigned char> encoded;
230  encodeIntegers(&arr->value()[0], (int)arr->value().size(), encoded); VL_CHECK(encoded.size())
231  writeInteger(encoded.size());
232  mOutputFile->writeUInt8(&encoded[0], encoded.size());
233  }
234  }
235 
236  bool needsDoublePrecision(const double* in, size_t count)
237  {
238  for(size_t i=0; i<count; ++i)
239  {
240  float f = (float)in[i];
241  if ((double)f != in[i])
242  return true;
243  }
244 
245  return false;
246  }
247 
248  virtual void visitArray(VLXArrayReal* arr)
249  {
250  bool needs_double = arr->value().empty() ? false : needsDoublePrecision(&arr->value()[0], arr->value().size());
251 
252  // header
253  mOutputFile->writeUInt8( (unsigned char)(needs_double ? VLB_ChunkArrayRealDouble : VLB_ChunkArrayRealFloat) );
254  // tag
255  writeString(arr->tag().c_str());
256  // count
257  writeInteger(arr->value().size());
258  // value
259  if (arr->value().size())
260  {
261 #if 1
262  if (needs_double)
263  mOutputFile->writeDouble(&arr->value().front(), arr->value().size());
264  else
265  {
266  std::vector<float> floats;
267  floats.resize(arr->value().size());
268  for(size_t i=0; i<arr->value().size(); ++i)
269  floats[i] = (float)arr->value()[i];
270  mOutputFile->writeFloat(&floats[0], floats.size());
271  }
272 #else
273  std::vector<unsigned char> zipped;
274  compress( &arr->value()[0], arr->value().size() * sizeof(arr->value()[0]), zipped, 1 );
275  writeInteger( zipped.size() );
276  mOutputFile->write(&zipped[0], zipped.size());
277 #endif
278  }
279  }
280 
281  /*
282  virtual void visitArray(VLXArrayString* arr)
283  {
284  }
285 
286  virtual void visitArray(VLXArrayIdentifier* arr)
287  {
288  }
289 
290  virtual void visitArray(VLXArrayID* arr)
291  {
292  }
293  */
294 
295  void writeHeader()
296  {
297  // see http://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/ for more info on why I choose these characters.
298  unsigned char vlx_identifier[] = { 0xAB, 'V', 'L', 'X', 0xBB, 0x0D, 0x0A, 0x1A, 0x0A };
299 
300  mOutputFile->write(vlx_identifier, sizeof(vlx_identifier));
301  mOutputFile->writeUInt16(VL_SERIALIZER_VERSION); // "version" (16 bits uint)
302  mOutputFile->write("ascii", 5+1); // "encoding" (zero terminated string)
303  mOutputFile->writeUInt32(0); // "flags" (reserved for the future)
304  }
305 
306  void writeString(const char* str)
307  {
308  size_t len = strlen(str);
309  writeInteger(len);
310  mOutputFile->write(str, len);
311  }
312 
313  void writeInteger(long long n)
314  {
315 #if 0
316  mOutputFile->writeSInt64(n);
317 #else
318  const unsigned char nxt_flag = 0x80;
319  const unsigned char neg_flag = 0x40;
320  unsigned char bytes[12]; memset(bytes, 0, sizeof(bytes)); // should take maximum 10 bytes
321  unsigned char* byte = bytes;
322  if (n < 0)
323  {
324  n = -n;
325  *byte = neg_flag;
326  }
327  // lower 6 bits
328  *byte |= n & 0x3F; n >>= 6;
329  *byte |= n ? nxt_flag : 0;
330  ++byte; // --> output
331  // rest of the bytes
332  while (n)
333  {
334  *byte = n & 0x7F; n >>= 7;
335  *byte |= n ? nxt_flag : 0;
336  ++byte; // --> output
337  }
338  mOutputFile->write(bytes, byte - bytes);
339 #endif
340  }
341 
342  void encodeIntegers(long long* val, int count, std::vector<unsigned char>& out)
343  {
344  const unsigned char nxt_flag = 0x80;
345  const unsigned char neg_flag = 0x40;
346  out.reserve(count);
347  for( int i=0; i<count; ++i)
348  {
349  unsigned char byte = 0;
350  long long n = val[i];
351  if (n < 0)
352  {
353  n = -n;
354  byte = neg_flag;
355  }
356  // lower 6 bits
357  byte |= n & 0x3F; n >>= 6;
358  byte |= n ? nxt_flag : 0;
359  out.push_back(byte);
360  // rest of the bytes
361  while (n)
362  {
363  byte = n & 0x7F; n >>= 7;
364  byte |= n ? nxt_flag : 0;
365  out.push_back(byte);
366  }
367  }
368  }
369 
370  void setIDSet(std::map< std::string, int >* uids) { mIDSet = uids; }
371 
372  std::map< std::string, int >* uidSet() { return mIDSet; }
373 
374  const std::map< std::string, int >* uidSet() const { return mIDSet; }
375 
377  {
378  mOutputFile = file;
379  if (file)
380  {
381  file->close();
382  file->open(vl::OM_WriteOnly);
383  }
384  }
385 
386  vl::VirtualFile* outputFile() { return mOutputFile.get(); }
387 
388  const vl::VirtualFile* outputFile() const { return mOutputFile.get(); }
389 
390  private:
391  std::map< std::string, int >* mIDSet;
392  vl::ref<vl::VirtualFile> mOutputFile;
393  };
394 }
395 
396 #endif
VLXRawtextBlock * getRawtextBlock()
Definition: Value.hpp:418
bool needsDoublePrecision(const double *in, size_t count)
void setOutputFile(vl::VirtualFile *file)
Wrapper for all VLX value types.
Definition: Value.hpp:240
const T * get() const
Definition: Object.hpp:128
An abstract class representing a file.
Definition: VirtualFile.hpp:60
long long writeDouble(double data, bool little_endian_data=true)
Writes a single entry. Returns the number of bytes written.
virtual void acceptVisitor(Visitor *v)
Definition: Value.hpp:151
long long writeUInt16(unsigned short data, bool little_endian_data=true)
Writes a single entry. Returns the number of bytes written.
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
std::string & value()
Definition: Value.hpp:84
void encodeIntegers(long long *val, int count, std::vector< unsigned char > &out)
const std::map< std::string, int > * uidSet() const
long long writeUInt8(unsigned char data)
Writes a single entry. Returns the number of bytes written.
An array of 64 bits floating point numbers, can also have a tag.
Definition: Value.hpp:144
double getReal() const
Definition: Value.hpp:506
void setIDSet(std::map< std::string, int > *uids)
const vl::VirtualFile * outputFile() const
long long writeSInt64(long long data, bool little_endian_data=true)
Writes a single entry. Returns the number of bytes written.
const std::string & getID() const
Definition: Value.hpp:484
virtual void acceptVisitor(Visitor *v)
Definition: Value.hpp:650
long long writeFloat(float data, bool little_endian_data=true)
Writes a single entry. Returns the number of bytes written.
VLXStructure * getStructure()
Definition: Value.hpp:402
bool isUsed(const std::string &uid)
#define VL_INSTRUMENT_CLASS(ClassName, BaseClass)
Definition: TypeInfo.hpp:122
virtual void close()=0
Closes the file.
long long writeUInt32(unsigned int data, bool little_endian_data=true)
Writes a single entry. Returns the number of bytes written.
std::vector< VLXValue > & value()
Definition: Value.hpp:652
std::map< std::string, int > * uidSet()
VisitorExportToVLB(vl::VirtualFile *file=NULL)
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 visitList(VLXList *list)
#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
Translates a VLX hierarchy into VLB format writing to the provided VirtualFile.
void writeValue(VLXValue &value)
virtual void visitStructure(VLXStructure *obj)
long long write(const void *buffer, long long byte_count)
Writes byte_count bytes to a file. Returns the number of bytes actually written.
Definition: VirtualFile.cpp:90
virtual bool open(EOpenMode mode)=0
Opens the file in the specified mode.
virtual void visitArray(VLXArrayInteger *arr)
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
void writeInteger(long long n)
A block of raw text.
Definition: Value.hpp:71
std::vector< T > & value()
Definition: Value.hpp:116
Base class for all visitors visiting a VLX hierarchy.
Definition: Visitor.hpp:53
const std::string & uid() const
Definition: Value.hpp:605
bool getBool() const
Definition: Value.hpp:517
vl::VirtualFile * outputFile()
VLXArrayInteger * getArrayInteger()
Definition: Value.hpp:444
EType type() const
Definition: Value.hpp:396
bool isVisited(void *node)
Definition: Visitor.hpp:69
const std::string & getString() const
Definition: Value.hpp:460
virtual void acceptVisitor(Visitor *v)
Definition: Value.hpp:140
#define VL_CHECK(expr)
Definition: checks.hpp:73
VLXArrayReal * getArrayReal()
Definition: Value.hpp:447
virtual void visitArray(VLXArrayReal *arr)
bool compress(const void *data, size_t size, std::vector< unsigned char > &out, int level)
void writeString(const char *str)
const std::string & getIdentifier() const
Definition: Value.hpp:472