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
00038
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
00075
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
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