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


typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Thu Jan 2 2014 11:38:41