summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cxml.cc68
-rw-r--r--src/cxml.h56
2 files changed, 98 insertions, 26 deletions
diff --git a/src/cxml.cc b/src/cxml.cc
index d3ec9e7..82e4bc3 100644
--- a/src/cxml.cc
+++ b/src/cxml.cc
@@ -300,3 +300,71 @@ cxml::Document::take_root_node ()
_root_name = _node->get_name ();
}
}
+
+static
+string
+make_local (string v)
+{
+ struct lconv* lc = localeconv ();
+ boost::algorithm::replace_all (v, ".", lc->decimal_point);
+ /* We hope it's ok not to add in thousands separators here */
+ return v;
+}
+
+template <typename P, typename Q>
+P
+locale_convert (Q x)
+{
+ /* We can't write a generic version of locale_convert; all required
+ versions must be specialised.
+ */
+ BOOST_STATIC_ASSERT (sizeof(Q) == 0);
+}
+
+template<>
+int
+locale_convert (string x)
+{
+ int y = 0;
+ sscanf (x.c_str(), "%d", &y);
+ return y;
+}
+
+template<>
+float
+locale_convert (string x)
+{
+ float y = 0;
+ sscanf (x.c_str(), "%f", &y);
+ return y;
+}
+
+template <>
+double
+locale_convert (string x)
+{
+ double y = 0;
+ sscanf (x.c_str(), "%lf", &y);
+ return y;
+}
+
+template <>
+int
+cxml::raw_convert (string v)
+{
+ return locale_convert<int> (make_local(v));
+}
+
+template <>
+float
+cxml::raw_convert (string v)
+{
+ return locale_convert<float> (make_local(v));
+}
+
+template <>
+double
+cxml::raw_convert (string v)
+{
+ return locale_convert<double> (make_local(v));
+}
diff --git a/src/cxml.h b/src/cxml.h
index d5b6261..bd9db00 100644
--- a/src/cxml.h
+++ b/src/cxml.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net>
This file is part of libcxml.
@@ -21,7 +21,6 @@
#ifndef LIBCXML_CXML_H
#define LIBCXML_CXML_H
-#include <locked_sstream.h>
#include <boost/shared_ptr.hpp>
#include <boost/optional.hpp>
#include <boost/filesystem.hpp>
@@ -66,6 +65,31 @@ private:
std::string _message;
};
+/** A sort-of version of boost::lexical_cast that does uses the "C"
+ * locale (i.e. no thousands separators and a . for the decimal separator).
+ */
+template <typename P, typename Q>
+P
+raw_convert (Q v)
+{
+ /* We can't write a generic version of raw_convert; all required
+ versions must be specialised.
+ */
+ BOOST_STATIC_ASSERT (sizeof(Q) == 0);
+}
+
+template <>
+int
+raw_convert (std::string v);
+
+template <>
+float
+raw_convert (std::string v);
+
+template <>
+double
+raw_convert (std::string v);
+
/** @brief A wrapper for a xmlpp::Node which simplifies parsing */
class Node
{
@@ -113,12 +137,7 @@ public:
{
std::string s = string_child (c);
boost::erase_all (s, " ");
- locked_stringstream t;
- t.imbue (std::locale::classic ());
- t << s;
- T n;
- t >> n;
- return n;
+ return raw_convert<T> (s);
}
template <class T>
@@ -131,12 +150,7 @@ public:
std::string t = s.get ();
boost::erase_all (t, " ");
- locked_stringstream u;
- u.imbue (std::locale::classic ());
- u << t;
- T n;
- u >> n;
- return n;
+ return raw_convert<T> (t);
}
/** This will mark a child as to be ignored when calling done() */
@@ -162,12 +176,7 @@ public:
{
std::string s = string_attribute (c);
boost::erase_all (s, " ");
- locked_stringstream t;
- t.imbue (std::locale::classic ());
- t << s;
- T n;
- t >> n;
- return n;
+ return raw_convert<T> (s);
}
template <class T>
@@ -180,12 +189,7 @@ public:
std::string t = s.get ();
boost::erase_all (t, " ");
- locked_stringstream u;
- u.imbue (std::locale::classic ());
- u << t;
- T n;
- u >> n;
- return n;
+ return raw_convert<T> (t);
}
/** @return The text content of this node (excluding comments or CDATA) */