Commit 0ccc51fb authored by Philipp A. Hartmann's avatar Philipp A. Hartmann

Writer: add SetDoublePrecision to control number of significant digits

Writing a double to an OutputStream current prints at most 6 significant
digits (according to the C standard).

The function SetDoublePrecision(), added to the Writer classes
can be used to fluently set the precision, i.e. the number of
significant digits to use for writing the double:

  Writer<...> writer(...);
  d.Accept(writer.SetDoublePrecision(12));
parent 60b8c119
......@@ -26,6 +26,9 @@ public:
PrettyWriter(OutputStream& os, Allocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
//! Overridden for fluent API, see \ref Writer::SetDoublePrecision()
PrettyWriter& SetDoublePrecision(int p) { Base::SetDoublePrecision(p); return *this; }
//! Set custom indentation.
/*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r').
\param indentCharCount Number of indent characters for each indentation level.
......
......@@ -35,7 +35,23 @@ public:
typedef typename SourceEncoding::Ch Ch;
Writer(OutputStream& os, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
os_(os), level_stack_(allocator, levelDepth * sizeof(Level)) {}
os_(os), level_stack_(allocator, levelDepth * sizeof(Level)),
doublePrecision_(kDefaultDoublePrecision) {}
//! Set the number of significant digits for \c double values
/*! When writing a \c double value to the \c OutputStream, the number
of significant digits is limited to 6 by default.
\param p maximum number of significant digits (default: 6)
\return The Writer itself for fluent API.
*/
Writer& SetDoublePrecision(int p = kDefaultDoublePrecision) {
if (p < 0) p = kDefaultDoublePrecision; // negative precision is ignored
doublePrecision_ = p;
return *this;
}
//! \see SetDoublePrecision()
int GetDoublePrecision() const { return doublePrecision_; }
//@name Implementation of Handler
//@{
......@@ -45,6 +61,18 @@ public:
Writer& Uint(unsigned u) { Prefix(kNumberType); WriteUint(u); return *this; }
Writer& Int64(int64_t i64) { Prefix(kNumberType); WriteInt64(i64); return *this; }
Writer& Uint64(uint64_t u64) { Prefix(kNumberType); WriteUint64(u64); return *this; }
//! Writes the given \c double value to the stream
/*!
The number of significant digits (the precision) to be written
can be set by \ref SetDoublePrecision() for the Writer:
\code
Writer<...> writer(...);
writer.SetDoublePrecision(12).Double(M_PI);
\endcode
\param d The value to be written.
\return The Writer itself for fluent API.
*/
Writer& Double(double d) { Prefix(kNumberType); WriteDouble(d); return *this; }
Writer& String(const Ch* str, SizeType length, bool copy = false) {
......@@ -161,18 +189,21 @@ protected:
} while (p != buffer);
}
//! \todo Optimization with custom double-to-string converter.
void WriteDouble(double d) {
char buffer[100];
#ifdef _MSC_VER
int ret = sprintf_s(buffer, sizeof(buffer), "%g", d);
#define RAPIDJSON_SNPRINTF sprintf_s
#else
int ret = snprintf(buffer, sizeof(buffer), "%g", d);
#define RAPIDJSON_SNPRINTF snprintf
#endif
//! \todo Optimization with custom double-to-string converter.
void WriteDouble(double d) {
char buffer[100];
int ret = RAPIDJSON_SNPRINTF(buffer, sizeof(buffer), "%.*g", doublePrecision_, d);
RAPIDJSON_ASSERT(ret >= 1);
for (int i = 0; i < ret; i++)
os_.Put(buffer[i]);
}
#undef RAPIDJSON_SNPRINTF
void WriteString(const Ch* str, SizeType length) {
static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
......@@ -234,6 +265,9 @@ protected:
OutputStream& os_;
internal::Stack<Allocator> level_stack_;
int doublePrecision_;
static const int kDefaultDoublePrecision = 6;
private:
// Prohibit assignment for VC C4512 warning
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment