Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlCore/VLXSeriailzer.cpp

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 #include <vlCore/VLXSerializer.hpp>
00033 #include <vlCore/VLXVisitorCountIDs.hpp>
00034 #include <vlCore/VLXVisitorLinker.hpp>
00035 #include <vlCore/VLXParserVLT.hpp>
00036 #include <vlCore/VLXParserVLB.hpp>
00037 #include <vlCore/VLXVisitorExportToVLT.hpp>
00038 #include <vlCore/VLXVisitorExportToVLB.hpp>
00039 #include <vlCore/DiskFile.hpp>
00040 #include <vlCore/version.hpp>
00041 #include <ctime>
00042 
00043 using namespace vl;
00044 
00045 #if _MSC_VER
00046   #define snprintf _snprintf
00047 #endif
00048 
00049 //-----------------------------------------------------------------------------
00050 Object* VLXSerializer::importVLX(const VLXStructure* st)
00051 {
00052   VL_CHECK(st)
00053 
00054   if (error())
00055     return NULL;
00056 
00057   Object* obj = getImportedStructure(st);
00058   if (obj)
00059     return obj;
00060   else
00061   {
00062     std::map< std::string, ref<VLXClassWrapper> >::iterator it = registry()->importRegistry().find(st->tag());
00063     if (it != registry()->importRegistry().end())
00064     {
00065       VLXClassWrapper* serializer = it->second.get_writable();
00066       VL_CHECK(serializer);
00067       // import structure
00068       ref<Object> obj = serializer->importVLX(*this, st);
00069       if (!obj)
00070       {
00071         setError(ImportError);
00072         Log::error( Say("Error importing structure '%s'.") << st->tag() );
00073         VL_TRAP()
00074       }
00075       return obj.get();
00076     }
00077     else
00078     {
00079       setError(ImportError);
00080       Log::error( Say("No importing serializer found for structure '%s'.") << st->tag() );
00081       VL_TRAP();
00082       return NULL;
00083     }
00084   }
00085 }
00086 //-----------------------------------------------------------------------------
00087 VLXStructure* VLXSerializer::exportVLX(const Object* obj)
00088 {
00089   VL_CHECK(obj)
00090 
00091   if (error())
00092     return NULL;
00093 
00094   VLXStructure* st = getExportedObject(obj);
00095   if (st)
00096     return st;
00097   else
00098   {
00099     std::map< TypeInfo, ref<VLXClassWrapper> >::iterator it = registry()->exportRegistry().find(obj->classType());
00100     if (it != registry()->exportRegistry().end())
00101     {
00102       VLXClassWrapper* serializer = it->second.get_writable();
00103       VL_CHECK(serializer);
00104       // export object
00105       ref<VLXStructure> st = serializer->exportVLX(*this, obj);
00106       if (!st)
00107       {
00108         setError(ExportError);
00109         Log::error( Say("Error exporting '%s'.") << obj->classType().name() );
00110         VL_TRAP()
00111       }
00112       return st.get();
00113     }
00114     else
00115     {
00116       setError(ExportError);
00117       Log::error( Say("No exporting serializer found for '%s'.") << obj->classType().name() );
00118       VL_TRAP()
00119       return NULL;
00120     }
00121   }
00122 }
00123 //-----------------------------------------------------------------------------
00124 bool VLXSerializer::canExport(const Object* obj) const 
00125 { 
00126   if (!registry())
00127     return false;
00128   else
00129     return registry()->exportRegistry().find(obj->classType()) != registry()->exportRegistry().end(); 
00130 }
00131 //-----------------------------------------------------------------------------
00132 bool VLXSerializer::canImport(const VLXStructure* st) const 
00133 { 
00134   if (!registry())
00135     return false;
00136   else
00137     return registry()->importRegistry().find(st->tag()) != registry()->importRegistry().end(); 
00138 }
00139 //-----------------------------------------------------------------------------
00140 void VLXSerializer::registerImportedStructure(const VLXStructure* st, Object* obj) 
00141 {
00142   VL_CHECK( mImportedStructures.find(st) == mImportedStructures.end() )
00143   mImportedStructures[st] = obj;
00144 }
00145 //-----------------------------------------------------------------------------
00146 void VLXSerializer::registerExportedObject(const Object* obj, VLXStructure* st)
00147 {
00148   VL_CHECK(mExportedObjects.find(obj) == mExportedObjects.end())
00149   mExportedObjects[obj] = st;
00150 }
00151 //-----------------------------------------------------------------------------
00152 Object* VLXSerializer::getImportedStructure(const VLXStructure* st)
00153 {
00154   std::map< ref<VLXStructure>, ref<Object> >::iterator it = mImportedStructures.find(st);
00155   if (it == mImportedStructures.end())
00156     return NULL;
00157   else
00158   {
00159     VL_CHECK(it->second.get_writable() != NULL)
00160     return it->second.get_writable();
00161   }
00162 }
00163 //-----------------------------------------------------------------------------
00164 VLXStructure* VLXSerializer::getExportedObject(const Object* obj)
00165 {
00166   std::map< ref<Object>, ref<VLXStructure> >::iterator it = mExportedObjects.find(obj);
00167   if (it == mExportedObjects.end())
00168     return NULL;
00169   else
00170   {
00171     VL_CHECK(it->second.get_writable() != NULL)
00172     return it->second.get_writable();
00173   }
00174 }
00175 //-----------------------------------------------------------------------------
00176 void VLXSerializer::signalImportError(const String& str) 
00177 { 
00178   // signal only the first one
00179   if (!error())
00180   {
00181     Log::error( str );
00182     setError( VLXSerializer::ImportError );
00183   }
00184 }
00185 //-----------------------------------------------------------------------------
00186 void VLXSerializer::signalExportError(const String& str)
00187 { 
00188   // signal only the first one
00189   if (!error())
00190   {
00191     Log::error( str );
00192     setError( VLXSerializer::ExportError ); 
00193   }
00194 }
00195 //-----------------------------------------------------------------------------
00196 std::string VLXSerializer::generateID(const char* prefix)
00197 {
00198   char number[sizeof(int)*8+1];
00199   snprintf(number, sizeof(number), "%d", ++mIDCounter);
00200   return std::string("#") + prefix + "id" + number;
00201 }
00202 //-----------------------------------------------------------------------------
00203 bool VLXSerializer::saveVLT(const String& path, const Object* obj, bool start_fresh)
00204 {
00205   ref<DiskFile> file = new DiskFile(path);
00206   return saveVLT(file.get(), obj, start_fresh);
00207 }
00208 //-----------------------------------------------------------------------------
00209 bool VLXSerializer::saveVLT(VirtualFile* file, const Object* obj, bool start_fresh)
00210 {
00211   if (start_fresh)
00212     reset();
00213 
00214   if (mError)
00215     return false;
00216 
00217   // metadata
00218 
00219   ref<VLXStructure> meta = new VLXStructure("<Metadata>");
00220   std::map< std::string, VLXValue >::iterator it = metadata().begin();
00221   for( ; it != metadata().end(); ++it )
00222   {
00223     if (it->first == "VL_Serializer_Version")
00224       continue;
00225     if (it->first == "Authoring_Tool")
00226       continue;
00227     if (it->first == "Creation_Date")
00228       continue;
00229     meta->value().push_back( VLXStructure::Value(it->first.c_str(), it->second) );
00230   }
00231 
00232   // add VL metadata
00233 
00234   String auth = Say("Visualization Library %n.%n.%n") << VL_Major << VL_Minor << VL_Build;
00235   *meta << "Authoring_Tool" << VLXValue( auth.toStdString().c_str(), VLXValue::String );
00236 
00237   time_t rawtime;
00238   time( &rawtime );
00239   std::string str = ctime(&rawtime);
00240   str.resize(str.size()-1); // remove the trailing \n
00241   *meta << "Creation_Date" << VLXValue( str.c_str(), VLXValue::String );
00242 
00243   *meta << "VL_Serializer_Version" << VLXValue( (long long) 100 );
00244 
00245   ref<VLXStructure> st = exportVLX( obj );
00246   if (st)
00247   {
00248     std::map< std::string, int > uid_set;
00249     VLXVisitorCountIDs uid_collector;
00250     uid_collector.setIDSet(&uid_set);
00251     meta->acceptVisitor(&uid_collector);
00252     st->acceptVisitor(&uid_collector);
00253 
00254     VLXVisitorExportToVLT text_export_visitor;
00255     text_export_visitor.setIDSet(&uid_set);
00256     text_export_visitor.writeHeader();
00257     meta->acceptVisitor(&text_export_visitor);
00258     st->acceptVisitor(&text_export_visitor);
00259 
00260     file->open(vl::OM_WriteOnly);
00261     if ( file->write( text_export_visitor.text().c_str(), text_export_visitor.text().size() ) != (int)text_export_visitor.text().size() )
00262     {
00263       Log::error( Say("VLXSerializer::saveVLT() write error : %s\n") << file->path() );
00264       mError = WriteError;
00265     }
00266     file->close();
00267 
00268     return mError == NoError;
00269   }
00270   else
00271     return false;
00272 }
00273 //-----------------------------------------------------------------------------
00274 bool VLXSerializer::saveVLB(const String& path, const Object* obj, bool start_fresh)
00275 {
00276   ref<DiskFile> file = new DiskFile(path);
00277   return saveVLB(file.get(), obj, start_fresh);
00278 }
00279 //-----------------------------------------------------------------------------
00280 bool VLXSerializer::saveVLB(VirtualFile* file, const Object* obj, bool start_fresh)
00281 {
00282   if (start_fresh)
00283     reset();
00284 
00285   if (mError)
00286     return false;
00287 
00288   // metadata
00289 
00290   ref<VLXStructure> meta = new VLXStructure("<Metadata>");
00291   std::map< std::string, VLXValue >::iterator it = metadata().begin();
00292   for( ; it != metadata().end(); ++it )
00293   {
00294     if (it->first == "VL_Serializer_Version")
00295       continue;
00296     if (it->first == "Authoring_Tool")
00297       continue;
00298     if (it->first == "Creation_Date")
00299       continue;
00300     meta->value().push_back( VLXStructure::Value(it->first.c_str(), it->second) );
00301   }
00302 
00303   // add VL metadata
00304 
00305   String auth = Say("Visualization Library %n.%n.%n") << VL_Major << VL_Minor << VL_Build;
00306   *meta << "Authoring_Tool" << VLXValue( auth.toStdString().c_str(), VLXValue::String );
00307 
00308   time_t rawtime;
00309   time( &rawtime );
00310   std::string str = ctime(&rawtime);
00311   str.resize(str.size()-1); // remove the trailing \n
00312   *meta << "Creation_Date" << VLXValue( str.c_str(), VLXValue::String );
00313 
00314   *meta << "VL_Serializer_Version" << VLXValue( (long long) 100 );
00315 
00316   ref<VLXStructure> st = exportVLX( obj );
00317   if (st)
00318   {
00319     std::map< std::string, int > uid_set;
00320     VLXVisitorCountIDs uid_collector;
00321     uid_collector.setIDSet(&uid_set);
00322     meta->acceptVisitor(&uid_collector);
00323     st->acceptVisitor(&uid_collector);
00324 
00325     VLXVisitorExportToVLB bin_export_visitor(file);
00326     bin_export_visitor.setIDSet(&uid_set);
00327     bin_export_visitor.writeHeader();
00328     meta->acceptVisitor(&bin_export_visitor);
00329     st->acceptVisitor(&bin_export_visitor);
00330     file->close();
00331 
00332     return mError == NoError;
00333   }
00334   else
00335     return false;
00336 }
00337 //-----------------------------------------------------------------------------
00338 ref<Object> VLXSerializer::loadVLT(const String& path, bool start_fresh)
00339 {
00340   ref<VirtualFile> file = vl::locateFile(path);
00341   return loadVLT(file.get(), start_fresh);
00342 }
00343 //-----------------------------------------------------------------------------
00344 ref<Object> VLXSerializer::loadVLT(VirtualFile* file, bool start_fresh)
00345 {
00346   if (start_fresh)
00347     reset();
00348 
00349   if (mError)
00350     return NULL;
00351 
00352   // set the base document URL to resolve document-relative paths
00353   setDocumentURL( file->path() );
00354 
00355   VLXParserVLT parser;
00356   parser.tokenizer()->setInputFile( file );
00357 
00358   bool ok = parser.parse();
00359   file->close();
00360 
00361   if (!ok)
00362   {
00363     setError(ImportError);
00364     return NULL;
00365   }
00366 
00367   // copy metadata over
00368   metadata() = parser.metadata();
00369 
00370   if (!parser.link())
00371   {
00372     setError(ImportError);
00373     return NULL;
00374   }
00375 
00376   if (parser.structures().empty())
00377     return NULL;
00378   else
00379     return importVLX( parser.structures()[0].get() ); // note that we ignore the other structures
00380 }
00381 //-----------------------------------------------------------------------------
00382 ref<Object> VLXSerializer::loadVLB(const String& path, bool start_fresh)
00383 {
00384   ref<VirtualFile> file = vl::locateFile(path);
00385   return loadVLB(file.get(), start_fresh);
00386 }
00387 //-----------------------------------------------------------------------------
00388 ref<Object> VLXSerializer::loadVLB(VirtualFile* file, bool start_fresh)
00389 {
00390   if (start_fresh)
00391     reset();
00392 
00393   if (mError)
00394     return NULL;
00395 
00396   // set the base document URL to resolve document-relative paths
00397   setDocumentURL( file->path() );
00398 
00399   VLXParserVLB parser;
00400   parser.setInputFile( file );
00401 
00402   bool ok = parser.parse();
00403   file->close();
00404 
00405   if (!ok)
00406   {
00407     setError(ImportError);
00408     return NULL;
00409   }
00410 
00411   // copy metadata over
00412   metadata() = parser.metadata();
00413 
00414   if (!parser.link())
00415   {
00416     setError(ImportError);
00417     return NULL;
00418   }
00419 
00420   if (parser.structures().empty())
00421     return NULL;
00422   else
00423     return importVLX( parser.structures()[0].get() ); // note that we ignore the other structures
00424 }
00425 //-----------------------------------------------------------------------------
00426 const char* VLXSerializer::errorString() const
00427 {
00428   switch(mError)
00429   {
00430   case NoError:     return "NoError";
00431   case ImportError: return "ImportError";
00432   case ExportError: return "ExportError";
00433   case ReadError:   return "ReadError";
00434   default:
00435   case WriteError:  return "WriteError";
00436   }
00437 }
00438 //-----------------------------------------------------------------------------
00439 void VLXSerializer::resolvePath(std::string& path)
00440 {
00441   String str = String::fromStdString( path );
00442   if (str.startsWith("this:"))
00443   {
00444     str = documentURL().extractPath() + str.right(-5);
00445     path = str.normalizeSlashes().toStdString();
00446   }
00447 }
00448 //-----------------------------------------------------------------------------

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:33.
Permission is granted to use this page to write and publish articles regarding Visualization Library.