diff --git a/src/oatpp/core/data/mapping/type/Object.hpp b/src/oatpp/core/data/mapping/type/Object.hpp
index 6aae76f9..f3aa5ad9 100644
--- a/src/oatpp/core/data/mapping/type/Object.hpp
+++ b/src/oatpp/core/data/mapping/type/Object.hpp
@@ -105,7 +105,7 @@ public:
/**
* Format.
*/
- std::string format = OATPP_FLOAT_STRING_FORMAT;
+ std::string format = "";
/**
* Required.
*/
diff --git a/src/oatpp/core/data/stream/Stream.cpp b/src/oatpp/core/data/stream/Stream.cpp
index 180b00c3..3bc18248 100644
--- a/src/oatpp/core/data/stream/Stream.cpp
+++ b/src/oatpp/core/data/stream/Stream.cpp
@@ -397,18 +397,18 @@ v_io_size ConsistentOutputStream::writeAsString(v_uint64 value){
return 0;
}
-v_io_size ConsistentOutputStream::writeAsString(v_float32 value){
+v_io_size ConsistentOutputStream::writeAsString(v_float32 value, const char* format){
v_char8 a[100];
- auto size = utils::conversion::float32ToCharSequence(value, &a[0], 100, floatFormat->c_str());
+ auto size = utils::conversion::float32ToCharSequence(value, &a[0], 100, format);
if(size > 0){
return writeSimple(&a[0], size);
}
return 0;
}
-v_io_size ConsistentOutputStream::writeAsString(v_float64 value){
+v_io_size ConsistentOutputStream::writeAsString(v_float64 value, const char* format){
v_char8 a[100];
- auto size = utils::conversion::float64ToCharSequence(value, &a[0], 100, floatFormat->c_str());
+ auto size = utils::conversion::float64ToCharSequence(value, &a[0], 100, format);
if(size > 0){
return writeSimple(&a[0], size);
}
@@ -533,6 +533,18 @@ ConsistentOutputStream& operator << (ConsistentOutputStream& s, const char* str)
return s;
}
+template<>
+ConsistentOutputStream& operator << (ConsistentOutputStream& s, v_float32 value) {
+ s.writeAsString(value, "");
+ return s;
+}
+
+template<>
+ConsistentOutputStream& operator << (ConsistentOutputStream& s, v_float64 value) {
+ s.writeAsString(value, "");
+ return s;
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DataTransferProcessor
diff --git a/src/oatpp/core/data/stream/Stream.hpp b/src/oatpp/core/data/stream/Stream.hpp
index a7068205..6162e15d 100644
--- a/src/oatpp/core/data/stream/Stream.hpp
+++ b/src/oatpp/core/data/stream/Stream.hpp
@@ -405,7 +405,6 @@ public:
*/
class ConsistentOutputStream : public OutputStream {
public:
- String floatFormat = OATPP_FLOAT_STRING_FORMAT;
/**
* Convert value to string and write to stream.
@@ -468,14 +467,14 @@ public:
* @param value
* @return - actual number of bytes written. &id:oatpp::v_io_size;.
*/
- v_io_size writeAsString(v_float32 value);
+ v_io_size writeAsString(v_float32 value, const char* format);
/**
* Convert value to string and write to stream.
* @param value
* @return - actual number of bytes written. &id:oatpp::v_io_size;.
*/
- v_io_size writeAsString(v_float64 value);
+ v_io_size writeAsString(v_float64 value, const char* format);
/**
* Convert value to string and write to stream.
@@ -507,6 +506,12 @@ ConsistentOutputStream& operator << (ConsistentOutputStream& s, T value) {
return s;
}
+template<>
+ConsistentOutputStream& operator << (ConsistentOutputStream& s, v_float32 value);
+
+template<>
+ConsistentOutputStream& operator << (ConsistentOutputStream& s, v_float64 value);
+
/**
* Error of Asynchronous stream transfer.
*/
diff --git a/src/oatpp/core/utils/ConversionUtils.cpp b/src/oatpp/core/utils/ConversionUtils.cpp
index a5ef0134..8485a9e9 100644
--- a/src/oatpp/core/utils/ConversionUtils.cpp
+++ b/src/oatpp/core/utils/ConversionUtils.cpp
@@ -189,10 +189,16 @@ namespace oatpp { namespace utils { namespace conversion {
}
v_buff_size float32ToCharSequence(v_float32 value, p_char8 data, v_buff_size n, const char* format) {
+ if(std::strlen(format) <= 0){
+ format = OATPP_FLOAT_STRING_FORMAT;
+ }
return snprintf((char*)data, n, format, value);
}
v_buff_size float64ToCharSequence(v_float64 value, p_char8 data, v_buff_size n, const char* format) {
+ if(std::strlen(format) <= 0){
+ format = OATPP_FLOAT_STRING_FORMAT;
+ }
return snprintf((char*)data, n, format, value);
}
diff --git a/src/oatpp/parser/json/mapping/Serializer.cpp b/src/oatpp/parser/json/mapping/Serializer.cpp
index 8a8b1515..fc469a59 100644
--- a/src/oatpp/parser/json/mapping/Serializer.cpp
+++ b/src/oatpp/parser/json/mapping/Serializer.cpp
@@ -64,6 +64,7 @@ Serializer::Serializer(const std::shared_ptr& config)
setSerializerMethod(data::mapping::type::__class::AbstractPairList::CLASS_ID, &Serializer::serializeMap);
setSerializerMethod(data::mapping::type::__class::AbstractUnorderedMap::CLASS_ID, &Serializer::serializeMap);
+ m_context = std::unique_ptr(new Context());
}
void Serializer::setSerializerMethod(const data::mapping::type::ClassId& classId, SerializerMethod method) {
@@ -74,6 +75,46 @@ void Serializer::setSerializerMethod(const data::mapping::type::ClassId& classId
m_methods[id] = method;
}
+template<>
+void Serializer::serializePrimitive(Serializer* serializer,
+ data::stream::ConsistentOutputStream* stream,
+ const oatpp::Void& polymorph){
+ if (polymorph) {
+ std::string format;
+ if (!serializer->m_context->info.format.empty()) {
+ format = serializer->m_context->info.format;
+ }
+ else if (!serializer->m_config->floatStringFormat->empty()) {
+ format = serializer->m_config->floatStringFormat;
+ }
+ stream->writeAsString(*static_cast(polymorph.get()),
+ format.c_str());
+ }
+ else {
+ stream->writeSimple("null", 4);
+ }
+}
+
+template<>
+void Serializer::serializePrimitive(Serializer* serializer,
+ data::stream::ConsistentOutputStream* stream,
+ const oatpp::Void& polymorph) {
+ if (polymorph) {
+ std::string format;
+ if (!serializer->m_context->info.format.empty()) {
+ format = serializer->m_context->info.format;
+ }
+ else if (!serializer->m_config->floatStringFormat->empty()) {
+ format = serializer->m_config->floatStringFormat;
+ }
+ stream->writeAsString(*static_cast(polymorph.get()),
+ format.c_str());
+ }
+ else {
+ stream->writeSimple("null", 4);
+ }
+}
+
void Serializer::serializeString(data::stream::ConsistentOutputStream* stream, const char* data, v_buff_size size, v_uint32 escapeFlags) {
auto encodedValue = Utils::escapeString(data, size, escapeFlags);
stream->writeCharSimple('\"');
@@ -228,6 +269,7 @@ void Serializer::serializeObject(Serializer* serializer,
auto fields = dispatcher->getProperties()->getList();
auto object = static_cast(polymorph.get());
auto config = serializer->m_config;
+ auto &context = serializer->m_context;
for (auto const& field : fields) {
@@ -243,17 +285,9 @@ void Serializer::serializeObject(Serializer* serializer,
(first) ? first = false : stream->writeSimple(",", 1);
serializeString(stream, field->name, std::strlen(field->name), serializer->m_config->escapeFlags);
stream->writeSimple(":", 1);
- auto streamFloatFormat = stream->floatFormat;
- if (config->floatStringFormat != OATPP_FLOAT_STRING_FORMAT) {
- stream->floatFormat = config->floatStringFormat;
- }
- if (field->info.format != OATPP_FLOAT_STRING_FORMAT) {
- stream->floatFormat = field->info.format;
- }
+
+ context->info = field->info;
serializer->serialize(stream, value);
- if (stream->floatFormat != streamFloatFormat) {
- stream->floatFormat = streamFloatFormat;
- }
}
}
@@ -286,8 +320,6 @@ void Serializer::serialize(data::stream::ConsistentOutputStream* stream,
void Serializer::serializeToStream(data::stream::ConsistentOutputStream* stream,
const oatpp::Void& polymorph)
{
- if(m_config->floatStringFormat != stream->floatFormat)
- stream->floatFormat = m_config->floatStringFormat;
if(m_config->useBeautifier) {
json::Beautifier beautifier(stream, " ", "\n");
serialize(&beautifier, polymorph);
diff --git a/src/oatpp/parser/json/mapping/Serializer.hpp b/src/oatpp/parser/json/mapping/Serializer.hpp
index db531dd5..b40bef74 100644
--- a/src/oatpp/parser/json/mapping/Serializer.hpp
+++ b/src/oatpp/parser/json/mapping/Serializer.hpp
@@ -116,9 +116,26 @@ public:
/**
* Format of float string.
*/
- oatpp::String floatStringFormat = OATPP_FLOAT_STRING_FORMAT;
+ oatpp::String floatStringFormat = "";
};
+
+private:
+ /**
+ * Serializer context.
+ */
+ class Context : public oatpp::base::Countable {
+ public:
+ /**
+ * Constructor.
+ */
+ Context()
+ {}
+ public:
+
+ data::mapping::type::BaseObject::Property::Info info;
+ };
+
public:
typedef void (*SerializerMethod)(Serializer*,
data::stream::ConsistentOutputStream*,
@@ -137,7 +154,7 @@ private:
stream->writeSimple("null", 4);
}
}
-
+
static void serializeString(oatpp::data::stream::ConsistentOutputStream* stream,
const char* data,
v_buff_size size,
@@ -171,6 +188,7 @@ private:
private:
std::shared_ptr m_config;
+ std::unique_ptr m_context;
std::vector m_methods;
public:
@@ -202,6 +220,16 @@ public:
};
+template<>
+void Serializer::serializePrimitive(Serializer* serializer,
+ data::stream::ConsistentOutputStream* stream,
+ const oatpp::Void& polymorph);
+
+template<>
+void Serializer::serializePrimitive(Serializer* serializer,
+ data::stream::ConsistentOutputStream* stream,
+ const oatpp::Void& polymorph);
+
}}}}
#endif /* oatpp_parser_json_mapping_Serializer_hpp */
diff --git a/test/oatpp/parser/json/mapping/FloatTest.cpp b/test/oatpp/parser/json/mapping/FloatTest.cpp
index bb10928f..2230c7b3 100644
--- a/test/oatpp/parser/json/mapping/FloatTest.cpp
+++ b/test/oatpp/parser/json/mapping/FloatTest.cpp
@@ -54,19 +54,36 @@ class DTO_32_1 : public oatpp::DTO {
class DTO_64_0 : public oatpp::DTO {
- DTO_INIT(DTO_64_0, DTO)
+ DTO_INIT(DTO_64_0, DTO)
- DTO_FIELD(Float64, f64);
+ DTO_FIELD(Float64, f64);
};
class DTO_64_1 : public oatpp::DTO {
- DTO_INIT(DTO_64_1, DTO)
+ DTO_INIT(DTO_64_1, DTO)
- DTO_FIELD_INFO(f64) {
- info->format = "%.2f";
- }
- DTO_FIELD(Float64, f64);
+ DTO_FIELD_INFO(f64) {
+ info->format = "%.2f";
+ }
+ DTO_FIELD(Float64, f64);
+};
+
+class DTO_64_2 : public oatpp::DTO {
+
+ DTO_INIT(DTO_64_2, DTO)
+
+ DTO_FIELD_INFO(f64_1) {
+ info->format = "%.1f";
+ }
+ DTO_FIELD(Float64, f64_1);
+
+ DTO_FIELD_INFO(f64_2) {
+ info->format = "%.2f";
+ }
+ DTO_FIELD(Float64, f64_2);
+
+ DTO_FIELD(Int32, i);
};
#include OATPP_CODEGEN_END(DTO)
@@ -120,6 +137,18 @@ void FloatTest::onRun() {
OATPP_LOGI(TAG, "OK");
}
+ {
+ auto test = DTO_64_2::createShared();
+ test->f64_1 = 123456.123456;
+ test->f64_2 = 123456.123456;
+ test->i = 10;
+ OATPP_LOGI(TAG, "using 2 formats...");
+ auto json = mapper.writeToString(test);
+ OATPP_LOGD(TAG, "json='%s'", json->c_str());
+ OATPP_ASSERT(json == "{\"f64_1\":123456.1,\"f64_2\":123456.12,\"i\":10}");
+ OATPP_LOGI(TAG, "OK");
+ }
+
{
auto test = DTO_32_0::createShared();
test->f32 = 123456.123456;