From 5e527213a2430bb3018e5eebd909aef294edf9b5 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 18 Dec 2020 18:48:46 +0300 Subject: Switch to build2 --- xsd-examples/cxx/tree/custom/double/.gitignore | 2 + xsd-examples/cxx/tree/custom/double/README | 62 ++++++++++++++ xsd-examples/cxx/tree/custom/double/buildfile | 46 +++++++++++ .../cxx/tree/custom/double/double-custom.cxx | 96 ++++++++++++++++++++++ .../cxx/tree/custom/double/double-custom.hxx | 67 +++++++++++++++ xsd-examples/cxx/tree/custom/double/driver.cxx | 31 +++++++ xsd-examples/cxx/tree/custom/double/order.xsd | 25 ++++++ 7 files changed, 329 insertions(+) create mode 100644 xsd-examples/cxx/tree/custom/double/.gitignore create mode 100644 xsd-examples/cxx/tree/custom/double/README create mode 100644 xsd-examples/cxx/tree/custom/double/buildfile create mode 100644 xsd-examples/cxx/tree/custom/double/double-custom.cxx create mode 100644 xsd-examples/cxx/tree/custom/double/double-custom.hxx create mode 100644 xsd-examples/cxx/tree/custom/double/driver.cxx create mode 100644 xsd-examples/cxx/tree/custom/double/order.xsd (limited to 'xsd-examples/cxx/tree/custom/double') diff --git a/xsd-examples/cxx/tree/custom/double/.gitignore b/xsd-examples/cxx/tree/custom/double/.gitignore new file mode 100644 index 0000000..5cc7f75 --- /dev/null +++ b/xsd-examples/cxx/tree/custom/double/.gitignore @@ -0,0 +1,2 @@ +order.?xx +xml-schema.hxx diff --git a/xsd-examples/cxx/tree/custom/double/README b/xsd-examples/cxx/tree/custom/double/README new file mode 100644 index 0000000..15348d2 --- /dev/null +++ b/xsd-examples/cxx/tree/custom/double/README @@ -0,0 +1,62 @@ +This example shows how to customize parsing and serialization code for the +xsd:double XML Schema built-in type using the type customization mechanism +provided by the C++/Tree Mapping. For more information on type customization +see the C++/Tree Mapping Customization Guide, particularly sections 1 and 4: + +http://wiki.codesynthesis.com/Tree/Customization_guide + +In this example our schema uses xsd:double to represent a price. There are +two potential problems with this choice of a price type. First, xsd:double +can be serialized in the scientific notation which would be an unusual way +of representing a price. Second, we would like to limit the number of +fraction digits in our prices to 2. Furthermore, we would like to always +have two fraction digits, even if one or both of them are zeros, for +example: 12.99, 12.90, 12.00. + +In case we can modify the schema, a better approach would be to define the +price type as a restriction of the xsd:decimal type (always fixed notation) +and specify the fractionDigits facet to limit the number of fraction digits +to 2. However, there is no way in XML Schema to specify that there should +always be exactly 2 fraction digits. Therefore, it may still be desirable +to customize this price type to get the required serialization behavior. + +Finally, it is worth noting that the behavior achieved in this example via +type customization can also be achieved by compiling your code with the +following macros defined: + +XSD_TREE_DOUBLE_FIXED +XSD_TREE_DOUBLE_PRECISION 2 + +However, the type customization approach while requiring more work is +cleaner since it does not rely on global macro definitions. + +This example consists of the following files: + +order.xsd + XML Schema definition for a simple order vocabulary. + +double-custom.hxx +double-custom.cxx + Custom parsing and serialization code for the xsd:double types. The + double-custom.hxx file is included at the end of the xml-schema.hxx + file described below. + +xml-schema.hxx + C++ types for XML Schema built-in types. This header file is generated + by the XSD compiler using the --generate-xml-schema option. The + --custom-type option is used to customize the xsd:double type. The + --hxx-epilogue option is used to include the double-custom.hxx file + at the end of this file. + +order.hxx +order.cxx + C++ types generated from order.xsd. The --extern-xml-schema option + is used to include xml-schema.hxx into order.hxx. + +driver.cxx + Test driver for the example. It creates a sample order and then + writes it to XML to test the custom xsd:double serialization code. + +To run the example simply execute: + +$ ./driver diff --git a/xsd-examples/cxx/tree/custom/double/buildfile b/xsd-examples/cxx/tree/custom/double/buildfile new file mode 100644 index 0000000..258191a --- /dev/null +++ b/xsd-examples/cxx/tree/custom/double/buildfile @@ -0,0 +1,46 @@ +# file : cxx/tree/custom/double/buildfile +# license : not copyrighted - public domain + +import libs = libxsd%lib{xsd} +import libs += libxerces-c%lib{xerces-c} + +./: exe{driver} doc{README} + +exe{driver}: {hxx cxx}{* -order -xml-schema} \ + {hxx ixx cxx}{order} \ + {hxx }{xml-schema} \ + $libs + +<{hxx ixx cxx}{order}>: xsd{order} $xsd +{{ + diag xsd ($<[0]) # @@ TMP + + $xsd cxx-tree --std c++11 \ + --generate-inline \ + --generate-serialization \ + --extern-xml-schema xml-schema.xsd \ + --output-dir $out_base \ + $path($<[0]) +}} + +hxx{xml-schema}: $xsd +{{ + diag xsd gen ($>[0]) + + # Note that the specified xml-schema.xsd doesn't exist and is only used to + # deduce the generated header name. + # + $xsd cxx-tree --std c++11 \ + --generate-xml-schema \ + --generate-serialization \ + --custom-type double=double \ + --hxx-epilogue '#include "double-custom.hxx"' \ + --output-dir $out_base \ + xml-schema.xsd +}} + +cxx.poptions =+ "-I$out_base" "-I$src_base" + +# Define XSD_CXX11 since we include libxsd headers directly. +# +cxx.poptions += -DXSD_CXX11 diff --git a/xsd-examples/cxx/tree/custom/double/double-custom.cxx b/xsd-examples/cxx/tree/custom/double/double-custom.cxx new file mode 100644 index 0000000..bfec6e0 --- /dev/null +++ b/xsd-examples/cxx/tree/custom/double/double-custom.cxx @@ -0,0 +1,96 @@ +// file : cxx/tree/custom/double/double-custom.cxx +// copyright : not copyrighted - public domain + +// Include xml-schema.hxx instead of double-custom.hxx here. +// +#include "xml-schema.hxx" + +#include +#include +#include + +#include +#include + +using namespace std; + +// Parsing. +// +namespace xsd +{ + namespace cxx + { + namespace tree + { + double traits:: + create (const std::string& s, + const xercesc::DOMElement*, + flags, + type*) + { + // This type cannot have whitespaces in its values. As result we + // don't need to waste time collapsing whitespaces. All we need to + // do is trim the string representation which can be done without + // copying. + // + ro_string tmp (s); + trim (tmp); + + zc_istream is (tmp); + is.imbue (locale::classic ()); + + double t; + is >> t; + + return t; + } + } + } +} + +// Serialization. +// +namespace XERCES_CPP_NAMESPACE +{ + void + operator<< (xercesc::DOMElement& e, const xml_schema::as_double& d) + { + ostringstream os; + os.imbue (locale::classic ()); + + os.precision (2); + os << fixed << d.x; + + e << os.str (); + } + + void + operator<< (xercesc::DOMAttr& a, const xml_schema::as_double& d) + { + ostringstream os; + os.imbue (locale::classic ()); + + os.precision (2); + os << fixed << d.x; + + a << os.str (); + } +} + +namespace xsd +{ + namespace cxx + { + namespace tree + { + void + operator<< (xml_schema::list_stream& ls, + const xml_schema::as_double& d) + { + ls.os_.imbue (locale::classic ()); + ls.os_.precision (2); + ls.os_ << fixed << d.x; + } + } + } +} diff --git a/xsd-examples/cxx/tree/custom/double/double-custom.hxx b/xsd-examples/cxx/tree/custom/double/double-custom.hxx new file mode 100644 index 0000000..cb74442 --- /dev/null +++ b/xsd-examples/cxx/tree/custom/double/double-custom.hxx @@ -0,0 +1,67 @@ +// file : cxx/tree/custom/double/double-custom.hxx +// copyright : not copyrighted - public domain + +// Do not include this file directly, use xml-schema.hxx instead. This +// file is included into generated xml-schema.hxx so we do not need to +// guard against multiple inclusions. +// + +#include // xml::transcode +#include // text_content + +// Parsing. +// +namespace xsd +{ + namespace cxx + { + namespace tree + { + template<> + struct traits + { + static double + create (const xercesc::DOMElement& e, flags f, type* c) + { + return create (text_content (e), 0, f, c); + } + + static double + create (const xercesc::DOMAttr& a, flags f, type* c) + { + return create (xml::transcode (a.getValue ()), 0, f, c); + } + + static double + create (const std::string& s, + const xercesc::DOMElement*, + flags, + type*); + }; + } + } +} + +// Serialization. +// +namespace XERCES_CPP_NAMESPACE +{ + void + operator<< (xercesc::DOMElement& e, const xml_schema::as_double& d); + + void + operator<< (xercesc::DOMAttr& a, const xml_schema::as_double& d); +} + +namespace xsd +{ + namespace cxx + { + namespace tree + { + void + operator<< (xml_schema::list_stream& ls, + const xml_schema::as_double& d); + } + } +} diff --git a/xsd-examples/cxx/tree/custom/double/driver.cxx b/xsd-examples/cxx/tree/custom/double/driver.cxx new file mode 100644 index 0000000..e3f1800 --- /dev/null +++ b/xsd-examples/cxx/tree/custom/double/driver.cxx @@ -0,0 +1,31 @@ +// file : cxx/tree/custom/double/driver.cxx +// copyright : not copyrighted - public domain + +#include + +#include "order.hxx" + +using std::cerr; +using std::endl; + +int +main () +{ + try + { + // Order one Airbus A380. + // + order o; + o.item ().push_back (item ("Airbus A380", 317000000.90)); + + + // Serialize. + // + order_ (std::cout, o); + } + catch (const xml_schema::exception& e) + { + cerr << e << endl; + return 1; + } +} diff --git a/xsd-examples/cxx/tree/custom/double/order.xsd b/xsd-examples/cxx/tree/custom/double/order.xsd new file mode 100644 index 0000000..8066975 --- /dev/null +++ b/xsd-examples/cxx/tree/custom/double/order.xsd @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + -- cgit v1.1