fixed locale problems
This commit is contained in:
		
							parent
							
								
									43ee70cef8
								
							
						
					
					
						commit
						31bccc83b9
					
				
					 3 changed files with 93 additions and 62 deletions
				
			
		
							
								
								
									
										48
									
								
								src/json.hpp
									
										
									
									
									
								
							
							
						
						
									
										48
									
								
								src/json.hpp
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -6114,24 +6114,26 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::number_float:
 | 
			
		||||
            {
 | 
			
		||||
                // buffer size: precision (2^8-1 = 255) + other ('-.e-xxx' = 7) + null (1)
 | 
			
		||||
                char buf[263];
 | 
			
		||||
                int len;
 | 
			
		||||
 | 
			
		||||
                // check if number was parsed from a string
 | 
			
		||||
                if (m_type.bits.parsed)
 | 
			
		||||
                {
 | 
			
		||||
                    // check if parsed number had an exponent given
 | 
			
		||||
                    if (m_type.bits.has_exp)
 | 
			
		||||
                    {
 | 
			
		||||
                        // buffer size: precision (2^8-1 = 255) + other ('-.e-xxx' = 7) + null (1)
 | 
			
		||||
                        char buf[263];
 | 
			
		||||
                        int len;
 | 
			
		||||
 | 
			
		||||
                        // handle capitalization of the exponent
 | 
			
		||||
                        if (m_type.bits.exp_cap)
 | 
			
		||||
                        {
 | 
			
		||||
                            len = snprintf(buf, sizeof(buf), "%.*E", m_type.bits.precision, m_value.number_float) + 1;
 | 
			
		||||
                            len = snprintf(buf, sizeof(buf), "%.*E",
 | 
			
		||||
                                           m_type.bits.precision, m_value.number_float) + 1;
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            len = snprintf(buf, sizeof(buf), "%.*e", m_type.bits.precision, m_value.number_float) + 1;
 | 
			
		||||
                            len = snprintf(buf, sizeof(buf), "%.*e",
 | 
			
		||||
                                           m_type.bits.precision, m_value.number_float) + 1;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // remove '+' sign from the exponent if necessary
 | 
			
		||||
| 
						 | 
				
			
			@ -6152,26 +6154,25 @@ class basic_json
 | 
			
		|||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        o << buf;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        // no exponent - output as a decimal
 | 
			
		||||
                        snprintf(buf, sizeof(buf), "%.*f",
 | 
			
		||||
                                 m_type.bits.precision, m_value.number_float);
 | 
			
		||||
                        std::stringstream ss;
 | 
			
		||||
                        ss.imbue(std::locale("C"));
 | 
			
		||||
                        ss << std::setprecision(m_type.bits.precision)
 | 
			
		||||
                           << std::fixed << m_value.number_float;
 | 
			
		||||
                        o << ss.str();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if (m_value.number_float == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    // special case for zero to get "0.0"/"-0.0"
 | 
			
		||||
                    if (std::signbit(m_value.number_float))
 | 
			
		||||
                    {
 | 
			
		||||
                        o << "-0.0";
 | 
			
		||||
                    }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                        o << "0.0";
 | 
			
		||||
                    }
 | 
			
		||||
                    return;
 | 
			
		||||
                    if (m_value.number_float == 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        // special case for zero to get "0.0"/"-0.0"
 | 
			
		||||
                        o << (std::signbit(m_value.number_float) ? "-0.0" : "0.0");
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
| 
						 | 
				
			
			@ -6180,12 +6181,13 @@ class basic_json
 | 
			
		|||
                        // string->double->string or string->long double->string;
 | 
			
		||||
                        // to be safe, we read this value from
 | 
			
		||||
                        // std::numeric_limits<number_float_t>::digits10
 | 
			
		||||
                    snprintf(buf, sizeof(buf), "%.*g",
 | 
			
		||||
                             std::numeric_limits<double>::digits10,
 | 
			
		||||
                             m_value.number_float);
 | 
			
		||||
                        std::stringstream ss;
 | 
			
		||||
                        ss.imbue(std::locale("C"));
 | 
			
		||||
                        ss << std::setprecision(std::numeric_limits<double>::digits10)
 | 
			
		||||
                           << m_value.number_float;
 | 
			
		||||
                        o << ss.str();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                o << buf;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6114,24 +6114,26 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::number_float:
 | 
			
		||||
            {
 | 
			
		||||
                // buffer size: precision (2^8-1 = 255) + other ('-.e-xxx' = 7) + null (1)
 | 
			
		||||
                char buf[263];
 | 
			
		||||
                int len;
 | 
			
		||||
 | 
			
		||||
                // check if number was parsed from a string
 | 
			
		||||
                if (m_type.bits.parsed)
 | 
			
		||||
                {
 | 
			
		||||
                    // check if parsed number had an exponent given
 | 
			
		||||
                    if (m_type.bits.has_exp)
 | 
			
		||||
                    {
 | 
			
		||||
                        // buffer size: precision (2^8-1 = 255) + other ('-.e-xxx' = 7) + null (1)
 | 
			
		||||
                        char buf[263];
 | 
			
		||||
                        int len;
 | 
			
		||||
 | 
			
		||||
                        // handle capitalization of the exponent
 | 
			
		||||
                        if (m_type.bits.exp_cap)
 | 
			
		||||
                        {
 | 
			
		||||
                            len = snprintf(buf, sizeof(buf), "%.*E", m_type.bits.precision, m_value.number_float) + 1;
 | 
			
		||||
                            len = snprintf(buf, sizeof(buf), "%.*E",
 | 
			
		||||
                                           m_type.bits.precision, m_value.number_float) + 1;
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            len = snprintf(buf, sizeof(buf), "%.*e", m_type.bits.precision, m_value.number_float) + 1;
 | 
			
		||||
                            len = snprintf(buf, sizeof(buf), "%.*e",
 | 
			
		||||
                                           m_type.bits.precision, m_value.number_float) + 1;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // remove '+' sign from the exponent if necessary
 | 
			
		||||
| 
						 | 
				
			
			@ -6152,26 +6154,25 @@ class basic_json
 | 
			
		|||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        o << buf;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        // no exponent - output as a decimal
 | 
			
		||||
                        snprintf(buf, sizeof(buf), "%.*f",
 | 
			
		||||
                                 m_type.bits.precision, m_value.number_float);
 | 
			
		||||
                        std::stringstream ss;
 | 
			
		||||
                        ss.imbue(std::locale("C"));  // fix locale problems
 | 
			
		||||
                        ss << std::setprecision(m_type.bits.precision)
 | 
			
		||||
                           << std::fixed << m_value.number_float;
 | 
			
		||||
                        o << ss.str();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if (m_value.number_float == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    // special case for zero to get "0.0"/"-0.0"
 | 
			
		||||
                    if (std::signbit(m_value.number_float))
 | 
			
		||||
                    {
 | 
			
		||||
                        o << "-0.0";
 | 
			
		||||
                    }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                        o << "0.0";
 | 
			
		||||
                    }
 | 
			
		||||
                    return;
 | 
			
		||||
                    if (m_value.number_float == 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        // special case for zero to get "0.0"/"-0.0"
 | 
			
		||||
                        o << (std::signbit(m_value.number_float) ? "-0.0" : "0.0");
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
| 
						 | 
				
			
			@ -6180,12 +6181,13 @@ class basic_json
 | 
			
		|||
                        // string->double->string or string->long double->string;
 | 
			
		||||
                        // to be safe, we read this value from
 | 
			
		||||
                        // std::numeric_limits<number_float_t>::digits10
 | 
			
		||||
                    snprintf(buf, sizeof(buf), "%.*g",
 | 
			
		||||
                             std::numeric_limits<double>::digits10,
 | 
			
		||||
                             m_value.number_float);
 | 
			
		||||
                        std::stringstream ss;
 | 
			
		||||
                        ss.imbue(std::locale("C"));  // fix locale problems
 | 
			
		||||
                        ss << std::setprecision(std::numeric_limits<double>::digits10)
 | 
			
		||||
                           << m_value.number_float;
 | 
			
		||||
                        o << ss.str();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                o << buf;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12369,5 +12369,32 @@ TEST_CASE("regression tests")
 | 
			
		|||
        j_long_double = 1.23e45L;
 | 
			
		||||
        CHECK(j_long_double.get<long double>() == 1.23e45L);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SECTION("issue #228 - double values are serialized with commas as decimal points")
 | 
			
		||||
    {
 | 
			
		||||
        json j1a = 23.42;
 | 
			
		||||
        json j1b = json::parse("23.42");
 | 
			
		||||
 | 
			
		||||
        json j2a = 2342e-2;
 | 
			
		||||
        //issue #230
 | 
			
		||||
        //json j2b = json::parse("2342e-2");
 | 
			
		||||
 | 
			
		||||
        json j3a = 10E3;
 | 
			
		||||
        json j3b = json::parse("10E3");
 | 
			
		||||
        json j3c = json::parse("10e3");
 | 
			
		||||
 | 
			
		||||
        std::locale::global(std::locale("de_DE"));
 | 
			
		||||
 | 
			
		||||
        CHECK(j1a.dump() == "23.42");
 | 
			
		||||
        CHECK(j1b.dump() == "23.42");
 | 
			
		||||
 | 
			
		||||
        CHECK(j2a.dump() == "23.42");
 | 
			
		||||
        //issue #230
 | 
			
		||||
        //CHECK(j2b.dump() == "23.42");
 | 
			
		||||
 | 
			
		||||
        CHECK(j3a.dump() == "10000");
 | 
			
		||||
        CHECK(j3b.dump() == "1E04");
 | 
			
		||||
        CHECK(j3c.dump() == "1e04");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue