# 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/VLXParserVLB.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 VLXParserVLB_INCLUDE_ONCE
    00033 #define VLXParserVLB_INCLUDE_ONCE
    00034
    00035 #include <vlCore/VLXParser.hpp>
    00036 #include <vlCore/VLXBinaryDefs.hpp>
    00037
    00038 namespace vl
    00039 {
    00041   class VLXParserVLB: public VLXParser
    00042   {
    00043     VL_INSTRUMENT_CLASS(vl::VLXParserVLB, VLXParser)
    00044
    00045   public:
    00046     VLXParserVLB()
    00047     {
    00048       mVersion = 0;
    00049     }
    00050
    00051     bool parseHeader()
    00052     {
    00053       mVersion = 0;
    00054       mEncoding.clear();
    00055       mFlags = 0;
    00056
    00057       // check the header is fine
    00058       unsigned char vlx_identifier[] = { 0xAB, 'V', 'L', 'X', 0xBB, 0x0D, 0x0A, 0x1A, 0x0A };
    00059       unsigned char vlx[sizeof(vlx_identifier)];
    00060       memset(vlx, 0, sizeof(vlx));
    00061       inputFile()->read(vlx, sizeof(vlx));
    00062       if ( memcmp(vlx, vlx_identifier, sizeof(vlx)) != 0 )
    00063         return false;
    00064
    00065       if ( inputFile()->readUInt16(&mVersion,1) != 2 )
    00066         return false;
    00067
    00068       unsigned char ch = 0xFF;
    00069       for( ; inputFile()->readUInt8(&ch, 1) && ch ; ch = 0xFF )
    00070         mEncoding.push_back(ch);
    00071       if (ch)
    00072         return false;
    00073
    00074       if ( inputFile()->readUInt32(&mFlags, 1) != 4 )
    00075         return false;
    00076
    00077       return true;
    00078     }
    00079
    00080     bool readChunk(unsigned char& chunk) { return inputFile()->read(&chunk, 1) == 1; }
    00081
    00082     bool readInteger(long long& n)
    00083     {
    00084 #if 0
    00085       return inputFile()->read(&n, sizeof(n)) == sizeof(n);
    00086 #else
    00087       const unsigned char nxt_flag = 0x80;
    00088       const unsigned char neg_flag = 0x40;
    00089       unsigned char byte = 0;
    00090       if ( inputFile()->read(&byte, 1) != 1 )
    00091         return false;
    00092       bool is_neg = (byte & neg_flag) != 0;
    00093       n = byte & 0x3F;
    00094       int shift = 6;
    00095       while(byte & nxt_flag)
    00096       {
    00097         if ( inputFile()->read(&byte, 1) != 1 )
    00098           return false;
    00099         n |= (long long)(byte & 0x7F) << shift;
    00100         shift += 7;
    00101       }
    00102       if (is_neg)
    00103         n = -n;
    00104       return true;
    00105 #endif
    00106     }
    00107
    00108     void decodeIntegers(const std::vector<unsigned char>& in, std::vector<long long>& out)
    00109     {
    00110       out.reserve(in.size());
    00111       const unsigned char nxt_flag = 0x80;
    00112       const unsigned char neg_flag = 0x40;
    00113       for( size_t i=0 ; i<in.size() ; )
    00114       {
    00115         unsigned char byte = in[i++];
    00116         bool is_neg = (byte & neg_flag) != 0;
    00117         long long n = byte & 0x3F;
    00118         int shift = 6;
    00119         while(byte & nxt_flag)
    00120         {
    00121           byte = in[i++];
    00122           n |= (long long)(byte & 0x7F) << shift;
    00123           shift += 7;
    00124         }
    00125         if (is_neg)
    00126           n = -n;
    00127         // --> output
    00128         out.push_back(n);
    00129       }
    00130     }
    00131
    00132     bool readString(std::string& str)
    00133     {
    00134       long long len = 0;
    00135       if (!readInteger(len))
    00136         return false;
    00137       VL_CHECK(len >= 0 );
    00138       if (len < 0)
    00139         return false;
    00140       if (len == 0)
    00141         return true;
    00142       str.resize((size_t)len);
    00143       bool ok = (size_t)inputFile()->read(&str[0], str.length()) == str.length();
    00144       return ok;
    00145     }
    00146
    00147     bool parse()
    00148     {
    00149       class CloseFileClass
    00150       {
    00151       public:
    00152         CloseFileClass(VirtualFile* f): mFile(f) {}
    00153         ~CloseFileClass()
    00154         {
    00155           if (mFile)
    00156             mFile->close();
    00157         }
    00158       private:
    00159         ref<VirtualFile> mFile;
    00160       } CloseFile(inputFile());
    00161
    00162       inputFile()->close();
    00163       inputFile()->open(OM_ReadOnly);
    00164
    00165       // clear metadata
    00166       mMetadata.clear();
    00167
    00168       // read version and encoding
    00169       mVersion = 0;
    00170       mEncoding.clear();
    00171
    00172       if (!parseHeader())
    00173       {
    00174         Log::error("VLXParserVLB : error parsing VLB header.\n");
    00175         return false;
    00176       }
    00177
    00178       if (mVersion != 100)
    00179       {
    00180         Log::error("VLX version not supported.\n");
    00181         return false;
    00182       }
    00183
    00184       if (mEncoding != "ascii")
    00185       {
    00186         Log::error("Encoding not supported.\n");
    00187         return false;
    00188       }
    00189
    00190       unsigned char chunk;
    00191       std::string str;
    00192
    00193       while(readChunk(chunk))
    00194       {
    00195         if(chunk == VLB_ChunkStructure)
    00196         {
    00197           ref<VLXStructure> st = new VLXStructure;
    00198
    00199           if (!parseStructure(st.get()))
    00200           {
    00201             Log::error( Say("Error parsing binary file at offset %n.\n") << inputFile()->position() );
    00202             return false;
    00203           }
    00204
    00205           mStructures.push_back(st);
    00206         }
    00207         else
    00208         {
    00209           Log::error( Say("Error parsing binary file at offset %n. Expected chunk structure.\n") << inputFile()->position() );
    00210           return false;
    00211         }
    00212       }
    00213
    00214       parseMetadata();
    00215
    00216       return true;
    00217     }
    00218
    00219     bool parseStructure(VLXStructure* st)
    00220     {
    00221       std::string str;
    00222
    00223       // tag
    00224       if (!readString(str))
    00225         return false;
    00226       st->setTag(str.c_str());
    00227
    00228       // ID
    00229       if (!readString(str))
    00230         return false;
    00231       st->setID(str.c_str());
    00232
    00233       // read key/value count
    00234       long long count = 0;
    00235       if (!readInteger(count))
    00236         return false;
    00237
    00238       // values
    00239       for(int i=0; i<count; ++i)
    00240       {
    00241         VLXStructure::Value val;
    00242
    00243         // key
    00244         if (!readString(str))
    00245           return false;
    00246         val.setKey(str.c_str());
    00247
    00248         // value
    00249         if (!readValue(val.value()))
    00250           return false;
    00251         st->value().push_back(val);
    00252       }
    00253
    00254       return true;
    00255     }
    00256
    00257     bool parseList(VLXList* list)
    00258     {
    00259       std::string str;
    00260
    00261       // tag
    00262       if (!readString(str))
    00263         return false;
    00264       list->setTag(str.c_str());
    00265
    00266       // read value count
    00267       long long count = 0;
    00268       if (!readInteger(count))
    00269         return false;
    00270
    00271       // values
    00272       for(int i=0; i<count; ++i)
    00273       {
    00274         VLXValue val;
    00275
    00276         if (!readValue(val))
    00277           return false;
    00278         else
    00279           list->value().push_back(val);
    00280       }
    00281
    00282       return true;
    00283     }
    00284
    00285     bool readValue(VLXValue& val)
    00286     {
    00287       unsigned char chunk = 0;
    00288
    00289       if (!readChunk(chunk))
    00290         return false;
    00291
    00292       std::string str;
    00293
    00294       switch(chunk)
    00295       {
    00296
    00297       case VLB_ChunkStructure:
    00298         val.setStructure( new VLXStructure );
    00299         return parseStructure( val.getStructure() );
    00300
    00301       case VLB_ChunkList:
    00302         val.setList( new VLXList );
    00303         return parseList( val.getList() );
    00304
    00305       case VLB_ChunkArrayInteger:
    00306         {
    00307           // tag
    00308           if (!readString(str))
    00309             return false;
    00310           else
    00311             val.setArrayInteger( new VLXArrayInteger( str.c_str() ) );
    00312
    00313           // count
    00314           long long count = 0;
    00315           if (!readInteger(count))
    00316             return false;
    00317
    00318           // values
    00319           VLXArrayInteger& arr = *val.getArrayInteger();
    00320           if (count)
    00321           {
    00322             long long encode_count = 0;
    00323             if (!readInteger(encode_count))
    00324               return false;
    00325             VL_CHECK(encode_count >= 0)
    00326             if (encode_count)
    00327             {
    00328               std::vector<unsigned char> encoded;
    00329               encoded.resize((size_t)encode_count);
    00330               inputFile()->readUInt8(&encoded[0], encode_count);
    00331               decodeIntegers(encoded, arr.value());
    00332             }
    00333           }
    00334           VL_CHECK((size_t)count == arr.value().size())
    00335           return (size_t)count == arr.value().size();
    00336         }
    00337
    00338       case VLB_ChunkArrayRealDouble:
    00339         {
    00340           // tag
    00341           if (!readString(str))
    00342             return false;
    00343           else
    00344             val.setArrayReal( new VLXArrayReal( str.c_str() ) );
    00345           // count
    00346           long long count = 0;
    00347           if (!readInteger(count))
    00348             return false;
    00349           // values
    00350           VLXArrayReal& arr = *val.getArrayReal();
    00351           arr.value().resize( (size_t)count );
    00352           if (count)
    00353           {
    00354 #if 1
    00355             long long c = inputFile()->readDouble( &arr.value()[0], count );
    00356             VL_CHECK(c == count * (int)sizeof(double))
    00357             return c == count * (int)sizeof(double);
    00358 #elif 0
    00359             long long zsize = 0;
    00360             readInteger(zsize);
    00361             std::vector<unsigned char> zipped;
    00362             zipped.resize((size_t)zsize);
    00363             inputFile()->read(&zipped[0], zipped.size());
    00364             bool ok = decompress(&zipped[0], (size_t)zsize, &arr.value()[0]);
    00365             VL_CHECK(ok);
    00366             return ok;
    00367 #endif
    00368           }
    00369           else
    00370             return true;
    00371         }
    00372
    00373       case VLB_ChunkArrayRealFloat:
    00374         {
    00375           // tag
    00376           if (!readString(str))
    00377             return false;
    00378           else
    00379             val.setArrayReal( new VLXArrayReal( str.c_str() ) );
    00380           // count
    00381           long long count = 0;
    00382           if (!readInteger(count))
    00383             return false;
    00384           // values
    00385           VLXArrayReal& arr = *val.getArrayReal();
    00386           arr.value().resize( (size_t)count );
    00387           if (count)
    00388           {
    00389 #if 1
    00390             std::vector<float> floats;
    00391             floats.resize( (size_t)count );
    00392             long long c = inputFile()->readFloat( &floats[0], count );
    00393             // copy over floats to doubles
    00394             for(size_t i=0; i<floats.size(); ++i)
    00395               arr.value()[i] = floats[i];
    00396             VL_CHECK(c == count * (int)sizeof(float))
    00397             return c == count * (int)sizeof(float);
    00398 #elif 0
    00399             long long zsize = 0;
    00400             readInteger(zsize);
    00401             std::vector<unsigned char> zipped;
    00402             zipped.resize((size_t)zsize);
    00403             inputFile()->read(&zipped[0], zipped.size());
    00404             bool ok = decompress(&zipped[0], (size_t)zsize, &arr.value()[0]);
    00405             VL_CHECK(ok);
    00406             return ok;
    00407 #endif
    00408           }
    00409           else
    00410             return true;
    00411         }
    00412
    00413       case VLB_ChunkRawtext:
    00414         // tag
    00415         if (!readString(str))
    00416           return false;
    00417         else
    00418           val.setRawtextBlock( new VLXRawtextBlock( str.c_str() ) );
    00419         // value
    00420         if (!readString(str))
    00421           return false;
    00422         else
    00423         {
    00424           val.getRawtextBlock()->setValue( str.c_str() );
    00425           return true;
    00426         }
    00427
    00428       case VLB_ChunkInteger:
    00429         {
    00430           long long i = 0;
    00431           if (!readInteger(i))
    00432             return false;
    00433           else
    00434           {
    00435             val.setInteger(i);
    00436             return true;
    00437           }
    00438         }
    00439
    00440       case VLB_ChunkRealDouble:
    00441         {
    00442           double d = 0;
    00443           if (inputFile()->readDouble(&d, 1) != sizeof(double))
    00444             return false;
    00445           else
    00446           {
    00447             val.setReal(d);
    00448             return true;
    00449           }
    00450         }
    00451
    00452       case VLB_ChunkString:
    00453         if (!readString(str))
    00454           return false;
    00455         else
    00456         {
    00457           val.setString(str.c_str());
    00458           return true;
    00459         }
    00460
    00461       case VLB_ChunkIdentifier:
    00462         if (!readString(str))
    00463           return false;
    00464         else
    00465         {
    00466           val.setIdentifier(str.c_str());
    00467           return true;
    00468         }
    00469
    00470       case VLB_ChunkID:
    00471         if (!readString(str))
    00472           return false;
    00473         else
    00474         {
    00475           val.setID(str.c_str());
    00476           return true;
    00477         }
    00478
    00479       case VLB_ChunkBool:
    00480         {
    00481           unsigned char boolean = false;
    00482           if ( inputFile()->readUInt8(&boolean, 1) != 1 )
    00483             return false;
    00484           else
    00485           {
    00486             val.setBool( boolean != 0 );
    00487             return true;
    00488           }
    00489         }
    00490
    00491       default:
    00492         return false;
    00493
    00494       }
    00495     }
    00496
    00497     void setInputFile(VirtualFile* file) { mInputFile = file; }
    00498
    00499     VirtualFile* inputFile() { return mInputFile.get(); }
    00500
    00501     const VirtualFile* inputFile() const { return mInputFile.get(); }
    00502
    00503   private:
    00504     unsigned int mFlags;
    00505     ref<VirtualFile> mInputFile;
    00506   };
    00507 }
    00508
    00509 #endif

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