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


typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Sat Jun 8 2019 18:49:22