export.cc
Go to the documentation of this file.
00001 #include "export.hh"
00002 #include <iostream>
00003 
00004 #include <typelib/typevisitor.hh>
00005 
00006 namespace
00007 {
00008     using namespace std;
00009     using namespace Typelib;
00010     class TlbExportVisitor : public TypeVisitor
00011     {
00012         ostream&  m_stream;
00013         string    m_indent;
00014         string    m_source_id;
00015         string emitSourceID() const;
00016         string emitMetaData(Type const& type) const;
00017         string emitMetaData(MetaData const& metadata) const;
00018 
00019     protected:
00020         bool visit_(Compound const& type);
00021         bool visit_(Compound const& type, Field const& field);
00022 
00023         bool visit_(Numeric const& type);
00024 
00025         bool visit_(Pointer const& type);
00026         bool visit_(Array const& type);
00027 
00028         bool visit_(Enum const& type);
00029 
00030         bool visit_(NullType const& type);
00031         bool visit_(OpaqueType const& type);
00032         bool visit_(Container const& type);
00033 
00034     public:
00035         TlbExportVisitor(ostream& stream, string const& base_indent, std::string const& source_id);
00036     };
00037 
00038     struct Indent
00039     {
00040         string& m_indent;
00041         string  m_save;
00042         Indent(string& current)
00043             : m_indent(current), m_save(current)
00044         { m_indent += "  "; }
00045         ~Indent() { m_indent = m_save; }
00046     };
00047 
00048     TlbExportVisitor::TlbExportVisitor(ostream& stream, string const& base_indent, std::string const& source_id)
00049         : m_stream(stream), m_indent(base_indent), m_source_id(source_id) {}
00050                 
00051     std::string xmlEscape(std::string const& source)
00052     {
00053         string result = source;
00054         size_t pos = result.find_first_of("<>");
00055         while (pos != string::npos)
00056         {
00057             if (result[pos] == '<')
00058                 result.replace(pos, 1, "&lt;");
00059             else if (result[pos] == '>')
00060                 result.replace(pos, 1, "&gt;");
00061             pos = result.find_first_of("<>");
00062         }
00063 
00064         return result;
00065     }
00066 
00067     std::string TlbExportVisitor::emitMetaData(Type const& type) const
00068     {
00069         return emitMetaData(type.getMetaData());
00070     }
00071     std::string TlbExportVisitor::emitMetaData(MetaData const& metadata) const
00072     {
00073         std::ostringstream stream;
00074         MetaData::Map const& map = metadata.get();
00075         for (MetaData::Map::const_iterator it = map.begin(); it != map.end(); ++it)
00076         {
00077             std::string key = it->first;
00078             MetaData::Values values = it->second;
00079             for (MetaData::Values::const_iterator it_value = values.begin(); it_value != values.end(); ++it_value)
00080                 stream << "<metadata key=\"" << key << "\"><![CDATA[" << *it_value << "]]></metadata>\n";
00081         }
00082         return stream.str();
00083     }
00084 
00085     std::string TlbExportVisitor::emitSourceID() const
00086     {
00087         if (!m_source_id.empty())
00088             return "source_id=\"" + xmlEscape(m_source_id) + "\"";
00089         else return std::string();
00090     }
00091 
00092     bool TlbExportVisitor::visit_(OpaqueType const& type)
00093     {
00094         m_stream << "<opaque name=\"" << xmlEscape(type.getName()) << "\" size=\"" << type.getSize() << "\" " << emitSourceID() << ">\n";
00095         m_stream << m_indent << emitMetaData(type) << "\n";
00096         m_stream << m_indent << "</opaque>";
00097         return true;
00098     }
00099 
00100     bool TlbExportVisitor::visit_(Compound const& type)
00101     { 
00102         m_stream << "<compound name=\"" << xmlEscape(type.getName()) << "\" size=\"" << type.getSize() << "\" " << emitSourceID() << ">\n";
00103         
00104         { Indent indenter(m_indent);
00105             TypeVisitor::visit_(type);
00106         }
00107 
00108         m_stream << m_indent << emitMetaData(type) << "\n";
00109         m_stream << m_indent << "</compound>";
00110 
00111         return true;
00112     }
00113     bool TlbExportVisitor::visit_(Compound const& type, Field const& field)
00114     { 
00115         m_stream 
00116             << m_indent
00117             << "<field name=\"" << field.getName() << "\""
00118             << " type=\""   << xmlEscape(field.getType().getName())  << "\""
00119             << " offset=\"" << field.getOffset() << "\">\n";
00120         m_stream << m_indent << emitMetaData(field.getMetaData()) << "\n";
00121         m_stream << m_indent << "</field>\n";
00122         return true;
00123     }
00124 
00125     namespace
00126     {
00127         char const* getStringCategory(Numeric::NumericCategory category)
00128         {
00129             switch(category)
00130             {
00131                 case Numeric::SInt:
00132                     return "sint";
00133                 case Numeric::UInt:
00134                     return "uint";
00135                 case Numeric::Float:
00136                     return "float";
00137                 default:
00138                     throw "invalid category";
00139             }
00140         }
00141     }
00142 
00143     bool TlbExportVisitor::visit_(Numeric const& type)
00144     {
00145         m_stream 
00146             << "<numeric name=\"" << type.getName() << "\" " 
00147             << "category=\"" << getStringCategory(type.getNumericCategory()) << "\" "
00148             << "size=\"" << type.getSize() << "\" " << emitSourceID() << ">\n";
00149         m_stream << m_indent << emitMetaData(type) << "\n";
00150         m_stream << m_indent << "</numeric>";
00151 
00152         return true;
00153     }
00154     bool TlbExportVisitor::visit_ (NullType const& type)
00155     {
00156         m_stream << "<null " << " name=\"" << type.getName() << "\" " << emitSourceID() << ">\n";
00157         m_stream << m_indent << emitMetaData(type) << "\n";
00158         m_stream << m_indent << "</null>";
00159         return true;
00160     }
00161 
00162     void indirect(ostream& stream, Indirect const& type)
00163     {
00164         stream 
00165             << " name=\"" << xmlEscape(type.getName())
00166             << "\" of=\"" << xmlEscape(type.getIndirection().getName()) << "\"";
00167     }
00168 
00169     bool TlbExportVisitor::visit_ (Pointer const& type)
00170     {
00171         m_stream << "<pointer ";
00172         indirect(m_stream, type);
00173         m_stream << " " << emitSourceID() << ">\n";
00174         m_stream << m_indent << emitMetaData(type) << "\n";
00175         m_stream << m_indent << "</pointer>";
00176         return true;
00177     }
00178     bool TlbExportVisitor::visit_ (Array const& type)
00179     {
00180         m_stream << "<array ";
00181         indirect(m_stream, type);
00182         m_stream << " dimension=\"" << type.getDimension() << "\" " << emitSourceID() << ">\n";
00183         m_stream << m_indent << emitMetaData(type) << "\n";
00184         m_stream << m_indent << "</array>";
00185         return true;
00186     }
00187     bool TlbExportVisitor::visit_(Container const& type)
00188     { 
00189         m_stream << "<container ";
00190         indirect(m_stream, type);
00191         m_stream
00192             << " size=\"" << type.getSize() << "\""
00193             << " kind=\"" << xmlEscape(type.kind()) << "\""
00194             << " " << emitSourceID() << ">\n";
00195         m_stream << m_indent << emitMetaData(type) << "\n";
00196         m_stream << m_indent << "</container>";
00197         return true;
00198     }
00199 
00200     bool TlbExportVisitor::visit_ (Enum const& type)
00201     {
00202         Enum::ValueMap const& values = type.values();
00203         m_stream << "<enum name=\"" << type.getName() << "\" " << emitSourceID() << ">\n";
00204         { Indent indenter(m_indent);
00205             Enum::ValueMap::const_iterator it;
00206             for (it = values.begin(); it != values.end(); ++it)
00207                 m_stream << m_indent << "<value symbol=\"" << it->first << "\" value=\"" << it->second << "\"/>\n";
00208         }
00209         m_stream << m_indent << emitMetaData(type) << "\n";
00210         m_stream << m_indent << "</enum>";
00211 
00212         return true;
00213     }
00214 
00215 }
00216 
00217 using namespace std;
00218 void TlbExport::begin
00219     ( ostream& stream
00220     , Typelib::Registry const& /*registry*/ )
00221 {
00222     stream << 
00223         "<?xml version=\"1.0\"?>\n"
00224         "<typelib>\n";
00225 }
00226 void TlbExport::end
00227     ( ostream& stream
00228     , Typelib::Registry const& /*registry*/ )
00229 {
00230     stream << 
00231         "</typelib>\n";
00232 }
00233 
00234 bool TlbExport::save
00235     ( ostream& stream
00236     , Typelib::RegistryIterator const& type )
00237 {
00238     if (type.isAlias())
00239     {
00240         stream << "  <alias "
00241             "name=\"" << xmlEscape(type.getName()) << "\" "
00242             "source=\"" << xmlEscape(type->getName()) << "\"/>\n";
00243     }
00244     else
00245     {
00246         stream << "  ";
00247         TlbExportVisitor exporter(stream, "  ", type.getSource());
00248         exporter.apply(*type);
00249         stream << "\n";
00250     }
00251     return true;
00252 }
00253 


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