summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/generate_adaptor.cpp1358
-rw-r--r--tools/generate_proxy.cpp1244
-rw-r--r--tools/generator_utils.cpp270
-rw-r--r--tools/generator_utils.h2
-rw-r--r--tools/introspect.cpp62
-rw-r--r--tools/introspect.h6
-rw-r--r--tools/xml.cpp356
-rw-r--r--tools/xml.h82
-rw-r--r--tools/xml2cpp.cpp131
9 files changed, 1758 insertions, 1753 deletions
diff --git a/tools/generate_adaptor.cpp b/tools/generate_adaptor.cpp
index 940e451..f7972be 100644
--- a/tools/generate_adaptor.cpp
+++ b/tools/generate_adaptor.cpp
@@ -40,683 +40,683 @@ extern const char *dbus_includes;
*/
void generate_adaptor(Xml::Document &doc, const char *filename)
{
- ostringstream body;
- ostringstream head;
- vector <string> include_vector;
-
- head << header;
- string filestring = filename;
- underscorize(filestring);
-
- string cond_comp = "__dbusxx__" + filestring + "__ADAPTOR_MARSHAL_H";
-
- head << "#ifndef " << cond_comp << endl
- << "#define " << cond_comp << endl;
-
- head << dbus_includes;
-
- Xml::Node &root = *(doc.root);
- Xml::Nodes interfaces = root["interface"];
-
- // iterate over all interface definitions
- for (Xml::Nodes::iterator i = interfaces.begin(); i != interfaces.end(); ++i)
- {
- Xml::Node &iface = **i;
- Xml::Nodes methods = iface["method"];
- Xml::Nodes signals = iface["signal"];
- Xml::Nodes properties = iface["property"];
- Xml::Nodes ms;
- ms.insert(ms.end(), methods.begin(), methods.end());
- ms.insert(ms.end(), signals.begin(), signals.end());
-
- // gets the name of a interface: <interface name="XYZ">
- string ifacename = iface.get("name");
-
- // these interface names are skipped.
- if (ifacename == "org.freedesktop.DBus.Introspectable"
- ||ifacename == "org.freedesktop.DBus.Properties")
- {
- cerr << "skipping interface " << ifacename << endl;
- continue;
- }
-
- istringstream ss(ifacename);
- string nspace;
- unsigned int nspaces = 0;
-
- // prints all the namespaces defined with <interface name="X.Y.Z">
- while (ss.str().find('.', ss.tellg()) != string::npos)
- {
- getline(ss, nspace, '.');
-
- body << "namespace " << nspace << " {" << endl;
-
- ++nspaces;
- }
- body << endl;
-
- string ifaceclass;
-
- getline(ss, ifaceclass);
-
- // a "_adaptor" is added to class name to distinguish between proxy and adaptor
- ifaceclass += "_adaptor";
-
- cerr << "generating code for interface " << ifacename << "..." << endl;
-
- // the code from class definiton up to opening of the constructor is generated...
- body << "class " << ifaceclass << endl
- << ": public ::DBus::InterfaceAdaptor" << endl
- << "{" << endl
- << "public:" << endl
- << endl
- << tab << ifaceclass << "()" << endl
- << tab << ": ::DBus::InterfaceAdaptor(\"" << ifacename << "\")" << endl
- << tab << "{" << endl;
-
- // generates code to bind the properties
- for (Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi)
- {
- Xml::Node &property = **pi;
-
- body << tab << tab << "bind_property("
- << property.get("name") << ", "
- << "\"" << property.get("type") << "\", "
- << (property.get("access").find("read") != string::npos
- ? "true"
- : "false")
- << ", "
- << (property.get("access").find("write") != string::npos
- ? "true"
- : "false")
- << ");" << endl;
- }
-
- // generate code to register all methods
- for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
- {
- Xml::Node &method = **mi;
-
- body << tab << tab << "register_method("
- << ifaceclass << ", " << method.get("name") << ", "<< stub_name(method.get("name"))
- << ");" << endl;
- }
-
- body << tab << "}" << endl
- << endl;
-
- body << tab << "::DBus::IntrospectedInterface *introspect() const " << endl
- << tab << "{" << endl;
-
- // generate the introspect arguments
- for (Xml::Nodes::iterator mi = ms.begin(); mi != ms.end(); ++mi)
- {
- Xml::Node &method = **mi;
- Xml::Nodes args = method["arg"];
-
- body << tab << tab << "static ::DBus::IntrospectedArgument " << method.get("name") << "_args[] = " << endl
- << tab << tab << "{" << endl;
-
- for (Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai)
- {
- Xml::Node &arg = **ai;
-
- body << tab << tab << tab << "{ ";
-
- if (arg.get("name").length())
- {
- body << "\"" << arg.get("name") << "\", ";
- }
- else
- {
- body << "0, ";
- }
- body << "\"" << arg.get("type") << "\", "
- << (arg.get("direction") == "in" ? "true" : "false")
- << " }," << endl;
- }
- body << tab << tab << tab << "{ 0, 0, 0 }" << endl
- << tab << tab << "};" << endl;
- }
-
- body << tab << tab << "static ::DBus::IntrospectedMethod " << ifaceclass << "_methods[] = " << endl
- << tab << tab << "{" << endl;
-
- // generate the introspect methods
- for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
- {
- Xml::Node &method = **mi;
-
- body << tab << tab << tab << "{ \"" << method.get("name") << "\", " << method.get("name") << "_args }," << endl;
- }
-
- body << tab << tab << tab << "{ 0, 0 }" << endl
- << tab << tab << "};" << endl;
-
- body << tab << tab << "static ::DBus::IntrospectedMethod " << ifaceclass << "_signals[] = " << endl
- << tab << tab << "{" << endl;
-
- for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
- {
- Xml::Node &method = **si;
-
- body << tab << tab << tab << "{ \"" << method.get("name") << "\", " << method.get("name") << "_args }," << endl;
- }
-
- body << tab << tab << tab << "{ 0, 0 }" << endl
- << tab << tab << "};" << endl;
-
- body << tab << tab << "static ::DBus::IntrospectedProperty " << ifaceclass << "_properties[] = " << endl
- << tab << tab << "{" << endl;
-
- for (Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi)
- {
- Xml::Node &property = **pi;
-
- body << tab << tab << tab << "{ "
- << "\"" << property.get("name") << "\", "
- << "\"" << property.get("type") << "\", "
- << (property.get("access").find("read") != string::npos
- ? "true"
- : "false")
- << ", "
- << (property.get("access").find("write") != string::npos
- ? "true"
- : "false")
- << " }," << endl;
- }
-
-
- body << tab << tab << tab << "{ 0, 0, 0, 0 }" << endl
- << tab << tab << "};" << endl;
-
- // generate the Introspected interface
- body << tab << tab << "static ::DBus::IntrospectedInterface " << ifaceclass << "_interface = " << endl
- << tab << tab << "{" << endl
- << tab << tab << tab << "\"" << ifacename << "\"," << endl
- << tab << tab << tab << ifaceclass << "_methods," << endl
- << tab << tab << tab << ifaceclass << "_signals," << endl
- << tab << tab << tab << ifaceclass << "_properties" << endl
- << tab << tab << "};" << endl
- << tab << tab << "return &" << ifaceclass << "_interface;" << endl
- << tab << "}" << endl
- << endl;
-
- body << "public:" << endl
- << endl
- << tab << "/* properties exposed by this interface, use" << endl
- << tab << " * property() and property(value) to get and set a particular property" << endl
- << tab << " */" << endl;
-
- // generate the properties code
- for (Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi)
- {
- Xml::Node &property = **pi;
- string name = property.get("name");
- string type = property.get("type");
- string type_name = signature_to_type(type);
-
- body << tab << "::DBus::PropertyAdaptor< " << type_name << " > " << name << ";" << endl;
- }
-
- body << endl;
-
- body << "public:" << endl
- << endl
- << tab << "/* methods exported by this interface," << endl
- << tab << " * you will have to implement them in your ObjectAdaptor" << endl
- << tab << " */" << endl;
-
- // generate the methods code
- for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
- {
- Xml::Node &method = **mi;
- Xml::Nodes args = method["arg"];
- Xml::Nodes args_in = args.select("direction","in");
- Xml::Nodes args_out = args.select("direction","out");
- Xml::Nodes annotations = args["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- body << tab << "virtual ";
-
- // return type is 'void' if none or multible return values
- if (args_out.size() == 0 || args_out.size() > 1)
- {
- body << "void ";
- }
- else if (args_out.size() == 1)
- {
- // generate basic or object return type
- if (arg_object.length())
- {
- body << arg_object << " ";
- }
- else
- {
- body << signature_to_type(args_out.front()->get("type")) << " ";
- }
- }
-
- // generate the method name
- body << method.get("name") << "(";
-
- // generate the methods 'in' variables
- unsigned int i = 0;
- for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
- {
- Xml::Node &arg = **ai;
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_name = arg.get("name");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- // generate basic signature only if no object name available...
- if (!arg_object.length())
- {
- body << "const " << signature_to_type(arg.get("type")) << "& ";
- }
- // ...or generate object style if available
- else
- {
- body << "const " << arg_object << "& ";
-
- // store a object name to later generate header includes
- include_vector.push_back (arg_object);
- }
-
- if (arg_name.length())
- body << arg_name;
-
- if ((i+1 != args_in.size() || args_out.size() > 1))
- body << ", ";
- }
-
- // generate the method 'out' variables if multibe 'out' values exist
- if (args_out.size() > 1)
- {
- unsigned int i = 0;
- for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
- {
- Xml::Node &arg = **ao;
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_name = arg.get("name");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- // generate basic signature only if no object name available...
- if (!arg_object.length())
- {
- body << signature_to_type(arg.get("type")) << "& ";
- }
- // ...or generate object style if available
- else
- {
- body << arg_object << "& ";
-
- // store a object name to later generate header includes
- include_vector.push_back (arg_object);
- }
-
- if (arg_name.length())
- body << arg_name;
-
- if (i+1 != args_out.size())
- body << ", ";
- }
- }
- body << ") = 0;" << endl;
- }
-
- body << endl
- << "public:" << endl
- << endl
- << tab << "/* signal emitters for this interface" << endl
- << tab << " */" << endl;
-
- // generate the signals code
- for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
- {
- Xml::Node &signal = **si;
- Xml::Nodes args = signal["arg"];
-
- body << tab << "void " << signal.get("name") << "(";
-
- // generate the signal arguments
- unsigned int i = 0;
- for (Xml::Nodes::iterator a = args.begin(); a != args.end(); ++a, ++i)
- {
- Xml::Node &arg = **a;
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- // generate basic signature only if no object name available...
- if (!arg_object.length())
- {
- body << "const " << signature_to_type(arg.get("type")) << "& arg" << i+1;
- }
- // ...or generate object style if available
- else
- {
- body << "const " << arg_object << "& arg" << i+1;
-
- // store a object name to later generate header includes
- include_vector.push_back (arg_object);
- }
-
- if (i+1 != args.size())
- body << ", ";
- }
-
- body << ")" << endl
- << tab << "{" << endl
- << tab << tab << "::DBus::SignalMessage sig(\"" << signal.get("name") <<"\");" << endl;
-
- // generate the signal body
- if (!args.empty())
- {
- body << tab << tab << "::DBus::MessageIter wi = sig.writer();" << endl;
-
- unsigned int i = 0;
- for (Xml::Nodes::iterator a = args.begin(); a != args.end(); ++a, ++i)
- {
- Xml::Node &arg = **a;
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- if (arg_object.length())
- {
- body << tab << tab << signature_to_type(arg.get("type")) << " _arg" << i+1 << ";" << endl;
- body << tab << tab << "_arg" << i+1 << " << " << "arg" << i+1 << ";" << endl;
-
- body << tab << tab << "wi << _arg" << i+1 << ";" << endl;
- }
- else
- {
- body << tab << tab << "wi << arg" << i+1 << ";" << endl;
- }
- }
- }
-
- // emit the signal in method body
- body << tab << tab << "emit_signal(sig);" << endl
- << tab << "}" << endl;
- }
-
- body << endl
- << "private:" << endl
- << endl
- << tab << "/* unmarshalers (to unpack the DBus message before calling the actual interface method)" << endl
- << tab << " */" << endl;
-
- // generate the unmarshalers
- for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
- {
- Xml::Node &method = **mi;
- Xml::Nodes args = method["arg"];
- Xml::Nodes args_in = args.select("direction","in");
- Xml::Nodes args_out = args.select("direction","out");
-
- body << tab << "::DBus::Message " << stub_name(method.get("name")) << "(const ::DBus::CallMessage &call)" << endl
- << tab << "{" << endl
- << tab << tab << "::DBus::MessageIter ri = call.reader();" << endl
- << endl;
-
- // generate the 'in' variables
- unsigned int i = 1;
- for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
- {
- Xml::Node &arg = **ai;
-
- body << tab << tab << signature_to_type(arg.get("type")) << " argin" << i << ";" << " ";
- body << "ri >> argin" << i << ";" << endl;
- }
-
- // generate the 'in' object variables
- i = 1;
- for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
- {
- Xml::Node &arg = **ai;
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- if (arg_object.length())
- {
- body << tab << tab << arg_object << " _argin" << i << ";";
- body << " " << "_argin" << i << " << " << "argin" << i << ";" << endl;
- }
- }
-
- // generate 'out' variables
- if (!args_out.empty())
- {
- unsigned int i = 1;
- for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
- {
- Xml::Node &arg = **ao;
-
- body << tab << tab << signature_to_type(arg.get("type")) << " argout" << i;
-
- if (args_out.size() == 1) // a single 'out' parameter will be assigned
- {
- body << " = ";
- }
- else // multible 'out' parameters will be handled as parameters below
- {
- body << ";" << endl;
- }
- }
- }
-
- // generate 'out' object variables
- if (!args_out.empty())
- {
- unsigned int i = 1;
- for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
- {
- Xml::Node &arg = **ao;
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- // generate object types
- if (arg_object.length())
- {
- body << tab << tab << arg_object << " _argout" << i << ";" << endl;
- }
- }
- }
-
- // generate in '<<' operation
- i = 0;
- for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
- {
- Xml::Node &arg = **ai;
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
- }
-
- // do correct indent
- if (args_out.size() != 1 )
- {
- body << tab << tab;
- }
-
- body << method.get("name") << "(";
-
- // generate call stub parameters
- i = 0;
- for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
- {
- Xml::Node &arg = **ai;
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- if (arg_object.length())
- {
- body << "_argin" << i+1;
- }
- else
- {
- body << "argin" << i+1;
- }
-
- if ((i+1 != args_in.size() || args_out.size() > 1))
- body << ", ";
- }
-
- if (args_out.size() > 1)
- {
- i = 0;
- for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
- {
- Xml::Node &arg = **ao;
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- if (arg_object.length())
- {
- body << "_argout" << i+1;
- }
- else
- {
- body << "argout" << i+1;
- }
-
- if (i+1 != args_out.size())
- body << ", ";
- }
- }
-
- body << ");" << endl;
-
- body << tab << tab << "::DBus::ReturnMessage reply(call);" << endl;
-
- if (!args_out.empty())
- {
- body << tab << tab << "::DBus::MessageIter wi = reply.writer();" << endl;
-
- // generate out '<<' operation
- i = 0;
- for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
- {
- Xml::Node &arg = **ao;
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- if (arg_object.length())
- {
- body << tab << tab << "argout" << i+1 << " << " << "_argout" << i+1 << ";" << endl;
- }
- }
-
- for (unsigned int i = 0; i < args_out.size(); ++i)
- {
- body << tab << tab << "wi << argout" << i+1 << ";" << endl;
- }
- }
-
- body << tab << tab << "return reply;" << endl;
-
- body << tab << "}" << endl;
- }
-
- body << "};" << endl
- << endl;
-
- for (unsigned int i = 0; i < nspaces; ++i)
- {
- body << "} ";
- }
- body << endl;
- }
-
- body << "#endif //" << cond_comp << endl;
-
- // remove all duplicates in the header include vector
- vector<string>::const_iterator vec_end_it = unique (include_vector.begin (), include_vector.end ());
-
- for (vector<string>::const_iterator vec_it = include_vector.begin ();
- vec_it != vec_end_it;
- ++vec_it)
- {
- const string &include = *vec_it;
-
- head << "#include " << "\"" << include << ".h" << "\"" << endl;
- }
- head << endl;
-
- ofstream file(filename);
- if (file.bad())
- {
- cerr << "unable to write file " << filename << endl;
- exit(-1);
- }
-
- file << head.str ();
- file << body.str ();
-
- file.close();
+ ostringstream body;
+ ostringstream head;
+ vector <string> include_vector;
+
+ head << header;
+ string filestring = filename;
+ underscorize(filestring);
+
+ string cond_comp = "__dbusxx__" + filestring + "__ADAPTOR_MARSHAL_H";
+
+ head << "#ifndef " << cond_comp << endl
+ << "#define " << cond_comp << endl;
+
+ head << dbus_includes;
+
+ Xml::Node &root = *(doc.root);
+ Xml::Nodes interfaces = root["interface"];
+
+ // iterate over all interface definitions
+ for (Xml::Nodes::iterator i = interfaces.begin(); i != interfaces.end(); ++i)
+ {
+ Xml::Node &iface = **i;
+ Xml::Nodes methods = iface["method"];
+ Xml::Nodes signals = iface["signal"];
+ Xml::Nodes properties = iface["property"];
+ Xml::Nodes ms;
+ ms.insert(ms.end(), methods.begin(), methods.end());
+ ms.insert(ms.end(), signals.begin(), signals.end());
+
+ // gets the name of a interface: <interface name="XYZ">
+ string ifacename = iface.get("name");
+
+ // these interface names are skipped.
+ if (ifacename == "org.freedesktop.DBus.Introspectable"
+ || ifacename == "org.freedesktop.DBus.Properties")
+ {
+ cerr << "skipping interface " << ifacename << endl;
+ continue;
+ }
+
+ istringstream ss(ifacename);
+ string nspace;
+ unsigned int nspaces = 0;
+
+ // prints all the namespaces defined with <interface name="X.Y.Z">
+ while (ss.str().find('.', ss.tellg()) != string::npos)
+ {
+ getline(ss, nspace, '.');
+
+ body << "namespace " << nspace << " {" << endl;
+
+ ++nspaces;
+ }
+ body << endl;
+
+ string ifaceclass;
+
+ getline(ss, ifaceclass);
+
+ // a "_adaptor" is added to class name to distinguish between proxy and adaptor
+ ifaceclass += "_adaptor";
+
+ cerr << "generating code for interface " << ifacename << "..." << endl;
+
+ // the code from class definiton up to opening of the constructor is generated...
+ body << "class " << ifaceclass << endl
+ << ": public ::DBus::InterfaceAdaptor" << endl
+ << "{" << endl
+ << "public:" << endl
+ << endl
+ << tab << ifaceclass << "()" << endl
+ << tab << ": ::DBus::InterfaceAdaptor(\"" << ifacename << "\")" << endl
+ << tab << "{" << endl;
+
+ // generates code to bind the properties
+ for (Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi)
+ {
+ Xml::Node &property = **pi;
+
+ body << tab << tab << "bind_property("
+ << property.get("name") << ", "
+ << "\"" << property.get("type") << "\", "
+ << (property.get("access").find("read") != string::npos
+ ? "true"
+ : "false")
+ << ", "
+ << (property.get("access").find("write") != string::npos
+ ? "true"
+ : "false")
+ << ");" << endl;
+ }
+
+ // generate code to register all methods
+ for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
+ {
+ Xml::Node &method = **mi;
+
+ body << tab << tab << "register_method("
+ << ifaceclass << ", " << method.get("name") << ", " << stub_name(method.get("name"))
+ << ");" << endl;
+ }
+
+ body << tab << "}" << endl
+ << endl;
+
+ body << tab << "::DBus::IntrospectedInterface *introspect() const " << endl
+ << tab << "{" << endl;
+
+ // generate the introspect arguments
+ for (Xml::Nodes::iterator mi = ms.begin(); mi != ms.end(); ++mi)
+ {
+ Xml::Node &method = **mi;
+ Xml::Nodes args = method["arg"];
+
+ body << tab << tab << "static ::DBus::IntrospectedArgument " << method.get("name") << "_args[] = " << endl
+ << tab << tab << "{" << endl;
+
+ for (Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai)
+ {
+ Xml::Node &arg = **ai;
+
+ body << tab << tab << tab << "{ ";
+
+ if (arg.get("name").length())
+ {
+ body << "\"" << arg.get("name") << "\", ";
+ }
+ else
+ {
+ body << "0, ";
+ }
+ body << "\"" << arg.get("type") << "\", "
+ << (arg.get("direction") == "in" ? "true" : "false")
+ << " }," << endl;
+ }
+ body << tab << tab << tab << "{ 0, 0, 0 }" << endl
+ << tab << tab << "};" << endl;
+ }
+
+ body << tab << tab << "static ::DBus::IntrospectedMethod " << ifaceclass << "_methods[] = " << endl
+ << tab << tab << "{" << endl;
+
+ // generate the introspect methods
+ for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
+ {
+ Xml::Node &method = **mi;
+
+ body << tab << tab << tab << "{ \"" << method.get("name") << "\", " << method.get("name") << "_args }," << endl;
+ }
+
+ body << tab << tab << tab << "{ 0, 0 }" << endl
+ << tab << tab << "};" << endl;
+
+ body << tab << tab << "static ::DBus::IntrospectedMethod " << ifaceclass << "_signals[] = " << endl
+ << tab << tab << "{" << endl;
+
+ for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
+ {
+ Xml::Node &method = **si;
+
+ body << tab << tab << tab << "{ \"" << method.get("name") << "\", " << method.get("name") << "_args }," << endl;
+ }
+
+ body << tab << tab << tab << "{ 0, 0 }" << endl
+ << tab << tab << "};" << endl;
+
+ body << tab << tab << "static ::DBus::IntrospectedProperty " << ifaceclass << "_properties[] = " << endl
+ << tab << tab << "{" << endl;
+
+ for (Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi)
+ {
+ Xml::Node &property = **pi;
+
+ body << tab << tab << tab << "{ "
+ << "\"" << property.get("name") << "\", "
+ << "\"" << property.get("type") << "\", "
+ << (property.get("access").find("read") != string::npos
+ ? "true"
+ : "false")
+ << ", "
+ << (property.get("access").find("write") != string::npos
+ ? "true"
+ : "false")
+ << " }," << endl;
+ }
+
+
+ body << tab << tab << tab << "{ 0, 0, 0, 0 }" << endl
+ << tab << tab << "};" << endl;
+
+ // generate the Introspected interface
+ body << tab << tab << "static ::DBus::IntrospectedInterface " << ifaceclass << "_interface = " << endl
+ << tab << tab << "{" << endl
+ << tab << tab << tab << "\"" << ifacename << "\"," << endl
+ << tab << tab << tab << ifaceclass << "_methods," << endl
+ << tab << tab << tab << ifaceclass << "_signals," << endl
+ << tab << tab << tab << ifaceclass << "_properties" << endl
+ << tab << tab << "};" << endl
+ << tab << tab << "return &" << ifaceclass << "_interface;" << endl
+ << tab << "}" << endl
+ << endl;
+
+ body << "public:" << endl
+ << endl
+ << tab << "/* properties exposed by this interface, use" << endl
+ << tab << " * property() and property(value) to get and set a particular property" << endl
+ << tab << " */" << endl;
+
+ // generate the properties code
+ for (Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi)
+ {
+ Xml::Node &property = **pi;
+ string name = property.get("name");
+ string type = property.get("type");
+ string type_name = signature_to_type(type);
+
+ body << tab << "::DBus::PropertyAdaptor< " << type_name << " > " << name << ";" << endl;
+ }
+
+ body << endl;
+
+ body << "public:" << endl
+ << endl
+ << tab << "/* methods exported by this interface," << endl
+ << tab << " * you will have to implement them in your ObjectAdaptor" << endl
+ << tab << " */" << endl;
+
+ // generate the methods code
+ for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
+ {
+ Xml::Node &method = **mi;
+ Xml::Nodes args = method["arg"];
+ Xml::Nodes args_in = args.select("direction", "in");
+ Xml::Nodes args_out = args.select("direction", "out");
+ Xml::Nodes annotations = args["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ body << tab << "virtual ";
+
+ // return type is 'void' if none or multible return values
+ if (args_out.size() == 0 || args_out.size() > 1)
+ {
+ body << "void ";
+ }
+ else if (args_out.size() == 1)
+ {
+ // generate basic or object return type
+ if (arg_object.length())
+ {
+ body << arg_object << " ";
+ }
+ else
+ {
+ body << signature_to_type(args_out.front()->get("type")) << " ";
+ }
+ }
+
+ // generate the method name
+ body << method.get("name") << "(";
+
+ // generate the methods 'in' variables
+ unsigned int i = 0;
+ for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
+ {
+ Xml::Node &arg = **ai;
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_name = arg.get("name");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ // generate basic signature only if no object name available...
+ if (!arg_object.length())
+ {
+ body << "const " << signature_to_type(arg.get("type")) << "& ";
+ }
+ // ...or generate object style if available
+ else
+ {
+ body << "const " << arg_object << "& ";
+
+ // store a object name to later generate header includes
+ include_vector.push_back(arg_object);
+ }
+
+ if (arg_name.length())
+ body << arg_name;
+
+ if ((i + 1 != args_in.size() || args_out.size() > 1))
+ body << ", ";
+ }
+
+ // generate the method 'out' variables if multibe 'out' values exist
+ if (args_out.size() > 1)
+ {
+ unsigned int i = 0;
+ for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
+ {
+ Xml::Node &arg = **ao;
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_name = arg.get("name");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ // generate basic signature only if no object name available...
+ if (!arg_object.length())
+ {
+ body << signature_to_type(arg.get("type")) << "& ";
+ }
+ // ...or generate object style if available
+ else
+ {
+ body << arg_object << "& ";
+
+ // store a object name to later generate header includes
+ include_vector.push_back(arg_object);
+ }
+
+ if (arg_name.length())
+ body << arg_name;
+
+ if (i + 1 != args_out.size())
+ body << ", ";
+ }
+ }
+ body << ") = 0;" << endl;
+ }
+
+ body << endl
+ << "public:" << endl
+ << endl
+ << tab << "/* signal emitters for this interface" << endl
+ << tab << " */" << endl;
+
+ // generate the signals code
+ for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
+ {
+ Xml::Node &signal = **si;
+ Xml::Nodes args = signal["arg"];
+
+ body << tab << "void " << signal.get("name") << "(";
+
+ // generate the signal arguments
+ unsigned int i = 0;
+ for (Xml::Nodes::iterator a = args.begin(); a != args.end(); ++a, ++i)
+ {
+ Xml::Node &arg = **a;
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ // generate basic signature only if no object name available...
+ if (!arg_object.length())
+ {
+ body << "const " << signature_to_type(arg.get("type")) << "& arg" << i + 1;
+ }
+ // ...or generate object style if available
+ else
+ {
+ body << "const " << arg_object << "& arg" << i + 1;
+
+ // store a object name to later generate header includes
+ include_vector.push_back(arg_object);
+ }
+
+ if (i + 1 != args.size())
+ body << ", ";
+ }
+
+ body << ")" << endl
+ << tab << "{" << endl
+ << tab << tab << "::DBus::SignalMessage sig(\"" << signal.get("name") << "\");" << endl;
+
+ // generate the signal body
+ if (!args.empty())
+ {
+ body << tab << tab << "::DBus::MessageIter wi = sig.writer();" << endl;
+
+ unsigned int i = 0;
+ for (Xml::Nodes::iterator a = args.begin(); a != args.end(); ++a, ++i)
+ {
+ Xml::Node &arg = **a;
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ if (arg_object.length())
+ {
+ body << tab << tab << signature_to_type(arg.get("type")) << " _arg" << i + 1 << ";" << endl;
+ body << tab << tab << "_arg" << i + 1 << " << " << "arg" << i + 1 << ";" << endl;
+
+ body << tab << tab << "wi << _arg" << i + 1 << ";" << endl;
+ }
+ else
+ {
+ body << tab << tab << "wi << arg" << i + 1 << ";" << endl;
+ }
+ }
+ }
+
+ // emit the signal in method body
+ body << tab << tab << "emit_signal(sig);" << endl
+ << tab << "}" << endl;
+ }
+
+ body << endl
+ << "private:" << endl
+ << endl
+ << tab << "/* unmarshalers (to unpack the DBus message before calling the actual interface method)" << endl
+ << tab << " */" << endl;
+
+ // generate the unmarshalers
+ for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
+ {
+ Xml::Node &method = **mi;
+ Xml::Nodes args = method["arg"];
+ Xml::Nodes args_in = args.select("direction", "in");
+ Xml::Nodes args_out = args.select("direction", "out");
+
+ body << tab << "::DBus::Message " << stub_name(method.get("name")) << "(const ::DBus::CallMessage &call)" << endl
+ << tab << "{" << endl
+ << tab << tab << "::DBus::MessageIter ri = call.reader();" << endl
+ << endl;
+
+ // generate the 'in' variables
+ unsigned int i = 1;
+ for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
+ {
+ Xml::Node &arg = **ai;
+
+ body << tab << tab << signature_to_type(arg.get("type")) << " argin" << i << ";" << " ";
+ body << "ri >> argin" << i << ";" << endl;
+ }
+
+ // generate the 'in' object variables
+ i = 1;
+ for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
+ {
+ Xml::Node &arg = **ai;
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ if (arg_object.length())
+ {
+ body << tab << tab << arg_object << " _argin" << i << ";";
+ body << " " << "_argin" << i << " << " << "argin" << i << ";" << endl;
+ }
+ }
+
+ // generate 'out' variables
+ if (!args_out.empty())
+ {
+ unsigned int i = 1;
+ for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
+ {
+ Xml::Node &arg = **ao;
+
+ body << tab << tab << signature_to_type(arg.get("type")) << " argout" << i;
+
+ if (args_out.size() == 1) // a single 'out' parameter will be assigned
+ {
+ body << " = ";
+ }
+ else // multible 'out' parameters will be handled as parameters below
+ {
+ body << ";" << endl;
+ }
+ }
+ }
+
+ // generate 'out' object variables
+ if (!args_out.empty())
+ {
+ unsigned int i = 1;
+ for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
+ {
+ Xml::Node &arg = **ao;
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ // generate object types
+ if (arg_object.length())
+ {
+ body << tab << tab << arg_object << " _argout" << i << ";" << endl;
+ }
+ }
+ }
+
+ // generate in '<<' operation
+ i = 0;
+ for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
+ {
+ Xml::Node &arg = **ai;
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+ }
+
+ // do correct indent
+ if (args_out.size() != 1)
+ {
+ body << tab << tab;
+ }
+
+ body << method.get("name") << "(";
+
+ // generate call stub parameters
+ i = 0;
+ for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
+ {
+ Xml::Node &arg = **ai;
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ if (arg_object.length())
+ {
+ body << "_argin" << i + 1;
+ }
+ else
+ {
+ body << "argin" << i + 1;
+ }
+
+ if ((i + 1 != args_in.size() || args_out.size() > 1))
+ body << ", ";
+ }
+
+ if (args_out.size() > 1)
+ {
+ i = 0;
+ for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
+ {
+ Xml::Node &arg = **ao;
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ if (arg_object.length())
+ {
+ body << "_argout" << i + 1;
+ }
+ else
+ {
+ body << "argout" << i + 1;
+ }
+
+ if (i + 1 != args_out.size())
+ body << ", ";
+ }
+ }
+
+ body << ");" << endl;
+
+ body << tab << tab << "::DBus::ReturnMessage reply(call);" << endl;
+
+ if (!args_out.empty())
+ {
+ body << tab << tab << "::DBus::MessageIter wi = reply.writer();" << endl;
+
+ // generate out '<<' operation
+ i = 0;
+ for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
+ {
+ Xml::Node &arg = **ao;
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ if (arg_object.length())
+ {
+ body << tab << tab << "argout" << i + 1 << " << " << "_argout" << i + 1 << ";" << endl;
+ }
+ }
+
+ for (unsigned int i = 0; i < args_out.size(); ++i)
+ {
+ body << tab << tab << "wi << argout" << i + 1 << ";" << endl;
+ }
+ }
+
+ body << tab << tab << "return reply;" << endl;
+
+ body << tab << "}" << endl;
+ }
+
+ body << "};" << endl
+ << endl;
+
+ for (unsigned int i = 0; i < nspaces; ++i)
+ {
+ body << "} ";
+ }
+ body << endl;
+ }
+
+ body << "#endif //" << cond_comp << endl;
+
+ // remove all duplicates in the header include vector
+ vector<string>::const_iterator vec_end_it = unique(include_vector.begin(), include_vector.end());
+
+ for (vector<string>::const_iterator vec_it = include_vector.begin();
+ vec_it != vec_end_it;
+ ++vec_it)
+ {
+ const string &include = *vec_it;
+
+ head << "#include " << "\"" << include << ".h" << "\"" << endl;
+ }
+ head << endl;
+
+ ofstream file(filename);
+ if (file.bad())
+ {
+ cerr << "unable to write file " << filename << endl;
+ exit(-1);
+ }
+
+ file << head.str();
+ file << body.str();
+
+ file.close();
}
diff --git a/tools/generate_proxy.cpp b/tools/generate_proxy.cpp
index a90d025..bf1094a 100644
--- a/tools/generate_proxy.cpp
+++ b/tools/generate_proxy.cpp
@@ -40,626 +40,626 @@ extern const char *dbus_includes;
*/
void generate_proxy(Xml::Document &doc, const char *filename)
{
- ostringstream body;
- ostringstream head;
- vector <string> include_vector;
-
- head << header;
- string filestring = filename;
- underscorize(filestring);
-
- string cond_comp = "__dbusxx__" + filestring + "__PROXY_MARSHAL_H";
-
- head << "#ifndef " << cond_comp << endl
- << "#define " << cond_comp << endl;
-
- head << dbus_includes;
-
- Xml::Node &root = *(doc.root);
- Xml::Nodes interfaces = root["interface"];
-
- // iterate over all interface definitions
- for (Xml::Nodes::iterator i = interfaces.begin(); i != interfaces.end(); ++i)
- {
- Xml::Node &iface = **i;
- Xml::Nodes methods = iface["method"];
- Xml::Nodes signals = iface["signal"];
- Xml::Nodes properties = iface["property"];
- Xml::Nodes ms;
- ms.insert(ms.end(), methods.begin(), methods.end());
- ms.insert(ms.end(), signals.begin(), signals.end());
-
- // gets the name of a interface: <interface name="XYZ">
- string ifacename = iface.get("name");
-
- // these interface names are skipped.
- if (ifacename == "org.freedesktop.DBus.Introspectable"
- ||ifacename == "org.freedesktop.DBus.Properties")
- {
- cerr << "skipping interface " << ifacename << endl;
- continue;
- }
-
- istringstream ss(ifacename);
- string nspace;
- unsigned int nspaces = 0;
-
- // prints all the namespaces defined with <interface name="X.Y.Z">
- while (ss.str().find('.', ss.tellg()) != string::npos)
- {
- getline(ss, nspace, '.');
-
- body << "namespace " << nspace << " {" << endl;
-
- ++nspaces;
- }
- body << endl;
-
- 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...
- body << "class " << ifaceclass << endl
- << ": public ::DBus::InterfaceProxy" << endl
- << "{" << endl
- << "public:" << endl
- << endl
- << tab << ifaceclass << "()" << endl
- << tab << ": ::DBus::InterfaceProxy(\"" << ifacename << "\")" << endl
- << tab << "{" << endl;
-
- // 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;
-
- string marshname = "_" + signal.get("name") + "_stub";
-
- body << tab << tab << "connect_signal("
- << ifaceclass << ", " << signal.get("name") << ", " << stub_name(signal.get("name"))
- << ");" << endl;
- }
-
- // the constructor ends here
- body << tab << "}" << endl
- << endl;
-
- // write public block header for properties
- body << "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)
- {
- Xml::Node & property = **pi;
- string prop_name = property.get ("name");
- string property_access = property.get ("access");
- if (property_access == "read" || property_access == "readwrite")
- {
- body << tab << tab << "const " << signature_to_type (property.get("type"))
- << " " << prop_name << "() {" << endl;
- body << tab << tab << tab << "::DBus::CallMessage call ;\n ";
- body << tab << tab << tab
- << "call.member(\"Get\"); call.interface(\"org.freedesktop.DBus.Properties\");"
- << endl;
- body << tab << tab << tab
- << "::DBus::MessageIter wi = call.writer(); " << endl;
- body << tab << tab << tab
- << "const std::string interface_name = \"" << ifacename << "\";"
- << endl;
- body << tab << tab << tab
- << "const std::string property_name = \"" << prop_name << "\";"
- << endl;
- body << tab << tab << tab << "wi << interface_name;" << endl;
- body << tab << tab << tab << "wi << property_name;" << endl;
- body << tab << tab << tab
- << "::DBus::Message ret = this->invoke_method (call);" << endl;
- // TODO: support invoke_method_NoReply for properties
- body << tab << tab << tab
- << "::DBus::MessageIter ri = ret.reader ();" << endl;
- body << tab << tab << tab << "::DBus::Variant argout; " << endl;
- body << tab << tab << tab << "ri >> argout;" << endl;
- body << tab << tab << tab << "return argout;" << endl;
- body << tab << tab << "};" << endl;
- }
-
- if (property_access == "write" || property_access == "readwrite")
- {
- body << tab << tab << "void " << prop_name << "( const "<< signature_to_type (property.get("type")) << " & input" << ") {" << endl;
- body << tab << tab << tab << "::DBus::CallMessage call ;\n ";
- body << tab << tab << tab <<"call.member(\"Set\"); call.interface( \"org.freedesktop.DBus.Properties\");"<< endl;
- body << tab << tab << tab <<"::DBus::MessageIter wi = call.writer(); " << endl;
- body << tab << tab << tab <<"::DBus::Variant value;" << endl;
- body << tab << tab << tab <<"::DBus::MessageIter vi = value.writer ();" << endl;
- body << tab << tab << tab <<"vi << input;" << endl;
- body << tab << tab << tab <<"const std::string interface_name = \"" << ifacename << "\";" << endl;
- body << tab << tab << tab <<"const std::string property_name = \"" << prop_name << "\";"<< endl;
- body << tab << tab << tab <<"wi << interface_name;" << endl;
- body << tab << tab << tab <<"wi << property_name;" << endl;
- body << tab << tab << tab <<"wi << value;" << endl;
- body << tab << tab << tab <<"::DBus::Message ret = this->invoke_method (call);" << endl;
- // TODO: support invoke_method_noreply for properties
- body << tab << tab << "};" << endl;
- }
- }
-
- // write public block header for methods
- body << "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;
- Xml::Nodes args = method["arg"];
- Xml::Nodes args_in = args.select("direction","in");
- Xml::Nodes args_out = args.select("direction","out");
- Xml::Nodes annotations = args["annotation"];
- Xml::Nodes method_annotations = method["annotation"];
- Xml::Nodes annotations_noreply = method_annotations.select("name","org.freedesktop.DBus.Method.NoReply");
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
- bool annotation_noreply_value = false;
-
- // parse method level noreply annotations
- if (!annotations_noreply.empty())
- {
- string annotation_noreply_value_str = annotations_noreply.front()->get("value");
-
- if (annotation_noreply_value_str == "true")
- {
- annotation_noreply_value = true;
- }
- }
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- if (args_out.size() == 0 || args_out.size() > 1)
- {
- body << tab << "void ";
- }
- else if (args_out.size() == 1)
- {
- if (arg_object.length())
- {
- body << tab << arg_object << " ";
- }
- else
- {
- body << tab << signature_to_type(args_out.front()->get("type")) << " ";
- }
- }
-
- body << method.get("name") << "(";
-
- // generate all 'in' arguments for a method signature
- unsigned int i = 0;
- for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
- {
- Xml::Node &arg = **ai;
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- // generate basic signature only if no object name available...
- if (!arg_object.length())
- {
- body << "const " << signature_to_type(arg.get("type")) << "& ";
- }
- // ...or generate object style if available
- else
- {
- body << "const " << arg_object << "& ";
-
- // store a object name to later generate header includes
- include_vector.push_back (arg_object);
- }
-
- string arg_name = arg.get("name");
- if (arg_name.length())
- body << arg_name;
- else
- body << "argin" << i;
-
- if ((i+1 != args_in.size() || args_out.size() > 1))
- body << ", ";
- }
-
- if (args_out.size() > 1)
- {
- // generate all 'out' arguments for a method signature
- unsigned int j = 0;
- for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++j)
- {
- Xml::Node &arg = **ao;
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- // generate basic signature only if no object name available...
- if (!arg_object.length())
- {
- body << signature_to_type(arg.get("type")) << "&";
- }
- // ...or generate object style if available
- else
- {
- body << arg_object << "& ";
-
- // store a object name to later generate header includes
- include_vector.push_back (arg_object);
- }
-
- string arg_name = arg.get("name");
- if (arg_name.length())
- body << " " << arg_name;
- else
- body << " argout" << j;
-
- if (j+1 != args_out.size())
- body << ", ";
- }
- }
- body << ")" << endl;
-
- body << tab << "{" << endl
- << tab << tab << "::DBus::CallMessage call;" << endl;
-
- if (!args_in.empty())
- {
- body << tab << tab << "::DBus::MessageIter wi = call.writer();" << endl
- << endl;
- }
-
- // generate all 'in' arguments for a method body
- i = 0;
- for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
- {
- Xml::Node &arg = **ai;
- string arg_name = arg.get("name");
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- if (!arg_name.length())
- {
- arg_name = "argin";
- arg_name += toString <uint> (i);
- }
-
- // generate extra code to wrap object
- if (arg_object.length())
- {
- body << tab << tab << signature_to_type(arg.get("type")) << "_" << arg_name << ";" << endl;
- body << tab << tab << "_" << arg_name << " << " << arg_name << ";" << endl;
-
- arg_name = string ("_") + arg_name;
- }
-
- body << tab << tab << "wi << " << arg_name << ";" << endl;
- }
-
- body << tab << tab << "call.member(\"" << method.get("name") << "\");" << endl;
-
- // generate noreply/reply method calls
- if (annotation_noreply_value)
- {
- if (args_out.size ())
- {
- cerr << "Function: " << method.get("name") << ":" << endl;
- cerr << "Option 'org.freedesktop.DBus.Method.NoReply' not allowed for methods with 'out' variables!" << endl << "-> Option ignored!" << endl;
-
- body << tab << tab << "::DBus::Message ret = invoke_method (call);" << endl;
- }
- else
- {
- body << tab << tab << "assert (invoke_method_noreply (call));" << endl; // will only assert in case of no memory
- }
- }
- else
- {
- body << tab << tab << "::DBus::Message ret = invoke_method (call);" << endl;
- }
-
- if (!args_out.empty())
- {
- body << tab << tab << "::DBus::MessageIter ri = ret.reader();" << endl
- << endl;
- }
-
- // generate 'out' values as return if only one existing
- if (args_out.size() == 1)
- {
- Xml::Nodes annotations = args_out["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- if (arg_object.length())
- {
- body << tab << tab << arg_object << " _argout;" << endl;
- }
-
- body << tab << tab << signature_to_type(args_out.front()->get("type")) << " argout;" << endl;
-
- body << tab << tab << "ri >> argout;" << endl;
-
- if (arg_object.length())
- {
- body << tab << tab << "_argout << argout;" << endl;
- body << tab << tab << "return _argout;" << endl;
- }
- else
- {
- body << tab << tab << "return argout;" << endl;
- }
- }
- else if (args_out.size() > 1)
- {
- // generate multible 'out' value
- unsigned int i = 0;
- for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
- {
- Xml::Node &arg = **ao;
- string arg_name = arg.get("name");
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- if (!arg_name.length())
- {
- arg_name = "argout" + toString <uint> (i);
- }
-
- if (arg_object.length())
- {
- body << tab << tab << signature_to_type(arg.get("type")) << "_" << arg_name << ";" << endl;
- }
-
- if (arg_object.length())
- {
- body << tab << tab << "ri >> " << "_" << arg_name << ";" << endl;
- }
- else
- {
- body << tab << tab << "ri >> " << arg_name << ";" << endl;
- }
-
- if (arg_object.length())
- {
- body << tab << tab << arg_name << " << " << "_" << arg_name << ";" << endl;
- }
- }
- }
-
- body << tab << "}" << endl
- << endl;
- }
-
- // write public block header for signals
- body << 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;
- Xml::Nodes args = signal["arg"];
-
- body << 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;
- string arg_name = arg.get("name");
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- // generate basic signature only if no object name available...
- if (!arg_object.length())
- {
- body << "const " << signature_to_type(arg.get("type")) << "& ";
- }
- // ...or generate object style if available
- else
- {
- body << "const " << arg_object << "& ";
-
- // store a object name to later generate header includes
- include_vector.push_back (arg_object);
- }
-
- if (arg_name.length())
- body << arg_name;
- else
- body << "argin" << i;
-
- if ((ai+1 != args.end()))
- body << ", ";
- }
- body << ") = 0;" << endl;
- }
-
- // write private block header for unmarshalers
- body << endl
- << "private:" << endl
- << endl
- << tab << "/* unmarshalers (to unpack the DBus message before calling the actual signal handler)" << endl
- << tab << " */" << endl;
-
- // generate all the unmarshalers
- for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
- {
- Xml::Node &signal = **si;
- Xml::Nodes args = signal["arg"];
-
- body << tab << "void " << stub_name(signal.get("name")) << "(const ::DBus::SignalMessage &sig)" << endl
- << tab << "{" << endl;
-
- if (!args.empty())
- {
- body << tab << tab << "::DBus::MessageIter ri = sig.reader();" << endl
- << endl;
- }
-
- unsigned int i = 0;
- for (Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++i)
- {
- Xml::Node &arg = **ai;
- string arg_name = arg.get("name");
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- body << tab << tab << signature_to_type(arg.get("type")) << " " ;
-
- // use a default if no arg name given
- if (!arg_name.length())
- {
- arg_name = "arg" + toString <uint> (i);
- }
-
- body << arg_name << ";" << endl;
- body << 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())
- {
- body << tab << tab << arg_object << " _" << arg_name << ";" << endl;
- body << tab << tab << "_" << arg_name << " << " << arg_name << ";" << endl;
-
- // store a object name to later generate header includes
- include_vector.push_back (arg_object);
- }
- }
-
- body << 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");
- Xml::Nodes annotations = arg["annotation"];
- Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object");
- string arg_object;
-
- if (!annotations_object.empty())
- {
- arg_object = annotations_object.front()->get("value");
- }
-
- if (!arg_name.length())
- {
- arg_name = "arg" + toString <uint> (j);
- }
-
- if (arg_object.length())
- {
- body << "_" << arg_name;
- }
- else
- {
- body << arg_name;
- }
-
- if (ai+1 != args.end())
- body << ", ";
- }
-
- body << ");" << endl;
-
- body << tab << "}" << endl;
- }
-
- body << "};" << endl
- << endl;
-
- for (unsigned int i = 0; i < nspaces; ++i)
- {
- body << "} ";
- }
- body << endl;
- }
-
- body << "#endif //" << cond_comp << endl;
-
- // remove all duplicates in the header include vector
- vector<string>::const_iterator vec_end_it = unique (include_vector.begin (), include_vector.end ());
-
- for (vector<string>::const_iterator vec_it = include_vector.begin ();
- vec_it != vec_end_it;
- ++vec_it)
- {
- const string &include = *vec_it;
-
- head << "#include " << "\"" << include << ".h" << "\"" << endl;
- }
- head << endl;
-
- ofstream file(filename);
- if (file.bad())
- {
- cerr << "unable to write file " << filename << endl;
- exit(-1);
- }
-
- file << head.str ();
- file << body.str ();
-
- file.close();
+ ostringstream body;
+ ostringstream head;
+ vector <string> include_vector;
+
+ head << header;
+ string filestring = filename;
+ underscorize(filestring);
+
+ string cond_comp = "__dbusxx__" + filestring + "__PROXY_MARSHAL_H";
+
+ head << "#ifndef " << cond_comp << endl
+ << "#define " << cond_comp << endl;
+
+ head << dbus_includes;
+
+ Xml::Node &root = *(doc.root);
+ Xml::Nodes interfaces = root["interface"];
+
+ // iterate over all interface definitions
+ for (Xml::Nodes::iterator i = interfaces.begin(); i != interfaces.end(); ++i)
+ {
+ Xml::Node &iface = **i;
+ Xml::Nodes methods = iface["method"];
+ Xml::Nodes signals = iface["signal"];
+ Xml::Nodes properties = iface["property"];
+ Xml::Nodes ms;
+ ms.insert(ms.end(), methods.begin(), methods.end());
+ ms.insert(ms.end(), signals.begin(), signals.end());
+
+ // gets the name of a interface: <interface name="XYZ">
+ string ifacename = iface.get("name");
+
+ // these interface names are skipped.
+ if (ifacename == "org.freedesktop.DBus.Introspectable"
+ || ifacename == "org.freedesktop.DBus.Properties")
+ {
+ cerr << "skipping interface " << ifacename << endl;
+ continue;
+ }
+
+ istringstream ss(ifacename);
+ string nspace;
+ unsigned int nspaces = 0;
+
+ // prints all the namespaces defined with <interface name="X.Y.Z">
+ while (ss.str().find('.', ss.tellg()) != string::npos)
+ {
+ getline(ss, nspace, '.');
+
+ body << "namespace " << nspace << " {" << endl;
+
+ ++nspaces;
+ }
+ body << endl;
+
+ 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...
+ body << "class " << ifaceclass << endl
+ << ": public ::DBus::InterfaceProxy" << endl
+ << "{" << endl
+ << "public:" << endl
+ << endl
+ << tab << ifaceclass << "()" << endl
+ << tab << ": ::DBus::InterfaceProxy(\"" << ifacename << "\")" << endl
+ << tab << "{" << endl;
+
+ // 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;
+
+ string marshname = "_" + signal.get("name") + "_stub";
+
+ body << tab << tab << "connect_signal("
+ << ifaceclass << ", " << signal.get("name") << ", " << stub_name(signal.get("name"))
+ << ");" << endl;
+ }
+
+ // the constructor ends here
+ body << tab << "}" << endl
+ << endl;
+
+ // write public block header for properties
+ body << "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)
+ {
+ Xml::Node &property = **pi;
+ string prop_name = property.get("name");
+ string property_access = property.get("access");
+ if (property_access == "read" || property_access == "readwrite")
+ {
+ body << tab << tab << "const " << signature_to_type(property.get("type"))
+ << " " << prop_name << "() {" << endl;
+ body << tab << tab << tab << "::DBus::CallMessage call ;\n ";
+ body << tab << tab << tab
+ << "call.member(\"Get\"); call.interface(\"org.freedesktop.DBus.Properties\");"
+ << endl;
+ body << tab << tab << tab
+ << "::DBus::MessageIter wi = call.writer(); " << endl;
+ body << tab << tab << tab
+ << "const std::string interface_name = \"" << ifacename << "\";"
+ << endl;
+ body << tab << tab << tab
+ << "const std::string property_name = \"" << prop_name << "\";"
+ << endl;
+ body << tab << tab << tab << "wi << interface_name;" << endl;
+ body << tab << tab << tab << "wi << property_name;" << endl;
+ body << tab << tab << tab
+ << "::DBus::Message ret = this->invoke_method (call);" << endl;
+ // TODO: support invoke_method_NoReply for properties
+ body << tab << tab << tab
+ << "::DBus::MessageIter ri = ret.reader ();" << endl;
+ body << tab << tab << tab << "::DBus::Variant argout; " << endl;
+ body << tab << tab << tab << "ri >> argout;" << endl;
+ body << tab << tab << tab << "return argout;" << endl;
+ body << tab << tab << "};" << endl;
+ }
+
+ if (property_access == "write" || property_access == "readwrite")
+ {
+ body << tab << tab << "void " << prop_name << "( const " << signature_to_type(property.get("type")) << " & input" << ") {" << endl;
+ body << tab << tab << tab << "::DBus::CallMessage call ;\n ";
+ body << tab << tab << tab << "call.member(\"Set\"); call.interface( \"org.freedesktop.DBus.Properties\");" << endl;
+ body << tab << tab << tab << "::DBus::MessageIter wi = call.writer(); " << endl;
+ body << tab << tab << tab << "::DBus::Variant value;" << endl;
+ body << tab << tab << tab << "::DBus::MessageIter vi = value.writer ();" << endl;
+ body << tab << tab << tab << "vi << input;" << endl;
+ body << tab << tab << tab << "const std::string interface_name = \"" << ifacename << "\";" << endl;
+ body << tab << tab << tab << "const std::string property_name = \"" << prop_name << "\";" << endl;
+ body << tab << tab << tab << "wi << interface_name;" << endl;
+ body << tab << tab << tab << "wi << property_name;" << endl;
+ body << tab << tab << tab << "wi << value;" << endl;
+ body << tab << tab << tab << "::DBus::Message ret = this->invoke_method (call);" << endl;
+ // TODO: support invoke_method_noreply for properties
+ body << tab << tab << "};" << endl;
+ }
+ }
+
+ // write public block header for methods
+ body << "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;
+ Xml::Nodes args = method["arg"];
+ Xml::Nodes args_in = args.select("direction", "in");
+ Xml::Nodes args_out = args.select("direction", "out");
+ Xml::Nodes annotations = args["annotation"];
+ Xml::Nodes method_annotations = method["annotation"];
+ Xml::Nodes annotations_noreply = method_annotations.select("name", "org.freedesktop.DBus.Method.NoReply");
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+ bool annotation_noreply_value = false;
+
+ // parse method level noreply annotations
+ if (!annotations_noreply.empty())
+ {
+ string annotation_noreply_value_str = annotations_noreply.front()->get("value");
+
+ if (annotation_noreply_value_str == "true")
+ {
+ annotation_noreply_value = true;
+ }
+ }
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ if (args_out.size() == 0 || args_out.size() > 1)
+ {
+ body << tab << "void ";
+ }
+ else if (args_out.size() == 1)
+ {
+ if (arg_object.length())
+ {
+ body << tab << arg_object << " ";
+ }
+ else
+ {
+ body << tab << signature_to_type(args_out.front()->get("type")) << " ";
+ }
+ }
+
+ body << method.get("name") << "(";
+
+ // generate all 'in' arguments for a method signature
+ unsigned int i = 0;
+ for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
+ {
+ Xml::Node &arg = **ai;
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ // generate basic signature only if no object name available...
+ if (!arg_object.length())
+ {
+ body << "const " << signature_to_type(arg.get("type")) << "& ";
+ }
+ // ...or generate object style if available
+ else
+ {
+ body << "const " << arg_object << "& ";
+
+ // store a object name to later generate header includes
+ include_vector.push_back(arg_object);
+ }
+
+ string arg_name = arg.get("name");
+ if (arg_name.length())
+ body << arg_name;
+ else
+ body << "argin" << i;
+
+ if ((i + 1 != args_in.size() || args_out.size() > 1))
+ body << ", ";
+ }
+
+ if (args_out.size() > 1)
+ {
+ // generate all 'out' arguments for a method signature
+ unsigned int j = 0;
+ for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++j)
+ {
+ Xml::Node &arg = **ao;
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ // generate basic signature only if no object name available...
+ if (!arg_object.length())
+ {
+ body << signature_to_type(arg.get("type")) << "&";
+ }
+ // ...or generate object style if available
+ else
+ {
+ body << arg_object << "& ";
+
+ // store a object name to later generate header includes
+ include_vector.push_back(arg_object);
+ }
+
+ string arg_name = arg.get("name");
+ if (arg_name.length())
+ body << " " << arg_name;
+ else
+ body << " argout" << j;
+
+ if (j + 1 != args_out.size())
+ body << ", ";
+ }
+ }
+ body << ")" << endl;
+
+ body << tab << "{" << endl
+ << tab << tab << "::DBus::CallMessage call;" << endl;
+
+ if (!args_in.empty())
+ {
+ body << tab << tab << "::DBus::MessageIter wi = call.writer();" << endl
+ << endl;
+ }
+
+ // generate all 'in' arguments for a method body
+ i = 0;
+ for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
+ {
+ Xml::Node &arg = **ai;
+ string arg_name = arg.get("name");
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ if (!arg_name.length())
+ {
+ arg_name = "argin";
+ arg_name += toString <uint> (i);
+ }
+
+ // generate extra code to wrap object
+ if (arg_object.length())
+ {
+ body << tab << tab << signature_to_type(arg.get("type")) << "_" << arg_name << ";" << endl;
+ body << tab << tab << "_" << arg_name << " << " << arg_name << ";" << endl;
+
+ arg_name = string("_") + arg_name;
+ }
+
+ body << tab << tab << "wi << " << arg_name << ";" << endl;
+ }
+
+ body << tab << tab << "call.member(\"" << method.get("name") << "\");" << endl;
+
+ // generate noreply/reply method calls
+ if (annotation_noreply_value)
+ {
+ if (args_out.size())
+ {
+ cerr << "Function: " << method.get("name") << ":" << endl;
+ cerr << "Option 'org.freedesktop.DBus.Method.NoReply' not allowed for methods with 'out' variables!" << endl << "-> Option ignored!" << endl;
+
+ body << tab << tab << "::DBus::Message ret = invoke_method (call);" << endl;
+ }
+ else
+ {
+ body << tab << tab << "assert (invoke_method_noreply (call));" << endl; // will only assert in case of no memory
+ }
+ }
+ else
+ {
+ body << tab << tab << "::DBus::Message ret = invoke_method (call);" << endl;
+ }
+
+ if (!args_out.empty())
+ {
+ body << tab << tab << "::DBus::MessageIter ri = ret.reader();" << endl
+ << endl;
+ }
+
+ // generate 'out' values as return if only one existing
+ if (args_out.size() == 1)
+ {
+ Xml::Nodes annotations = args_out["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ if (arg_object.length())
+ {
+ body << tab << tab << arg_object << " _argout;" << endl;
+ }
+
+ body << tab << tab << signature_to_type(args_out.front()->get("type")) << " argout;" << endl;
+
+ body << tab << tab << "ri >> argout;" << endl;
+
+ if (arg_object.length())
+ {
+ body << tab << tab << "_argout << argout;" << endl;
+ body << tab << tab << "return _argout;" << endl;
+ }
+ else
+ {
+ body << tab << tab << "return argout;" << endl;
+ }
+ }
+ else if (args_out.size() > 1)
+ {
+ // generate multible 'out' value
+ unsigned int i = 0;
+ for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
+ {
+ Xml::Node &arg = **ao;
+ string arg_name = arg.get("name");
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ if (!arg_name.length())
+ {
+ arg_name = "argout" + toString <uint> (i);
+ }
+
+ if (arg_object.length())
+ {
+ body << tab << tab << signature_to_type(arg.get("type")) << "_" << arg_name << ";" << endl;
+ }
+
+ if (arg_object.length())
+ {
+ body << tab << tab << "ri >> " << "_" << arg_name << ";" << endl;
+ }
+ else
+ {
+ body << tab << tab << "ri >> " << arg_name << ";" << endl;
+ }
+
+ if (arg_object.length())
+ {
+ body << tab << tab << arg_name << " << " << "_" << arg_name << ";" << endl;
+ }
+ }
+ }
+
+ body << tab << "}" << endl
+ << endl;
+ }
+
+ // write public block header for signals
+ body << 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;
+ Xml::Nodes args = signal["arg"];
+
+ body << 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;
+ string arg_name = arg.get("name");
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ // generate basic signature only if no object name available...
+ if (!arg_object.length())
+ {
+ body << "const " << signature_to_type(arg.get("type")) << "& ";
+ }
+ // ...or generate object style if available
+ else
+ {
+ body << "const " << arg_object << "& ";
+
+ // store a object name to later generate header includes
+ include_vector.push_back(arg_object);
+ }
+
+ if (arg_name.length())
+ body << arg_name;
+ else
+ body << "argin" << i;
+
+ if ((ai + 1 != args.end()))
+ body << ", ";
+ }
+ body << ") = 0;" << endl;
+ }
+
+ // write private block header for unmarshalers
+ body << endl
+ << "private:" << endl
+ << endl
+ << tab << "/* unmarshalers (to unpack the DBus message before calling the actual signal handler)" << endl
+ << tab << " */" << endl;
+
+ // generate all the unmarshalers
+ for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
+ {
+ Xml::Node &signal = **si;
+ Xml::Nodes args = signal["arg"];
+
+ body << tab << "void " << stub_name(signal.get("name")) << "(const ::DBus::SignalMessage &sig)" << endl
+ << tab << "{" << endl;
+
+ if (!args.empty())
+ {
+ body << tab << tab << "::DBus::MessageIter ri = sig.reader();" << endl
+ << endl;
+ }
+
+ unsigned int i = 0;
+ for (Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++i)
+ {
+ Xml::Node &arg = **ai;
+ string arg_name = arg.get("name");
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ body << tab << tab << signature_to_type(arg.get("type")) << " " ;
+
+ // use a default if no arg name given
+ if (!arg_name.length())
+ {
+ arg_name = "arg" + toString <uint> (i);
+ }
+
+ body << arg_name << ";" << endl;
+ body << 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())
+ {
+ body << tab << tab << arg_object << " _" << arg_name << ";" << endl;
+ body << tab << tab << "_" << arg_name << " << " << arg_name << ";" << endl;
+
+ // store a object name to later generate header includes
+ include_vector.push_back(arg_object);
+ }
+ }
+
+ body << 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");
+ Xml::Nodes annotations = arg["annotation"];
+ Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
+ string arg_object;
+
+ if (!annotations_object.empty())
+ {
+ arg_object = annotations_object.front()->get("value");
+ }
+
+ if (!arg_name.length())
+ {
+ arg_name = "arg" + toString <uint> (j);
+ }
+
+ if (arg_object.length())
+ {
+ body << "_" << arg_name;
+ }
+ else
+ {
+ body << arg_name;
+ }
+
+ if (ai + 1 != args.end())
+ body << ", ";
+ }
+
+ body << ");" << endl;
+
+ body << tab << "}" << endl;
+ }
+
+ body << "};" << endl
+ << endl;
+
+ for (unsigned int i = 0; i < nspaces; ++i)
+ {
+ body << "} ";
+ }
+ body << endl;
+ }
+
+ body << "#endif //" << cond_comp << endl;
+
+ // remove all duplicates in the header include vector
+ vector<string>::const_iterator vec_end_it = unique(include_vector.begin(), include_vector.end());
+
+ for (vector<string>::const_iterator vec_it = include_vector.begin();
+ vec_it != vec_end_it;
+ ++vec_it)
+ {
+ const string &include = *vec_it;
+
+ head << "#include " << "\"" << include << ".h" << "\"" << endl;
+ }
+ head << endl;
+
+ ofstream file(filename);
+ if (file.bad())
+ {
+ cerr << "unable to write file " << filename << endl;
+ exit(-1);
+ }
+
+ file << head.str();
+ file << body.str();
+
+ file.close();
}
diff --git a/tools/generator_utils.cpp b/tools/generator_utils.cpp
index 0e9ed24..2ccf313 100644
--- a/tools/generator_utils.cpp
+++ b/tools/generator_utils.cpp
@@ -42,136 +42,140 @@ const char *dbus_includes = "\n\
#include <cassert>\n\
";
-void underscorize(string &str)
-{
- for (unsigned int i = 0; i < str.length(); ++i)
- {
- if (!isalpha(str[i]) && !isdigit(str[i])) str[i] = '_';
- }
-}
-
-string stub_name(string name)
-{
- underscorize(name);
-
- return "_" + name + "_stub";
-}
-
-const char *atomic_type_to_string(char t)
-{
- static struct { char type; const char *name; } atos[] =
- {
- { 'y', "uint8_t" },
- { 'b', "bool" },
- { 'n', "int16_t" },
- { 'q', "uint16_t" },
- { 'i', "int32_t" },
- { 'u', "uint32_t" },
- { 'x', "int64_t" },
- { 't', "uint64_t" },
- { 'd', "double" },
- { 's', "std::string" },
- { 'o', "::DBus::Path" },
- { 'g', "::DBus::Signature" },
- { 'v', "::DBus::Variant" },
- { '\0', "" }
- };
- int i;
-
- for (i = 0; atos[i].type; ++i)
- {
- if (atos[i].type == t) break;
- }
- return atos[i].name;
-}
-
-static void _parse_signature(const string &signature, string &type, unsigned int &i, bool only_once = false)
-{
- /*cout << "signature: " << signature << endl;
- cout << "type: " << type << endl;
- cout << "i: " << i << ", signature[i]: " << signature[i] << endl;*/
-
- for (; i < signature.length(); ++i)
- {
- switch (signature[i])
- {
- case 'a':
- {
- switch (signature[++i])
- {
- case '{':
- {
- type += "std::map< ";
- ++i;
- _parse_signature(signature, type, i);
- type += " >";
-
- break;
- }
- case '(':
- {
- type += "std::vector< ::DBus::Struct< ";
- ++i;
- _parse_signature(signature, type, i);
- type += " > >";
-
- break;
- }
- default:
- {
- type += "std::vector< ";
- _parse_signature(signature, type, i, true);
-
- type += " >";
-
- break;
- }
- }
- break;
- }
- case '(':
- {
- type += "::DBus::Struct< ";
- ++i;
-
- _parse_signature(signature, type, i);
-
- type += " >";
- break;
- }
- case ')':
- case '}':
- {
- return;
- }
- default:
- {
- const char *atom = atomic_type_to_string(signature[i]);
- if (!atom)
- {
- cerr << "invalid signature" << endl;
- exit(-1);
- }
- type += atom;
-
- break;
- }
- }
-
- if (only_once)
- return;
-
- if (i+1 < signature.length() && signature[i+1] != ')' && signature[i+1] != '}')
- {
- type += ", ";
- }
- }
-}
-
-string signature_to_type(const string &signature)
-{
- string type;
- unsigned int i = 0;
- _parse_signature(signature, type, i);
- return type;
-}
+ void underscorize(string &str)
+ {
+ for (unsigned int i = 0; i < str.length(); ++i)
+ {
+ if (!isalpha(str[i]) && !isdigit(str[i])) str[i] = '_';
+ }
+ }
+
+ string stub_name(string name)
+ {
+ underscorize(name);
+
+ return "_" + name + "_stub";
+ }
+
+ const char *atomic_type_to_string(char t)
+ {
+ static struct
+ {
+ char type;
+ const char *name;
+ } atos[] =
+ {
+ { 'y', "uint8_t" },
+ { 'b', "bool" },
+ { 'n', "int16_t" },
+ { 'q', "uint16_t" },
+ { 'i', "int32_t" },
+ { 'u', "uint32_t" },
+ { 'x', "int64_t" },
+ { 't', "uint64_t" },
+ { 'd', "double" },
+ { 's', "std::string" },
+ { 'o', "::DBus::Path" },
+ { 'g', "::DBus::Signature" },
+ { 'v', "::DBus::Variant" },
+ { '\0', "" }
+ };
+ int i;
+
+ for (i = 0; atos[i].type; ++i)
+ {
+ if (atos[i].type == t) break;
+ }
+ return atos[i].name;
+ }
+
+ static void _parse_signature(const string &signature, string &type, unsigned int &i, bool only_once = false)
+ {
+ /*cout << "signature: " << signature << endl;
+ cout << "type: " << type << endl;
+ cout << "i: " << i << ", signature[i]: " << signature[i] << endl;*/
+
+ for (; i < signature.length(); ++i)
+ {
+ switch (signature[i])
+ {
+ case 'a':
+ {
+ switch (signature[++i])
+ {
+ case '{':
+ {
+ type += "std::map< ";
+ ++i;
+ _parse_signature(signature, type, i);
+ type += " >";
+
+ break;
+ }
+ case '(':
+ {
+ type += "std::vector< ::DBus::Struct< ";
+ ++i;
+ _parse_signature(signature, type, i);
+ type += " > >";
+
+ break;
+ }
+ default:
+ {
+ type += "std::vector< ";
+ _parse_signature(signature, type, i, true);
+
+ type += " >";
+
+ break;
+ }
+ }
+ break;
+ }
+ case '(':
+ {
+ type += "::DBus::Struct< ";
+ ++i;
+
+ _parse_signature(signature, type, i);
+
+ type += " >";
+ break;
+ }
+ case ')':
+ case '}':
+ {
+ return;
+ }
+ default:
+ {
+ const char *atom = atomic_type_to_string(signature[i]);
+ if (!atom)
+ {
+ cerr << "invalid signature" << endl;
+ exit(-1);
+ }
+ type += atom;
+
+ break;
+ }
+ }
+
+ if (only_once)
+ return;
+
+ if (i + 1 < signature.length() && signature[i + 1] != ')' && signature[i + 1] != '}')
+ {
+ type += ", ";
+ }
+ }
+ }
+
+ string signature_to_type(const string &signature)
+ {
+ string type;
+ unsigned int i = 0;
+ _parse_signature(signature, type, i);
+ return type;
+ }
diff --git a/tools/generator_utils.h b/tools/generator_utils.h
index ea754df..276d228 100644
--- a/tools/generator_utils.h
+++ b/tools/generator_utils.h
@@ -35,7 +35,7 @@ void underscorize(std::string &str);
/// create std::string from any number
template <typename T>
-std::string toString (const T &thing, int w = 0, int p = 0)
+std::string toString(const T &thing, int w = 0, int p = 0)
{
std::ostringstream os;
os << std::setw(w) << std::setprecision(p) << thing;
diff --git a/tools/introspect.cpp b/tools/introspect.cpp
index 8ce9f3a..a994ae1 100644
--- a/tools/introspect.cpp
+++ b/tools/introspect.cpp
@@ -34,46 +34,46 @@ static char *service;
void niam(int sig)
{
- DBus::Connection conn = systembus ? DBus::Connection::SystemBus() : DBus::Connection::SessionBus();
+ DBus::Connection conn = systembus ? DBus::Connection::SystemBus() : DBus::Connection::SessionBus();
- IntrospectedObject io(conn, path, service);
+ IntrospectedObject io(conn, path, service);
- std::cout << io.Introspect();
+ std::cout << io.Introspect();
- dispatcher.leave();
+ dispatcher.leave();
}
-int main(int argc, char ** argv)
+int main(int argc, char **argv)
{
- signal(SIGTERM, niam);
- signal(SIGINT, niam);
- signal(SIGALRM, niam);
+ signal(SIGTERM, niam);
+ signal(SIGINT, niam);
+ signal(SIGALRM, niam);
- if (argc == 1)
- {
- std::cerr << std::endl << "Usage: " << argv[0] << " [--system] <object_path> [<destination>]" << std::endl << std::endl;
- }
- else
- {
- if (strcmp(argv[1], "--system"))
- {
- systembus = false;
- path = argv[1];
- service = argc > 2 ? argv[2] : 0;
- }
- else
- {
- systembus = true;
- path = argv[2];
- service = argc > 3 ? argv[3] : 0;
- }
+ if (argc == 1)
+ {
+ std::cerr << std::endl << "Usage: " << argv[0] << " [--system] <object_path> [<destination>]" << std::endl << std::endl;
+ }
+ else
+ {
+ if (strcmp(argv[1], "--system"))
+ {
+ systembus = false;
+ path = argv[1];
+ service = argc > 2 ? argv[2] : 0;
+ }
+ else
+ {
+ systembus = true;
+ path = argv[2];
+ service = argc > 3 ? argv[3] : 0;
+ }
- DBus::default_dispatcher = &dispatcher;
+ DBus::default_dispatcher = &dispatcher;
- alarm(1);
+ alarm(1);
- dispatcher.enter();
- }
+ dispatcher.enter();
+ }
- return 0;
+ return 0;
}
diff --git a/tools/introspect.h b/tools/introspect.h
index 1c6e326..ee7b1c5 100644
--- a/tools/introspect.h
+++ b/tools/introspect.h
@@ -36,9 +36,9 @@ class IntrospectedObject : public DBus::IntrospectableProxy, public DBus::Object
{
public:
- IntrospectedObject(DBus::Connection &conn, const char *path, const char *service)
- : DBus::ObjectProxy(conn, path, service)
- {}
+ IntrospectedObject(DBus::Connection &conn, const char *path, const char *service)
+ : DBus::ObjectProxy(conn, path, service)
+ {}
};
#endif//__DBUSXX_TOOLS_INTROSPECT_H
diff --git a/tools/xml.cpp b/tools/xml.cpp
index c363781..d3cc3ab 100644
--- a/tools/xml.cpp
+++ b/tools/xml.cpp
@@ -28,16 +28,16 @@
std::istream &operator >> (std::istream &in, DBus::Xml::Document &doc)
{
- std::stringbuf xmlbuf;
- in.get(xmlbuf, '\0');
- doc.from_xml(xmlbuf.str());
+ std::stringbuf xmlbuf;
+ in.get(xmlbuf, '\0');
+ doc.from_xml(xmlbuf.str());
- return in;
+ return in;
}
std::ostream &operator << (std::ostream &out, const DBus::Xml::Document &doc)
{
- return out << doc.to_xml();
+ return out << doc.to_xml();
}
using namespace DBus;
@@ -45,209 +45,209 @@ using namespace DBus::Xml;
Error::Error(const char *error, int line, int column)
{
- std::ostringstream estream;
+ std::ostringstream estream;
- estream << "line " << line << ", column " << column << ": " << error;
+ estream << "line " << line << ", column " << column << ": " << error;
- _error = estream.str();
+ _error = estream.str();
}
-Node::Node(const char *n, const char ** a)
-: name(n)
+Node::Node(const char *n, const char **a)
+ : name(n)
{
- if (a)
- for (int i = 0; a[i]; i += 2)
- {
- _attrs[a[i]] = a[i+1];
+ if (a)
+ for (int i = 0; a[i]; i += 2)
+ {
+ _attrs[a[i]] = a[i + 1];
- //debug_log("xml:\t%s = %s", a[i], a[i+1]);
- }
+ //debug_log("xml:\t%s = %s", a[i], a[i+1]);
+ }
}
Nodes Nodes::operator[](const std::string &key)
{
- Nodes result;
+ Nodes result;
- for (iterator i = begin(); i != end(); ++i)
- {
- Nodes part = (**i)[key];
+ for (iterator i = begin(); i != end(); ++i)
+ {
+ Nodes part = (**i)[key];
- result.insert(result.end(), part.begin(), part.end());
- }
- return result;
+ result.insert(result.end(), part.begin(), part.end());
+ }
+ return result;
}
Nodes Nodes::select(const std::string &attr, const std::string &value)
{
- Nodes result;
-
- for (iterator i = begin(); i != end(); ++i)
- {
- if ((*i)->get(attr) == value)
- result.insert(result.end(), *i);
- }
- return result;
+ Nodes result;
+
+ for (iterator i = begin(); i != end(); ++i)
+ {
+ if ((*i)->get(attr) == value)
+ result.insert(result.end(), *i);
+ }
+ return result;
}
Nodes Node::operator[](const std::string &key)
{
- Nodes result;
+ Nodes result;
- if (key.length() == 0) return result;
+ if (key.length() == 0) return result;
- for (Children::iterator i = children.begin(); i != children.end(); ++i)
- {
- if (i->name == key)
- result.push_back(&(*i));
- }
- return result;
+ for (Children::iterator i = children.begin(); i != children.end(); ++i)
+ {
+ if (i->name == key)
+ result.push_back(&(*i));
+ }
+ return result;
}
std::string Node::get(const std::string &attribute)
{
- if (_attrs.find(attribute) != _attrs.end())
- return _attrs[attribute];
- else
- return "";
+ if (_attrs.find(attribute) != _attrs.end())
+ return _attrs[attribute];
+ else
+ return "";
}
void Node::set(const std::string &attribute, std::string value)
{
- if (value.length())
- _attrs[attribute] = value;
- else
- _attrs.erase(value);
+ if (value.length())
+ _attrs[attribute] = value;
+ else
+ _attrs.erase(value);
}
std::string Node::to_xml() const
{
- std::string xml;
- int depth = 0;
+ std::string xml;
+ int depth = 0;
- _raw_xml(xml, depth);
+ _raw_xml(xml, depth);
- return xml;
+ return xml;
}
void Node::_raw_xml(std::string &xml, int &depth) const
{
- xml.append(depth *2, ' ');
- xml.append("<"+name);
-
- for (Attributes::const_iterator i = _attrs.begin(); i != _attrs.end(); ++i)
- {
- xml.append(" "+i->first+"=\""+i->second+"\"");
- }
-
- if (cdata.length() == 0 && children.size() == 0)
- {
- xml.append("/>\n");
- }
- else
- {
- xml.append(">");
-
- if (cdata.length())
- {
- xml.append(cdata);
- }
-
- if (children.size())
- {
- xml.append("\n");
- depth++;
-
- for (Children::const_iterator i = children.begin(); i != children.end(); ++i)
- {
- i->_raw_xml(xml, depth);
- }
-
- depth--;
- xml.append(depth *2, ' ');
- }
- xml.append("</"+name+">\n");
- }
+ xml.append(depth * 2, ' ');
+ xml.append("<" + name);
+
+ for (Attributes::const_iterator i = _attrs.begin(); i != _attrs.end(); ++i)
+ {
+ xml.append(" " + i->first + "=\"" + i->second + "\"");
+ }
+
+ if (cdata.length() == 0 && children.size() == 0)
+ {
+ xml.append("/>\n");
+ }
+ else
+ {
+ xml.append(">");
+
+ if (cdata.length())
+ {
+ xml.append(cdata);
+ }
+
+ if (children.size())
+ {
+ xml.append("\n");
+ depth++;
+
+ for (Children::const_iterator i = children.begin(); i != children.end(); ++i)
+ {
+ i->_raw_xml(xml, depth);
+ }
+
+ depth--;
+ xml.append(depth * 2, ' ');
+ }
+ xml.append("</" + name + ">\n");
+ }
}
Document::Document()
-: root(0), _depth(0)
+ : root(0), _depth(0)
{
}
-
+
Document::Document(const std::string &xml)
-: root(0), _depth(0)
+ : root(0), _depth(0)
{
- from_xml(xml);
+ from_xml(xml);
}
Document::~Document()
{
- delete root;
+ delete root;
}
struct Document::Expat
{
- static void start_doctype_decl_handler(
- void *data, const XML_Char *name, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset
- );
- static void end_doctype_decl_handler(void *data);
- static void start_element_handler(void *data, const XML_Char *name, const XML_Char **atts);
- static void character_data_handler(void *data, const XML_Char *chars, int len);
- static void end_element_handler(void *data, const XML_Char *name);
+ static void start_doctype_decl_handler(
+ void *data, const XML_Char *name, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset
+ );
+ static void end_doctype_decl_handler(void *data);
+ static void start_element_handler(void *data, const XML_Char *name, const XML_Char **atts);
+ static void character_data_handler(void *data, const XML_Char *chars, int len);
+ static void end_element_handler(void *data, const XML_Char *name);
};
void Document::from_xml(const std::string &xml)
{
- _depth = 0;
- delete root;
- root = 0;
-
- XML_Parser parser = XML_ParserCreate("UTF-8");
-
- XML_SetUserData(parser, this);
-
- XML_SetDoctypeDeclHandler(
- parser,
- Document::Expat::start_doctype_decl_handler,
- Document::Expat::end_doctype_decl_handler
- );
-
- XML_SetElementHandler(
- parser,
- Document::Expat::start_element_handler,
- Document::Expat::end_element_handler
- );
-
- XML_SetCharacterDataHandler(
- parser,
- Document::Expat::character_data_handler
- );
-
- XML_Status status = XML_Parse(parser, xml.c_str(), xml.length(), true);
-
- if (status == XML_STATUS_ERROR)
- {
- const char *error = XML_ErrorString(XML_GetErrorCode(parser));
- int line = XML_GetCurrentLineNumber(parser);
- int column = XML_GetCurrentColumnNumber(parser);
-
- XML_ParserFree(parser);
-
- throw Error(error, line, column);
- }
- else
- {
- XML_ParserFree(parser);
- }
+ _depth = 0;
+ delete root;
+ root = 0;
+
+ XML_Parser parser = XML_ParserCreate("UTF-8");
+
+ XML_SetUserData(parser, this);
+
+ XML_SetDoctypeDeclHandler(
+ parser,
+ Document::Expat::start_doctype_decl_handler,
+ Document::Expat::end_doctype_decl_handler
+ );
+
+ XML_SetElementHandler(
+ parser,
+ Document::Expat::start_element_handler,
+ Document::Expat::end_element_handler
+ );
+
+ XML_SetCharacterDataHandler(
+ parser,
+ Document::Expat::character_data_handler
+ );
+
+ XML_Status status = XML_Parse(parser, xml.c_str(), xml.length(), true);
+
+ if (status == XML_STATUS_ERROR)
+ {
+ const char *error = XML_ErrorString(XML_GetErrorCode(parser));
+ int line = XML_GetCurrentLineNumber(parser);
+ int column = XML_GetCurrentColumnNumber(parser);
+
+ XML_ParserFree(parser);
+
+ throw Error(error, line, column);
+ }
+ else
+ {
+ XML_ParserFree(parser);
+ }
}
std::string Document::to_xml() const
{
- return root->to_xml();
+ return root->to_xml();
}
void Document::Expat::start_doctype_decl_handler(
- void *data, const XML_Char *name, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset
+ void *data, const XML_Char *name, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset
)
{
}
@@ -258,56 +258,56 @@ void Document::Expat::end_doctype_decl_handler(void *data)
void Document::Expat::start_element_handler(void *data, const XML_Char *name, const XML_Char **atts)
{
- Document *doc = (Document *)data;
-
- //debug_log("xml:%d -> %s", doc->_depth, name);
-
- if (!doc->root)
- {
- doc->root = new Node(name, atts);
- }
- else
- {
- Node::Children *cld = &(doc->root->children);
-
- for (int i = 1; i < doc->_depth; ++i)
- {
- cld = &(cld->back().children);
- }
- cld->push_back(Node(name, atts));
-
- //std::cerr << doc->to_xml() << std::endl;
- }
- doc->_depth++;
+ Document *doc = (Document *)data;
+
+ //debug_log("xml:%d -> %s", doc->_depth, name);
+
+ if (!doc->root)
+ {
+ doc->root = new Node(name, atts);
+ }
+ else
+ {
+ Node::Children *cld = &(doc->root->children);
+
+ for (int i = 1; i < doc->_depth; ++i)
+ {
+ cld = &(cld->back().children);
+ }
+ cld->push_back(Node(name, atts));
+
+ //std::cerr << doc->to_xml() << std::endl;
+ }
+ doc->_depth++;
}
void Document::Expat::character_data_handler(void *data, const XML_Char *chars, int len)
{
- Document *doc = (Document *)data;
+ Document *doc = (Document *)data;
- Node *nod = doc->root;
+ Node *nod = doc->root;
- for (int i = 1; i < doc->_depth; ++i)
- {
- nod = &(nod->children.back());
- }
- int x, y;
+ for (int i = 1; i < doc->_depth; ++i)
+ {
+ nod = &(nod->children.back());
+ }
+ int x, y;
- x = 0;
- y = len-1;
+ x = 0;
+ y = len - 1;
- while (isspace(chars[y]) && y > 0) --y;
- while (isspace(chars[x]) && x < y) ++x;
+ while (isspace(chars[y]) && y > 0) --y;
+ while (isspace(chars[x]) && x < y) ++x;
- nod->cdata = std::string(chars, x, y+1);
+ nod->cdata = std::string(chars, x, y + 1);
}
void Document::Expat::end_element_handler(void *data, const XML_Char *name)
{
- Document *doc = (Document *)data;
+ Document *doc = (Document *)data;
- //debug_log("xml:%d <- %s", doc->_depth, name);
+ //debug_log("xml:%d <- %s", doc->_depth, name);
- doc->_depth--;
+ doc->_depth--;
}
diff --git a/tools/xml.h b/tools/xml.h
index 6a8e69c..736a0dd 100644
--- a/tools/xml.h
+++ b/tools/xml.h
@@ -36,27 +36,29 @@
#include <iostream>
#include <sstream>
-namespace DBus {
+namespace DBus
+{
-namespace Xml {
+namespace Xml
+{
class Error : public std::exception
{
public:
- Error(const char *error, int line, int column);
+ Error(const char *error, int line, int column);
- ~Error() throw()
- {}
+ ~Error() throw()
+ {}
- const char *what() const throw()
- {
- return _error.c_str();
- }
+ const char *what() const throw()
+ {
+ return _error.c_str();
+ }
private:
- std::string _error;
+ std::string _error;
};
class Node;
@@ -65,71 +67,71 @@ class Nodes : public std::vector<Node *>
{
public:
- Nodes operator[](const std::string &key);
+ Nodes operator[](const std::string &key);
- Nodes select(const std::string &attr, const std::string &value);
+ Nodes select(const std::string &attr, const std::string &value);
};
class Node
{
public:
- typedef std::map<std::string, std::string> Attributes;
+ typedef std::map<std::string, std::string> Attributes;
- typedef std::vector<Node> Children;
+ typedef std::vector<Node> Children;
- std::string name;
- std::string cdata;
- Children children;
+ std::string name;
+ std::string cdata;
+ Children children;
- Node(std::string &n, Attributes &a)
- : name(n), _attrs(a)
- {}
+ Node(std::string &n, Attributes &a)
+ : name(n), _attrs(a)
+ {}
- Node(const char *n, const char ** a = NULL);
+ Node(const char *n, const char **a = NULL);
- Nodes operator[](const std::string &key);
+ Nodes operator[](const std::string &key);
- std::string get(const std::string &attribute);
+ std::string get(const std::string &attribute);
- void set(const std::string &attribute, std::string value);
+ void set(const std::string &attribute, std::string value);
- std::string to_xml() const;
+ std::string to_xml() const;
- Node &add(Node child)
- {
- children.push_back(child);
- return children.back();
- }
+ Node &add(Node child)
+ {
+ children.push_back(child);
+ return children.back();
+ }
private:
- void _raw_xml(std::string &xml, int &depth) const;
+ void _raw_xml(std::string &xml, int &depth) const;
- Attributes _attrs;
+ Attributes _attrs;
};
class Document
{
public:
- struct Expat;
+ struct Expat;
- Node *root;
+ Node *root;
- Document();
+ Document();
- Document(const std::string &xml);
+ Document(const std::string &xml);
- ~Document();
+ ~Document();
- void from_xml(const std::string &xml);
+ void from_xml(const std::string &xml);
- std::string to_xml() const;
+ std::string to_xml() const;
private:
- int _depth;
+ int _depth;
};
} /* namespace Xml */
diff --git a/tools/xml2cpp.cpp b/tools/xml2cpp.cpp
index 7bfc3ea..ff031f8 100644
--- a/tools/xml2cpp.cpp
+++ b/tools/xml2cpp.cpp
@@ -40,9 +40,9 @@ using namespace DBus;
void usage(const char *argv0)
{
- cerr << endl << "Usage: " << argv0 << " <xmlfile> [ --proxy=<outfile.h> ] [ --adaptor=<outfile.h> ]"
- << endl << endl;
- exit(-1);
+ cerr << endl << "Usage: " << argv0 << " <xmlfile> [ --proxy=<outfile.h> ] [ --adaptor=<outfile.h> ]"
+ << endl << endl;
+ exit(-1);
}
/*int char_to_atomic_type(char t)
@@ -61,68 +61,67 @@ void usage(const char *argv0)
}*/
-int main(int argc, char ** argv)
+int main(int argc, char **argv)
{
- if (argc < 2)
- {
- usage(argv[0]);
- }
-
- bool proxy_mode, adaptor_mode;
- char *proxy, *adaptor;
-
- proxy_mode = false;
- proxy = 0;
-
- adaptor_mode = false;
- adaptor = 0;
-
- for (int a = 1; a < argc; ++a)
- {
- if (!strncmp(argv[a], "--proxy=", 8))
- {
- proxy_mode = true;
- proxy = argv[a] +8;
- }
- else
- if (!strncmp(argv[a], "--adaptor=", 10))
- {
- adaptor_mode = true;
- adaptor = argv[a] +10;
- }
- }
-
- if (!proxy_mode && !adaptor_mode) usage(argv[0]);
-
- ifstream xmlfile(argv[1]);
-
- if (xmlfile.bad())
- {
- cerr << "unable to open file " << argv[1] << endl;
- return -1;
- }
-
- Xml::Document doc;
-
- try
- {
- xmlfile >> doc;
- //cout << doc.to_xml();
- }
- catch(Xml::Error &e)
- {
- cerr << "error parsing " << argv[1] << ": " << e.what() << endl;
- return -1;
- }
-
- if (!doc.root)
- {
- cerr << "empty document" << endl;
- return -1;
- }
-
- if (proxy_mode) generate_proxy(doc, proxy);
- if (adaptor_mode) generate_adaptor(doc, adaptor);
-
- return 0;
+ if (argc < 2)
+ {
+ usage(argv[0]);
+ }
+
+ bool proxy_mode, adaptor_mode;
+ char *proxy, *adaptor;
+
+ proxy_mode = false;
+ proxy = 0;
+
+ adaptor_mode = false;
+ adaptor = 0;
+
+ for (int a = 1; a < argc; ++a)
+ {
+ if (!strncmp(argv[a], "--proxy=", 8))
+ {
+ proxy_mode = true;
+ proxy = argv[a] + 8;
+ }
+ else if (!strncmp(argv[a], "--adaptor=", 10))
+ {
+ adaptor_mode = true;
+ adaptor = argv[a] + 10;
+ }
+ }
+
+ if (!proxy_mode && !adaptor_mode) usage(argv[0]);
+
+ ifstream xmlfile(argv[1]);
+
+ if (xmlfile.bad())
+ {
+ cerr << "unable to open file " << argv[1] << endl;
+ return -1;
+ }
+
+ Xml::Document doc;
+
+ try
+ {
+ xmlfile >> doc;
+ //cout << doc.to_xml();
+ }
+ catch (Xml::Error &e)
+ {
+ cerr << "error parsing " << argv[1] << ": " << e.what() << endl;
+ return -1;
+ }
+
+ if (!doc.root)
+ {
+ cerr << "empty document" << endl;
+ return -1;
+ }
+
+ if (proxy_mode) generate_proxy(doc, proxy);
+ if (adaptor_mode) generate_adaptor(doc, adaptor);
+
+ return 0;
}