// file : cxx/tree/messaging/driver.cxx // copyright : not copyrighted - public domain #include // std::unique_ptr #include #include #include #include #include #include #include #include "dom-parse.hxx" #include "dom-serialize.hxx" #include "protocol.hxx" using namespace std; using namespace protocol; using namespace xercesc; int main (int argc, char* argv[]) { if (argc != 2) { cerr << "usage: " << argv[0] << " request.xml" << endl; return 1; } int r (0); // We need to initialize the Xerces-C++ runtime because we // are doing the XML-to-DOM parsing ourselves. // XMLPlatformUtils::Initialize (); try { ifstream ifs; ifs.exceptions (ifstream::badbit | ifstream::failbit); ifs.open (argv[1]); unique_ptr req, res; // Parse the XML request to a DOM document using the parse() // function from dom-parse.hxx. // { xml_schema::dom::unique_ptr doc ( parse (ifs, argv[1], true)); DOMElement& root (*doc->getDocumentElement ()); req = xml_schema::element_map::parse (root); } // We can test which request we've got either using RTTI or by // comparing the element names, as shown below. // if (balance* b = dynamic_cast (req.get ())) { account_t& a (b->value ()); cerr << "balance request for acc# " << a.account () << endl; res.reset (new success (balance_t (a.account (), 1000))); } else if (req->_name () == withdraw::name ()) { withdraw& w (static_cast (*req)); change_t& c (w.value ()); wcerr << "withdrawal request for acc# " << c.account () << ", " << "amount: " << c.amount () << endl; if (c.amount () > 1000) res.reset (new insufficient_funds (balance_t (c.account (), 1000))); else res.reset (new success (balance_t (c.account (), 1000 - c.amount ()))); } else if (req->_name () == deposit::name ()) { deposit& d (static_cast (*req)); change_t& c (d.value ()); wcerr << "deposit request for acc# " << c.account () << ", " << "amount: " << c.amount () << endl; res.reset (new success (balance_t (c.account (), 1000 + c.amount ()))); } // Serialize the response to a DOM document. // namespace xml = xsd::cxx::xml; const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull}; DOMImplementation* impl ( DOMImplementationRegistry::getDOMImplementation (ls_id)); const string& name (res->_name ()); const string& ns (res->_namespace ()); xml_schema::dom::unique_ptr doc ( impl->createDocument ( xml::string (ns).c_str (), xml::string ("p:" + name).c_str (), 0)); xml_schema::element_map::serialize (*doc->getDocumentElement (), *res); // Serialize the DOM document to XML using the serialize() function // from dom-serialize.hxx. // cout << "response:" << endl << endl; serialize (cout, *doc); } catch (const xml_schema::no_element_info& e) { // This exception indicates that we tried to parse or serialize // an unknown element. // cerr << "unknown request: " << e.element_namespace () << "#" << e.element_name () << endl; r = 1; } catch (const xml_schema::exception& e) { cerr << e << endl; r = 1; } catch (const std::ios_base::failure&) { cerr << argv[1] << ": unable to open or read failure" << endl; r = 1; } XMLPlatformUtils::Terminate (); return r; }