From f0510d2f90467de8e8f260b47d79a9baaf9bef17 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 17 Sep 2009 07:15:29 +0200 Subject: Start tracking XSD with git --- libxsd/xsd/cxx/tree/serialization/decimal.hxx | 126 ++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 libxsd/xsd/cxx/tree/serialization/decimal.hxx (limited to 'libxsd/xsd/cxx/tree/serialization/decimal.hxx') diff --git a/libxsd/xsd/cxx/tree/serialization/decimal.hxx b/libxsd/xsd/cxx/tree/serialization/decimal.hxx new file mode 100644 index 0000000..3fa2297 --- /dev/null +++ b/libxsd/xsd/cxx/tree/serialization/decimal.hxx @@ -0,0 +1,126 @@ +// file : xsd/cxx/tree/serialization/decimal.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_TREE_SERIALIZATION_DECIMAL_HXX +#define XSD_CXX_TREE_SERIALIZATION_DECIMAL_HXX + +#include // std::numeric_limits +#include +#include + +namespace xsd +{ + namespace cxx + { + namespace tree + { + namespace bits + { + // The formula for the number of decimla digits required is given in: + // + // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf + // + template + std::basic_string + insert (const as_decimal& d) + { + std::basic_ostringstream os; + os.imbue (std::locale::classic ()); + std::streamsize prec; + + const facet* f = d.facets ? + facet::find (d.facets, facet::fraction_digits) : 0; + + if (f) + prec = static_cast (f->value); + else + { + // Precision. + // +#if defined (XSD_CXX_TREE_DECIMAL_PRECISION_MAX) + prec = 2 + std::numeric_limits::digits * 301/1000; +#elif defined (XSD_CXX_TREE_DECIMAL_PRECISION) + prec = XSD_CXX_TREE_DECIMAL_PRECISION; +#else + prec = std::numeric_limits::digits10; +#endif + } + + os.precision (prec); + os << std::fixed << d.x; + std::basic_string r (os.str ()); + const C* cr (r.c_str ()); + + // Remove the trailing zeros and the decimal point if necessary. + // + typename std::basic_string::size_type size (r.size ()), n (size); + + if (prec != 0) + { + for (; n > 0 && cr[n - 1] == '0'; --n)/*noop*/; + + if (n > 0 && cr[n - 1] == '.') + --n; + } + + // See if we have a restriction on total digits. + // + f = d.facets ? facet::find (d.facets, facet::total_digits) : 0; + + if (f && n > f->value) + { + // Point and sign do not count so figure out if we have them. + // + typename std::basic_string::size_type extra ( + cr[0] == '-' ? 1 : 0); + + if (r.find ('.') < n) + extra++; + + // Unless we have a point and the size difference is one, + // remove some digits. + // + if ((n - extra) > f->value) + n -= (n - extra - f->value); + + if (n > 0 && cr[n - 1] == '.') + --n; + } + + if (n != size) + r.resize (n); + + return r; + } + } + + template + inline void + operator<< (list_stream& ls, const as_decimal& d) + { + ls.os_ << bits::insert (d); + } + } + } +} + +namespace XERCES_CPP_NAMESPACE +{ + inline void + operator<< (xercesc::DOMElement& e, + const xsd::cxx::tree::as_decimal& d) + { + e << xsd::cxx::tree::bits::insert (d); + } + + inline void + operator<< (xercesc::DOMAttr& a, + const xsd::cxx::tree::as_decimal& d) + { + a << xsd::cxx::tree::bits::insert (d); + } +} + +#endif // XSD_CXX_TREE_SERIALIZATION_DECIMAL_HXX -- cgit v1.1