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, "<");
00057 else if (result[pos] == '>')
00058 result.replace(pos, 1, ">");
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
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& )
00190 {
00191 stream <<
00192 "<?xml version=\"1.0\"?>\n"
00193 "<typelib>\n";
00194 }
00195 void TlbExport::end
00196 ( ostream& stream
00197 , Typelib::Registry const& )
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