Skip to content

Commit

Permalink
Use stringstream instead of stod to work around locale issues. (#42)
Browse files Browse the repository at this point in the history
* Use stringstream instead of stod to work around locale issues.

Signed-off-by: Chris Lalancette <[email protected]>

* Use imbue to always use the "classic" locale.

Signed-off-by: Chris Lalancette <[email protected]>

* Make a strToDouble facility in the utils.h header.

This will be useful elsewhere (i.e. urdfdom).

Signed-off-by: Chris Lalancette <[email protected]>

* Add some additional includes.

Signed-off-by: Chris Lalancette <[email protected]>

* Add in an actual error message to the strToDouble throw.

Signed-off-by: Chris Lalancette <[email protected]>
  • Loading branch information
clalancette authored Feb 21, 2018
1 parent ed597eb commit e7e0972
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
8 changes: 2 additions & 6 deletions urdf_model/include/urdf_model/pose.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,10 @@ class Vector3
for (unsigned int i = 0; i < pieces.size(); ++i){
if (pieces[i] != ""){
try {
xyz.push_back(std::stod(pieces[i]));
}
catch (std::invalid_argument &/*e*/) {
xyz.push_back(strToDouble(pieces[i].c_str()));
} catch(std::runtime_error &) {
throw ParseError("Unable to parse component [" + pieces[i] + "] to a double (while parsing a vector value)");
}
catch (std::out_of_range &/*e*/) {
throw ParseError("Unable to parse component [" + pieces[i] + "] to a double, out of range (while parsing a vector value)");
}
}
}

Expand Down
25 changes: 25 additions & 0 deletions urdf_model/include/urdf_model/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
#ifndef URDF_INTERFACE_UTILS_H
#define URDF_INTERFACE_UTILS_H

#include <locale>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

Expand All @@ -62,6 +65,28 @@ void split_string(std::vector<std::string> &result,
}
}

// This is a locale-safe version of string-to-double, which is suprisingly
// difficult to do correctly. This function ensures that the C locale is used
// for parsing, as that matches up with what the XSD for double specifies.
// On success, the double is returned; on failure, a std::runtime_error is
// thrown.
static inline double strToDouble(const char *in)
{
std::stringstream ss;
ss.imbue(std::locale::classic());

ss << in;

double out;
ss >> out;

if (ss.fail() || !ss.eof()) {
throw std::runtime_error("Failed converting string to double");
}

return out;
}

}

#endif

0 comments on commit e7e0972

Please sign in to comment.