summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorAndreas Volz <andreas@frodo.mittelerde>2008-08-31 14:14:04 +0200
committerAndreas Volz <andreas@frodo.mittelerde>2008-08-31 14:14:04 +0200
commit5f23f7d12484d2afafa4e0c739c0be8d5b98af99 (patch)
tree152c7c13b8729dd4456bc382b4b3d62f53c9e597 /tools
parent7db1248454f2f8904f2fc75d398ad37f29956a8a (diff)
downloaddbus-c++-5f23f7d12484d2afafa4e0c739c0be8d5b98af99.tar.gz
added object support for signal proxy
Diffstat (limited to 'tools')
-rw-r--r--tools/xml2cpp.cpp161
1 files changed, 120 insertions, 41 deletions
diff --git a/tools/xml2cpp.cpp b/tools/xml2cpp.cpp
index 45c8dde..9a5d594 100644
--- a/tools/xml2cpp.cpp
+++ b/tools/xml2cpp.cpp
@@ -33,6 +33,7 @@
#include <iostream>
#include <fstream>
#include <sstream>
+#include <algorithm>
using namespace std;
using namespace DBus;
@@ -198,25 +199,20 @@ string signature_to_type(const string &signature)
void generate_proxy(Xml::Document &doc, const char *filename)
{
- cerr << "writing " << filename << endl;
-
- ofstream file(filename);
- if (file.bad())
- {
- cerr << "unable to write file " << filename << endl;
- exit(-1);
- }
+ ostringstream file;
+ ostringstream headerStream;
+ vector <string> includeVector;
- file << header;
+ headerStream << header;
string filestring = filename;
underscorize(filestring);
string cond_comp = "__dbusxx__" + filestring + "__PROXY_MARSHAL_H";
- file << "#ifndef " << cond_comp << endl;
- file << "#define " << cond_comp << endl;
+ headerStream << "#ifndef " << cond_comp << endl;
+ headerStream << "#define " << cond_comp << endl;
- file << dbus_includes;
+ headerStream << dbus_includes;
Xml::Node &root = *(doc.root);
Xml::Nodes interfaces = root["interface"];
@@ -231,7 +227,10 @@ void generate_proxy(Xml::Document &doc, const char *filename)
ms.insert(ms.end(), methods.begin(), methods.end());
ms.insert(ms.end(), signals.begin(), signals.end());
+ // gets the name of each interface: <interface name="XYZ">
string ifacename = iface.get("name");
+
+ // these interface names are skipped. Not sure why...
if (ifacename == "org.freedesktop.DBus.Introspectable"
||ifacename == "org.freedesktop.DBus.Properties")
{
@@ -242,7 +241,8 @@ void generate_proxy(Xml::Document &doc, const char *filename)
istringstream ss(ifacename);
string nspace;
unsigned int nspaces = 0;
-
+
+ // this loop prints all the namespaces defined with <interface name="X.Y.Z">
while (ss.str().find('.', ss.tellg()) != string::npos)
{
getline(ss, nspace, '.');
@@ -256,11 +256,13 @@ void generate_proxy(Xml::Document &doc, const char *filename)
string ifaceclass;
getline(ss, ifaceclass);
-
+
+ // a "_proxy" is added to class name to distinguish between proxy and adaptor
ifaceclass += "_proxy";
cerr << "generating code for interface " << ifacename << "..." << endl;
-
+
+ // the code from class definiton up to opening of the constructor is generated...
file << "class " << ifaceclass << endl
<< " : public ::DBus::InterfaceProxy" << endl
<< "{" << endl
@@ -269,7 +271,8 @@ void generate_proxy(Xml::Document &doc, const char *filename)
<< tab << ifaceclass << "()" << endl
<< tab << ": ::DBus::InterfaceProxy(\"" << ifacename << "\")" << endl
<< tab << "{" << endl;
-
+
+ // this loop generates code to connect all the signal stubs; this is still inside the constructor
for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
{
Xml::Node &signal = **si;
@@ -280,13 +283,16 @@ void generate_proxy(Xml::Document &doc, const char *filename)
<< ifaceclass << ", " << signal.get("name") << ", " << stub_name(signal.get("name"))
<< ");" << endl;
}
-
+
+ // the constructor ends here
file << tab << "}" << endl
<< endl;
-/// write properties
+
+ // write public block header for properties
file << "public:" << endl << endl
<< tab << "/* properties exported by this interface */" << endl;
-
+
+ // this loop generates all properties
for (Xml::Nodes::iterator pi = properties.begin ();
pi != properties.end (); ++pi)
{
@@ -337,15 +343,17 @@ void generate_proxy(Xml::Document &doc, const char *filename)
file << tab << tab << tab <<"wi << value;" << endl;
file << tab << tab << tab <<"::DBus::Message ret = this->invoke_method (call);" << endl;
file << tab << tab << "};" << endl;
- }
+ }
}
-
+
+ // write public block header for methods
file << "public:" << endl
<< endl
<< tab << "/* methods exported by this interface," << endl
<< tab << " * this functions will invoke the corresponding methods on the remote objects" << endl
<< tab << " */" << endl;
-
+
+ // this loop generates all methods
for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
{
Xml::Node &method = **mi;
@@ -361,7 +369,7 @@ void generate_proxy(Xml::Document &doc, const char *filename)
{
file << tab << signature_to_type(args_out.front()->get("type")) << " ";
}
-
+
file << method.get("name") << "(";
unsigned int i = 0;
@@ -454,13 +462,15 @@ void generate_proxy(Xml::Document &doc, const char *filename)
file << tab << "}" << endl
<< endl;
}
-
+
+ // write public block header for signals
file << endl
<< "public:" << endl
<< endl
<< tab << "/* signal handlers for this interface" << endl
<< tab << " */" << endl;
-
+
+ // this loop generates all signals
for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
{
Xml::Node &signal = **si;
@@ -468,13 +478,29 @@ void generate_proxy(Xml::Document &doc, const char *filename)
file << tab << "virtual void " << signal.get("name") << "(";
+ // this loop generates all argument for a signal
unsigned int i = 0;
for (Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++i)
{
Xml::Node &arg = **ai;
- file << "const " << signature_to_type(arg.get("type")) << "& ";
-
- string arg_name = arg.get("name");
+
+ string arg_name = arg.get("name");
+ string arg_object = arg.get("object");
+
+ // generate basic signature only if no object name available...
+ if (!arg_object.length())
+ {
+ file << "const " << signature_to_type(arg.get("type")) << "& ";
+ }
+ // ...or generate object style if available
+ else
+ {
+ file << "const " << arg_object << "& ";
+
+ // store a object name to later generate header includes
+ includeVector.push_back (arg_object);
+ }
+
if (arg_name.length())
file << arg_name;
else
@@ -485,13 +511,15 @@ void generate_proxy(Xml::Document &doc, const char *filename)
}
file << ") = 0;" << endl;
}
-
+
+ // write private block header for unmarshalers
file << endl
<< "private:" << endl
<< endl
<< tab << "/* unmarshalers (to unpack the DBus message before calling the actual signal handler)" << endl
<< tab << " */" << endl;
+ // loop to generate all the unmarshalers
for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
{
Xml::Node &signal = **si;
@@ -513,25 +541,51 @@ void generate_proxy(Xml::Document &doc, const char *filename)
file << tab << tab << signature_to_type(arg.get("type")) << " " ;
string arg_name = arg.get("name");
- if (arg_name.length())
- file << arg_name << ";" << " ri >> " << arg_name << ";" << endl;
- else
- file << "arg" << i << ";" << " ri >> " << "arg" << i << ";" << endl;
+
+ string arg_object = arg.get("object");
+
+ // use a default if no arg name given
+ if (!arg_name.length())
+ {
+ arg_name = "arg";
+ }
+
+ file << arg_name << ";" << endl;
+ file << tab << tab << "ri >> " << arg_name << ";" << endl;
+
+ // if a object type is used create a local variable and insert values with '<<' operation
+ if (arg_object.length())
+ {
+ file << tab << tab << arg_object << " _" << arg_name << ";" << endl;
+ file << tab << tab << "_" << arg_name << " << " << arg_name << ";" << endl;
+ }
}
file << tab << tab << signal.get("name") << "(";
+ // generate all arguments for the call to the virtual function
unsigned int j = 0;
for (Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++j)
{
Xml::Node &arg = **ai;
- string arg_name = arg.get("name");
- if (arg_name.length())
- file << arg_name;
- else
- file << "arg" << j;
-
+ string arg_name = arg.get("name");
+ string arg_object = arg.get("object");
+
+ if (!arg_name.length())
+ {
+ arg_name = "arg" + j;
+ }
+
+ if (arg_object.length())
+ {
+ file << "_" << arg_name;
+ }
+ else
+ {
+ file << arg_name;
+ }
+
if (ai+1 != args.end())
file << ", ";
}
@@ -552,9 +606,34 @@ void generate_proxy(Xml::Document &doc, const char *filename)
file << endl;
}
- file << "#endif//" << cond_comp << endl;
+ file << "#endif //" << cond_comp << endl;
+
+ cerr << "writing " << filename << endl;
+
+ // remove all duplicates in the header include vector
+ vector<string>::const_iterator vec_end_it = unique (includeVector.begin (), includeVector.end ());
+
+ for (vector<string>::const_iterator vec_it = includeVector.begin ();
+ vec_it != vec_end_it;
+ ++vec_it)
+ {
+ const string &include = *vec_it;
+
+ headerStream << "#include " << "\"" << include << ".h" << "\"" << endl;
+ }
+ headerStream << endl;
+
+ ofstream fileX(filename);
+ if (file.bad())
+ {
+ cerr << "unable to write file " << filename << endl;
+ exit(-1);
+ }
+
+ fileX << headerStream.str ();
+ fileX << file.str ();
- file.close();
+ fileX.close();
}
void generate_adaptor(Xml::Document &doc, const char *filename)