# Visualization Library

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

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlCore/VLXVisitorExportToVLB.hpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.org                                               */
    00005 /*                                                                                    */
    00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
    00007 /*  All rights reserved.                                                              */
    00008 /*                                                                                    */
    00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
    00010 /*  are permitted provided that the following conditions are met:                     */
    00011 /*                                                                                    */
    00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
    00013 /*  list of conditions and the following disclaimer.                                  */
    00014 /*                                                                                    */
    00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
    00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
    00017 /*  other materials provided with the distribution.                                   */
    00018 /*                                                                                    */
    00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
    00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
    00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
    00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
    00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
    00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
    00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
    00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
    00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
    00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
    00029 /*                                                                                    */
    00030 /**************************************************************************************/
    00031
    00032 #ifndef VLXVisitorExportToVLB_INCLUDE_ONCE
    00033 #define VLXVisitorExportToVLB_INCLUDE_ONCE
    00034
    00035 #include <vlCore/VLXVisitor.hpp>
    00036 #include <vlCore/VLXValue.hpp>
    00037 #include <vlCore/VLXBinaryDefs.hpp>
    00038 #include <vlCore/VirtualFile.hpp>
    00039
    00040 namespace vl
    00041 {
    00043   class VLXVisitorExportToVLB: public VLXVisitor
    00044   {
    00045     VL_INSTRUMENT_CLASS(vl::VLXVisitorExportToVLB, VLXVisitor)
    00046
    00047   public:
    00048     VLXVisitorExportToVLB(VirtualFile* file = NULL)
    00049     {
    00050       mIDSet = NULL;
    00051       setOutputFile(file);
    00052     }
    00053
    00054     bool isUsed(const std::string& uid)
    00055     {
    00056       if (mIDSet)
    00057       {
    00058         std::map< std::string, int >::iterator it = mIDSet->find(uid);
    00059         if (it != mIDSet->end())
    00060           return it->second > 1;
    00061         else
    00062         {
    00063           // should not happen
    00064           VL_TRAP()
    00065           return false;
    00066         }
    00067       }
    00068       else
    00069         return true;
    00070     }
    00071
    00072     void writeValue(VLXValue& value)
    00073     {
    00074       switch(value.type())
    00075       {
    00076
    00077       case VLXValue::Structure:
    00078         value.getStructure()->acceptVisitor(this);
    00079         break;
    00080
    00081       case VLXValue::List:
    00082         value.getList()->acceptVisitor(this);
    00083         break;
    00084
    00085       /*
    00086       case VLXValue::ArrayString:
    00087         break;
    00088
    00089       case VLXValue::ArrayIdentifier:
    00090         break;
    00091
    00092       case VLXValue::ArrayID:
    00093         break;
    00094       */
    00095
    00096       case VLXValue::ArrayInteger:
    00097         value.getArrayInteger()->acceptVisitor(this);
    00098         break;
    00099
    00100       case VLXValue::ArrayReal:
    00101         value.getArrayReal()->acceptVisitor(this);
    00102         break;
    00103
    00104       case VLXValue::RawtextBlock:
    00105       {
    00106         VLXRawtextBlock* fblock = value.getRawtextBlock();
    00107         // header
    00108         mOutputFile->writeUInt8( VLB_ChunkRawtext );
    00109         // tag
    00110         writeString( fblock->tag().c_str() );
    00111         // value
    00112         writeString( fblock->value().c_str() ); // no decoding needed
    00113       }
    00114       break;
    00115
    00116       case VLXValue::String:
    00117         // header
    00118         mOutputFile->writeUInt8( VLB_ChunkString );
    00119         // value
    00120         writeString( value.getString().c_str() );
    00121         break;
    00122
    00123       case VLXValue::Identifier:
    00124         // header
    00125         mOutputFile->writeUInt8( VLB_ChunkIdentifier );
    00126         // value
    00127         writeString( value.getIdentifier().c_str() );
    00128         break;
    00129
    00130       case VLXValue::ID:
    00131         // header
    00132         mOutputFile->writeUInt8( VLB_ChunkID );
    00133         // value
    00134         writeString( value.getID().c_str() );
    00135         break;
    00136
    00137       case VLXValue::Bool:
    00138         // header
    00139         mOutputFile->writeUInt8( VLB_ChunkBool );
    00140         // value
    00141         mOutputFile->writeUInt8( value.getBool() );
    00142         break;
    00143
    00144       case VLXValue::Integer:
    00145         // header
    00146         mOutputFile->writeUInt8( VLB_ChunkInteger);
    00147         // value
    00148         writeInteger( value.getInteger() );
    00149         break;
    00150
    00151       case VLXValue::Real:
    00152         // header
    00153         mOutputFile->writeUInt8( VLB_ChunkRealDouble);
    00154         // value
    00155         mOutputFile->writeDouble( value.getReal() );
    00156         break;
    00157       }
    00158     }
    00159
    00160     virtual void visitStructure(VLXStructure* obj)
    00161     {
    00162       if (isVisited(obj))
    00163       {
    00164         mOutputFile->writeUInt8( VLB_ChunkID );
    00165         writeString( obj->uid().c_str() );
    00166         return;
    00167       }
    00168
    00169       // header
    00170       mOutputFile->writeUInt8( VLB_ChunkStructure );
    00171
    00172       // tag
    00173       writeString( obj->tag().c_str() );
    00174
    00175       // ID
    00176       writeString( obj->uid().c_str() );
    00177
    00178       // key/value count
    00179       writeInteger( obj->value().size() );
    00180
    00181       // values
    00182       for(size_t i=0; i<obj->value().size(); ++i)
    00183       {
    00184         // key
    00185         writeString(obj->value()[i].key().c_str());
    00186
    00187         // value
    00188         writeValue(obj->value()[i].value());
    00189       }
    00190     }
    00191
    00192     virtual void visitList(VLXList* list)
    00193     {
    00194       // this should happen only if the user manually creates loops
    00195       if (isVisited(list))
    00196       {
    00197         Log::warning("VLXVisitorExportToVLT: cycle detected on VLXList.\n");
    00198         return;
    00199       }
    00200
    00201       // header
    00202       mOutputFile->writeUInt8( VLB_ChunkList );
    00203
    00204       // tag
    00205       writeString( list->tag().c_str() );
    00206
    00207       // value count
    00208       writeInteger( list->value().size() );
    00209
    00210       // values
    00211       for(size_t i=0; i<list->value().size(); ++i)
    00212         writeValue(list->value()[i]);
    00213     }
    00214
    00215     virtual void visitArray(VLXArrayInteger* arr)
    00216     {
    00217       // header
    00218       mOutputFile->writeUInt8( VLB_ChunkArrayInteger );
    00219
    00220       // tag
    00221       writeString(arr->tag().c_str());
    00222
    00223       // value count
    00224       writeInteger(arr->value().size());
    00225
    00226       // value
    00227       if (arr->value().size() > 0)
    00228       {
    00229         std::vector<unsigned char> encoded;
    00230         encodeIntegers(&arr->value()[0], (int)arr->value().size(), encoded); VL_CHECK(encoded.size())
    00231         writeInteger(encoded.size());
    00232         mOutputFile->writeUInt8(&encoded[0], encoded.size());
    00233       }
    00234     }
    00235
    00236     bool needsDoublePrecision(const double* in, size_t count)
    00237     {
    00238       for(size_t i=0; i<count; ++i)
    00239       {
    00240         float f = (float)in[i];
    00241         if ((double)f != in[i])
    00242           return true;
    00243       }
    00244
    00245       return false;
    00246     }
    00247
    00248     virtual void visitArray(VLXArrayReal* arr)
    00249     {
    00250       bool needs_double = arr->value().empty() ? false : needsDoublePrecision(&arr->value()[0], arr->value().size());
    00251
    00252       // header
    00253       mOutputFile->writeUInt8( (unsigned char)(needs_double ? VLB_ChunkArrayRealDouble : VLB_ChunkArrayRealFloat) );
    00254       // tag
    00255       writeString(arr->tag().c_str());
    00256       // count
    00257       writeInteger(arr->value().size());
    00258       // value
    00259       if (arr->value().size())
    00260       {
    00261 #if 1
    00262         if (needs_double)
    00263           mOutputFile->writeDouble(&arr->value().front(), arr->value().size());
    00264         else
    00265         {
    00266           std::vector<float> floats;
    00267           floats.resize(arr->value().size());
    00268           for(size_t i=0; i<arr->value().size(); ++i)
    00269             floats[i] = (float)arr->value()[i];
    00270           mOutputFile->writeFloat(&floats[0], floats.size());
    00271         }
    00272 #else
    00273         std::vector<unsigned char> zipped;
    00274         compress( &arr->value()[0], arr->value().size() * sizeof(arr->value()[0]), zipped, 1 );
    00275         writeInteger( zipped.size() );
    00276         mOutputFile->write(&zipped[0], zipped.size());
    00277 #endif
    00278       }
    00279     }
    00280
    00281     /*
    00282     virtual void visitArray(VLXArrayString* arr)
    00283     {
    00284     }
    00285
    00286     virtual void visitArray(VLXArrayIdentifier* arr)
    00287     {
    00288     }
    00289
    00290     virtual void visitArray(VLXArrayID* arr)
    00291     {
    00292     }
    00293     */
    00294
    00295     void writeHeader()
    00296     {
    00297       // see http://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/ for more info on why I choose these characters.
    00298       unsigned char vlx_identifier[] = { 0xAB, 'V', 'L', 'X', 0xBB, 0x0D, 0x0A, 0x1A, 0x0A };
    00299
    00300       mOutputFile->write(vlx_identifier, sizeof(vlx_identifier));
    00301       mOutputFile->writeUInt16(100);    // "version" (16 bits uint)
    00302       mOutputFile->write("ascii", 5+1); // "encoding" (zero terminated string)
    00303       mOutputFile->writeUInt32(0);      // "flags" (reserved for the future)
    00304     }
    00305
    00306     void writeString(const char* str)
    00307     {
    00308       size_t len = strlen(str);
    00309       writeInteger(len);
    00310       mOutputFile->write(str, len);
    00311     }
    00312
    00313     void writeInteger(long long n)
    00314     {
    00315 #if 0
    00316       mOutputFile->writeSInt64(n);
    00317 #else
    00318       const unsigned char nxt_flag = 0x80;
    00319       const unsigned char neg_flag = 0x40;
    00320       unsigned char bytes[12]; memset(bytes, 0, sizeof(bytes)); // should take maximum 10 bytes
    00321       unsigned char* byte = bytes;
    00322       if (n < 0)
    00323       {
    00324         n = -n;
    00325         *byte = neg_flag;
    00326       }
    00327       // lower 6 bits
    00328       *byte |= n & 0x3F; n >>= 6;
    00329       *byte |= n ? nxt_flag : 0;
    00330       ++byte; // --> output
    00331       // rest of the bytes
    00332       while (n)
    00333       {
    00334         *byte = n & 0x7F; n >>= 7;
    00335         *byte |= n ? nxt_flag : 0;
    00336         ++byte; // --> output
    00337       }
    00338       mOutputFile->write(bytes, byte - bytes);
    00339 #endif
    00340     }
    00341
    00342     void encodeIntegers(long long* val, int count, std::vector<unsigned char>& out)
    00343     {
    00344       const unsigned char nxt_flag = 0x80;
    00345       const unsigned char neg_flag = 0x40;
    00346       out.reserve(count);
    00347       for( int i=0; i<count; ++i)
    00348       {
    00349         unsigned char byte = 0;
    00350         long long n = val[i];
    00351         if (n < 0)
    00352         {
    00353           n = -n;
    00354           byte = neg_flag;
    00355         }
    00356         // lower 6 bits
    00357         byte |= n & 0x3F; n >>= 6;
    00358         byte |= n ? nxt_flag : 0;
    00359         out.push_back(byte);
    00360         // rest of the bytes
    00361         while (n)
    00362         {
    00363           byte = n & 0x7F; n >>= 7;
    00364           byte |= n ? nxt_flag : 0;
    00365           out.push_back(byte);
    00366         }
    00367       }
    00368     }
    00369
    00370     void setIDSet(std::map< std::string, int >* uids) { mIDSet = uids; }
    00371
    00372     std::map< std::string, int >* uidSet() { return mIDSet; }
    00373
    00374     const std::map< std::string, int >* uidSet() const { return mIDSet; }
    00375
    00376     void setOutputFile(VirtualFile* file)
    00377     {
    00378       mOutputFile = file;
    00379       if (file)
    00380       {
    00381         file->close();
    00382         file->open(OM_WriteOnly);
    00383       }
    00384     }
    00385
    00386     VirtualFile* outputFile() { return mOutputFile.get(); }
    00387
    00388     const VirtualFile* outputFile() const { return mOutputFile.get(); }
    00389
    00390   private:
    00391     std::map< std::string, int >* mIDSet;
    00392     ref<VirtualFile> mOutputFile;
    00393   };
    00394 }
    00395
    00396 #endif

Visualization Library v2011.09.1162 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu Jan 26 2012 00:43:33.
Permission is granted to use this page to write and publish articles regarding Visualization Library.