$search
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 // 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