-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Decimal comma in Float32 in JSON #201
Comments
Hello @jerro1971 , Thanks for reporting this issue. We'll have to fix it. Regards, |
My 2c to that.
An easy - but not elegant - workaround would be to set the locale for numerics to en_US or similar if they are not json-compatible. So we could check in oatpp::base::environment::init() if the locale is compatible. If not, we could set a flag that it should be changed when formatting. But we need to reset the locale to the original! We don't want to screw around with the locales for the entire program! #include <locale>
// [...]
v_buff_size float32ToCharSequence(v_float32 value, p_char8 data, v_buff_size n) {
char* old_locale;
if(oatpp::base::environment::switchToJSONCompatibleLocale) {
old_locale = strdup(setlocale(LC_NUMERIC, nullptr);
setlocale(LC_NUMERIC, "en_US"); // or plain "C" locale for portability;
}
auto rc = snprintf((char*)data, n, "%f", value);
if(oatpp::base::environment::switchToJSONCompatibleLocale) {
setlocale(LC_NUMERIC, old_locale);
free(old_locale);
}
return rc;
} However, this is not very elegant and race-conditions could occur! A #include <iostream>
#include <locale>
class force_dot_decimal : : public std::numpunct<char> {
protected:
virtual char do_decimal_point() const
{
return '.';
}
};
v_buff_size float32ToCharSequence(v_float32 value, p_char8 data, v_buff_size n) {
{
std::stringstream ss;
/*
* This way we use the standard locale from std::locale() but force it to use a point as decimal point
* and we don't need to force the user to install our predefined en_US locale
*/
ss.imbue(std::locale(std::locale(), new force_dot_decimal));
ss << value;
/* [...] copying ss to data */
} At least for BSD, OSX and Windows we could use One (even more ugly hack) would be to brute-force a replacement... v_buff_size float32ToCharSequence(v_float32 value, p_char8 data, v_buff_size n) {
auto rc = snprintf((char*)data, n, "%f", value);
p_char8 ptr = data;
for(v_buff_size c = 0; c < rc; ++c){ // or use a stdlib function to search for ','
if(*ptr == ',') {
*ptr = '.';
}
}
return rc;
} |
Hey @bhorn , Yes, really, the fix of this issue is frustrated by existing options. I am more down to the last proposed variant with comma replacement. Also, I think that the fix to this issue should be affecting JSON serializer/deserializer functionality only. |
True that, thats literally the first issue that made me say *oof*
I took a peek at nlohmann's json-lib. This is one hell of a task.
Agreed
Maybe we should implement this for now as hot-fix and come up with something more useful later? |
I Agree |
How about: |
Yes, this was also considered in the @bhorn 's post. |
I have a solution which works good for my project. I attached the patches for version 1.2.0... |
Hey @LokleLama Could you create a fork and a PR for that so can review the changes in a more streamlined process? |
If I set the locale of my Ubuntu System to "de_DE.UTF-8" oat++ serializes float numbers with a comma as decimal separator instead of a dot.
When executing a GET using the Swagger UI I get:
can't parse JSON. Raw result:
{"x":2,000000,"y":0,000000,"z":200,000000}
Is this legal JSON or a bug in oat++ or can this be configured somehow?
The text was updated successfully, but these errors were encountered: