exporter.cc
Go to the documentation of this file.
00001 #include "exporter.hh"
00002 #include "registry.hh"
00003 #include "registryiterator.hh"
00004 #include <utilmm/configfile/configset.hh>
00005 #include <utilmm/stringtools.hh>
00006 #include <typelib/typevisitor.hh>
00007 #include <set>
00008 #include <fstream>
00009 
00010 using namespace Typelib;
00011 using namespace std;
00012 using utilmm::join;
00013 
00014 void Exporter::save(std::string const& file_name, utilmm::config_set const& config, Registry const& registry)
00015 {
00016     std::ofstream file(file_name.c_str(), std::ofstream::trunc);
00017     save(file, config, registry);
00018 }
00019 
00020 void Exporter::save(std::ostream& stream, utilmm::config_set const& config, Registry const& registry)
00021 {
00022     begin(stream, registry);
00023 
00024     std::set<Type const*> saved_types;
00025 
00026     typedef std::map
00027         < const std::string
00028         , RegistryIterator
00029         , bool (*) (const std::string&, const std::string&)
00030         >     TypeMap;
00031     TypeMap types(nameSort);
00032        
00033     RegistryIterator const it_end(registry.end());
00034     for (RegistryIterator it = registry.begin(); it != it_end; ++it)
00035         types.insert(make_pair(it.getName(), it));
00036 
00037     // Some exporters need to limit how many times a namespace appears. So, the
00038     // main algorithm (here) is meant to limit switching between namespaces.
00039     TypeMap free_types(nameSort);
00040     std::string last_namespace;
00041     while (!types.empty())
00042     {
00043         TypeMap::iterator it = types.begin();
00044         TypeMap::iterator const end = types.end();
00045 
00046         while (it != end)
00047         {
00048             bool done_dependencies = false;
00049             if (it->second.isAlias())
00050                 done_dependencies = (saved_types.find(&(*it->second)) != saved_types.end());
00051             else
00052             {
00053                 std::set<Type const*> dependencies = it->second->dependsOn();
00054                 done_dependencies = includes(saved_types.begin(), saved_types.end(),
00055                         dependencies.begin(), dependencies.end());
00056             }
00057 
00058             if (done_dependencies)
00059             {
00060                 free_types.insert(*it);
00061                 types.erase(it++);
00062             }
00063             else ++it;
00064         }
00065 
00066         if (free_types.empty())
00067         {
00068             list<string> remaining;
00069             for (TypeMap::iterator it = types.begin(); it != types.end(); ++it)
00070                 remaining.push_back(it->first);
00071             throw ExportError(join(remaining) + " seem to be recursive type(s). Exporting them is not supported yet");
00072         }
00073 
00074         // Remove all non-persistent types from the free_type set. If we found
00075         // any, just go loop. Otherwise, do dump some other types.
00076         bool got_some = false;
00077         TypeMap::iterator free_it = free_types.begin();
00078         TypeMap::iterator save_it = free_types.end();
00079         while (free_it != free_types.end())
00080         {
00081             if (!free_it->second.isPersistent())
00082             {
00083                 got_some = true;
00084                 saved_types.insert(&(*free_it->second));
00085                 free_types.erase(free_it++);
00086             }
00087             else
00088             {
00089                 if (save_it == free_types.end() && free_it->second.getNamespace() == last_namespace)
00090                     save_it = free_it;
00091                 ++free_it;
00092             }
00093         }
00094         if (got_some)
00095             continue;
00096 
00097         if (save_it == free_types.end())
00098             save_it = free_types.begin();
00099 
00100         std::string ns = save_it->second.getNamespace();
00101         while (save_it != free_types.end() && save_it->second.getNamespace() == ns)
00102         {
00103             saved_types.insert(&(*save_it->second));
00104             if (save(stream, save_it->second))
00105                 last_namespace = ns;
00106 
00107             free_types.erase(save_it++);
00108         }
00109     }
00110 
00111     // Now save the remaining types in free_types
00112     for (TypeMap::iterator it = free_types.begin(); it != free_types.end(); ++it)
00113     {
00114         if (it->second.isPersistent())
00115             save(stream, it->second);
00116     }
00117 
00118     end(stream, registry);
00119 }
00120 
00121 bool Exporter::save( std::ostream& stream, Registry const& registry )
00122 {
00123     utilmm::config_set config;
00124     try { save(stream, config, registry); }
00125     catch(UnsupportedType) { return false; }
00126     catch(ExportError) { return false; }
00127     return true;
00128 }
00129 
00130 void Exporter::begin(std::ostream& stream, Registry const& registry) {}
00131 void Exporter::end  (std::ostream& stream, Registry const& registry) {}
00132 


typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Mon Oct 6 2014 03:17:12