added object support for signal proxy
This commit is contained in:
parent
7db1248454
commit
5f23f7d124
1 changed files with 120 additions and 41 deletions
|
@ -33,6 +33,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace DBus;
|
using namespace DBus;
|
||||||
|
@ -198,25 +199,20 @@ string signature_to_type(const string &signature)
|
||||||
|
|
||||||
void generate_proxy(Xml::Document &doc, const char *filename)
|
void generate_proxy(Xml::Document &doc, const char *filename)
|
||||||
{
|
{
|
||||||
cerr << "writing " << filename << endl;
|
ostringstream file;
|
||||||
|
ostringstream headerStream;
|
||||||
|
vector <string> includeVector;
|
||||||
|
|
||||||
ofstream file(filename);
|
headerStream << header;
|
||||||
if (file.bad())
|
|
||||||
{
|
|
||||||
cerr << "unable to write file " << filename << endl;
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
file << header;
|
|
||||||
string filestring = filename;
|
string filestring = filename;
|
||||||
underscorize(filestring);
|
underscorize(filestring);
|
||||||
|
|
||||||
string cond_comp = "__dbusxx__" + filestring + "__PROXY_MARSHAL_H";
|
string cond_comp = "__dbusxx__" + filestring + "__PROXY_MARSHAL_H";
|
||||||
|
|
||||||
file << "#ifndef " << cond_comp << endl;
|
headerStream << "#ifndef " << cond_comp << endl;
|
||||||
file << "#define " << cond_comp << endl;
|
headerStream << "#define " << cond_comp << endl;
|
||||||
|
|
||||||
file << dbus_includes;
|
headerStream << dbus_includes;
|
||||||
|
|
||||||
Xml::Node &root = *(doc.root);
|
Xml::Node &root = *(doc.root);
|
||||||
Xml::Nodes interfaces = root["interface"];
|
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(), methods.begin(), methods.end());
|
||||||
ms.insert(ms.end(), signals.begin(), signals.end());
|
ms.insert(ms.end(), signals.begin(), signals.end());
|
||||||
|
|
||||||
|
// gets the name of each interface: <interface name="XYZ">
|
||||||
string ifacename = iface.get("name");
|
string ifacename = iface.get("name");
|
||||||
|
|
||||||
|
// these interface names are skipped. Not sure why...
|
||||||
if (ifacename == "org.freedesktop.DBus.Introspectable"
|
if (ifacename == "org.freedesktop.DBus.Introspectable"
|
||||||
||ifacename == "org.freedesktop.DBus.Properties")
|
||ifacename == "org.freedesktop.DBus.Properties")
|
||||||
{
|
{
|
||||||
|
@ -243,6 +242,7 @@ void generate_proxy(Xml::Document &doc, const char *filename)
|
||||||
string nspace;
|
string nspace;
|
||||||
unsigned int nspaces = 0;
|
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)
|
while (ss.str().find('.', ss.tellg()) != string::npos)
|
||||||
{
|
{
|
||||||
getline(ss, nspace, '.');
|
getline(ss, nspace, '.');
|
||||||
|
@ -257,10 +257,12 @@ void generate_proxy(Xml::Document &doc, const char *filename)
|
||||||
|
|
||||||
getline(ss, ifaceclass);
|
getline(ss, ifaceclass);
|
||||||
|
|
||||||
|
// a "_proxy" is added to class name to distinguish between proxy and adaptor
|
||||||
ifaceclass += "_proxy";
|
ifaceclass += "_proxy";
|
||||||
|
|
||||||
cerr << "generating code for interface " << ifacename << "..." << endl;
|
cerr << "generating code for interface " << ifacename << "..." << endl;
|
||||||
|
|
||||||
|
// the code from class definiton up to opening of the constructor is generated...
|
||||||
file << "class " << ifaceclass << endl
|
file << "class " << ifaceclass << endl
|
||||||
<< " : public ::DBus::InterfaceProxy" << endl
|
<< " : public ::DBus::InterfaceProxy" << endl
|
||||||
<< "{" << endl
|
<< "{" << endl
|
||||||
|
@ -270,6 +272,7 @@ void generate_proxy(Xml::Document &doc, const char *filename)
|
||||||
<< tab << ": ::DBus::InterfaceProxy(\"" << ifacename << "\")" << endl
|
<< tab << ": ::DBus::InterfaceProxy(\"" << ifacename << "\")" << endl
|
||||||
<< tab << "{" << 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)
|
for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
|
||||||
{
|
{
|
||||||
Xml::Node &signal = **si;
|
Xml::Node &signal = **si;
|
||||||
|
@ -281,12 +284,15 @@ void generate_proxy(Xml::Document &doc, const char *filename)
|
||||||
<< ");" << endl;
|
<< ");" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the constructor ends here
|
||||||
file << tab << "}" << endl
|
file << tab << "}" << endl
|
||||||
<< endl;
|
<< endl;
|
||||||
/// write properties
|
|
||||||
|
// write public block header for properties
|
||||||
file << "public:" << endl << endl
|
file << "public:" << endl << endl
|
||||||
<< tab << "/* properties exported by this interface */" << endl;
|
<< tab << "/* properties exported by this interface */" << endl;
|
||||||
|
|
||||||
|
// this loop generates all properties
|
||||||
for (Xml::Nodes::iterator pi = properties.begin ();
|
for (Xml::Nodes::iterator pi = properties.begin ();
|
||||||
pi != properties.end (); ++pi)
|
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 <<"wi << value;" << endl;
|
||||||
file << tab << tab << tab <<"::DBus::Message ret = this->invoke_method (call);" << endl;
|
file << tab << tab << tab <<"::DBus::Message ret = this->invoke_method (call);" << endl;
|
||||||
file << tab << tab << "};" << endl;
|
file << tab << tab << "};" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write public block header for methods
|
||||||
file << "public:" << endl
|
file << "public:" << endl
|
||||||
<< endl
|
<< endl
|
||||||
<< tab << "/* methods exported by this interface," << endl
|
<< tab << "/* methods exported by this interface," << endl
|
||||||
<< tab << " * this functions will invoke the corresponding methods on the remote objects" << endl
|
<< tab << " * this functions will invoke the corresponding methods on the remote objects" << endl
|
||||||
<< tab << " */" << endl;
|
<< tab << " */" << endl;
|
||||||
|
|
||||||
|
// this loop generates all methods
|
||||||
for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
|
for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
|
||||||
{
|
{
|
||||||
Xml::Node &method = **mi;
|
Xml::Node &method = **mi;
|
||||||
|
@ -455,12 +463,14 @@ void generate_proxy(Xml::Document &doc, const char *filename)
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write public block header for signals
|
||||||
file << endl
|
file << endl
|
||||||
<< "public:" << endl
|
<< "public:" << endl
|
||||||
<< endl
|
<< endl
|
||||||
<< tab << "/* signal handlers for this interface" << endl
|
<< tab << "/* signal handlers for this interface" << endl
|
||||||
<< tab << " */" << endl;
|
<< tab << " */" << endl;
|
||||||
|
|
||||||
|
// this loop generates all signals
|
||||||
for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
|
for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
|
||||||
{
|
{
|
||||||
Xml::Node &signal = **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") << "(";
|
file << tab << "virtual void " << signal.get("name") << "(";
|
||||||
|
|
||||||
|
// this loop generates all argument for a signal
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for (Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++i)
|
for (Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++i)
|
||||||
{
|
{
|
||||||
Xml::Node &arg = **ai;
|
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())
|
if (arg_name.length())
|
||||||
file << arg_name;
|
file << arg_name;
|
||||||
else
|
else
|
||||||
|
@ -486,12 +512,14 @@ void generate_proxy(Xml::Document &doc, const char *filename)
|
||||||
file << ") = 0;" << endl;
|
file << ") = 0;" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write private block header for unmarshalers
|
||||||
file << endl
|
file << endl
|
||||||
<< "private:" << endl
|
<< "private:" << endl
|
||||||
<< endl
|
<< endl
|
||||||
<< tab << "/* unmarshalers (to unpack the DBus message before calling the actual signal handler)" << endl
|
<< tab << "/* unmarshalers (to unpack the DBus message before calling the actual signal handler)" << endl
|
||||||
<< tab << " */" << endl;
|
<< tab << " */" << endl;
|
||||||
|
|
||||||
|
// loop to generate all the unmarshalers
|
||||||
for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
|
for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
|
||||||
{
|
{
|
||||||
Xml::Node &signal = **si;
|
Xml::Node &signal = **si;
|
||||||
|
@ -513,24 +541,50 @@ void generate_proxy(Xml::Document &doc, const char *filename)
|
||||||
file << tab << tab << signature_to_type(arg.get("type")) << " " ;
|
file << tab << tab << signature_to_type(arg.get("type")) << " " ;
|
||||||
|
|
||||||
string arg_name = arg.get("name");
|
string arg_name = arg.get("name");
|
||||||
if (arg_name.length())
|
|
||||||
file << arg_name << ";" << " ri >> " << arg_name << ";" << endl;
|
string arg_object = arg.get("object");
|
||||||
else
|
|
||||||
file << "arg" << i << ";" << " ri >> " << "arg" << i << ";" << endl;
|
// 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") << "(";
|
file << tab << tab << signal.get("name") << "(";
|
||||||
|
|
||||||
|
// generate all arguments for the call to the virtual function
|
||||||
unsigned int j = 0;
|
unsigned int j = 0;
|
||||||
for (Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++j)
|
for (Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++j)
|
||||||
{
|
{
|
||||||
Xml::Node &arg = **ai;
|
Xml::Node &arg = **ai;
|
||||||
|
|
||||||
string arg_name = arg.get("name");
|
string arg_name = arg.get("name");
|
||||||
if (arg_name.length())
|
string arg_object = arg.get("object");
|
||||||
file << arg_name;
|
|
||||||
else
|
if (!arg_name.length())
|
||||||
file << "arg" << j;
|
{
|
||||||
|
arg_name = "arg" + j;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg_object.length())
|
||||||
|
{
|
||||||
|
file << "_" << arg_name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file << arg_name;
|
||||||
|
}
|
||||||
|
|
||||||
if (ai+1 != args.end())
|
if (ai+1 != args.end())
|
||||||
file << ", ";
|
file << ", ";
|
||||||
|
@ -552,9 +606,34 @@ void generate_proxy(Xml::Document &doc, const char *filename)
|
||||||
file << endl;
|
file << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
file << "#endif//" << cond_comp << endl;
|
file << "#endif //" << cond_comp << endl;
|
||||||
|
|
||||||
file.close();
|
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 ();
|
||||||
|
|
||||||
|
fileX.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void generate_adaptor(Xml::Document &doc, const char *filename)
|
void generate_adaptor(Xml::Document &doc, const char *filename)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue