Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
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
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
00179 if (!error())
00180 {
00181 Log::error( str );
00182 setError( VLXSerializer::ImportError );
00183 }
00184 }
00185
00186 void VLXSerializer::signalExportError(const String& str)
00187 {
00188
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
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
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);
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
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
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);
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
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
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() );
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
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
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() );
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