mirror of
				https://github.com/Tencent/rapidjson.git
				synced 2025-11-04 12:17:41 +01:00 
			
		
		
		
	Merge branch 'master' into optimization
This commit is contained in:
		@@ -145,7 +145,7 @@ inline char* WriteExponent(int K, char* buffer) {
 | 
				
			|||||||
    return buffer;
 | 
					    return buffer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
inline char* Prettify(char* buffer, int length, int k) {
 | 
					inline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) {
 | 
				
			||||||
    const int kk = length + k;  // 10^(kk-1) <= v < 10^kk
 | 
					    const int kk = length + k;  // 10^(kk-1) <= v < 10^kk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (length <= kk && kk <= 21) {
 | 
					    if (length <= kk && kk <= 21) {
 | 
				
			||||||
@@ -160,7 +160,16 @@ inline char* Prettify(char* buffer, int length, int k) {
 | 
				
			|||||||
        // 1234e-2 -> 12.34
 | 
					        // 1234e-2 -> 12.34
 | 
				
			||||||
        std::memmove(&buffer[kk + 1], &buffer[kk], static_cast<size_t>(length - kk));
 | 
					        std::memmove(&buffer[kk + 1], &buffer[kk], static_cast<size_t>(length - kk));
 | 
				
			||||||
        buffer[kk] = '.';
 | 
					        buffer[kk] = '.';
 | 
				
			||||||
        return &buffer[length + 1];
 | 
					        if (length > kk + maxDecimalPlaces) {
 | 
				
			||||||
 | 
					            // When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1
 | 
				
			||||||
 | 
					            // Remove extra trailing zeros (at least one) after truncation.
 | 
				
			||||||
 | 
					            for (int i = kk + maxDecimalPlaces; i > kk + 1; i--)
 | 
				
			||||||
 | 
					                if (buffer[i] != '0')
 | 
				
			||||||
 | 
					                    return &buffer[i + 1];
 | 
				
			||||||
 | 
					            return &buffer[kk + 2]; // Reserve one zero
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            return &buffer[length + 1];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (-6 < kk && kk <= 0) {
 | 
					    else if (-6 < kk && kk <= 0) {
 | 
				
			||||||
        // 1234e-6 -> 0.001234
 | 
					        // 1234e-6 -> 0.001234
 | 
				
			||||||
@@ -170,7 +179,23 @@ inline char* Prettify(char* buffer, int length, int k) {
 | 
				
			|||||||
        buffer[1] = '.';
 | 
					        buffer[1] = '.';
 | 
				
			||||||
        for (int i = 2; i < offset; i++)
 | 
					        for (int i = 2; i < offset; i++)
 | 
				
			||||||
            buffer[i] = '0';
 | 
					            buffer[i] = '0';
 | 
				
			||||||
        return &buffer[length + offset];
 | 
					        if (length + offset > maxDecimalPlaces) {
 | 
				
			||||||
 | 
					            // When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1
 | 
				
			||||||
 | 
					            // Remove extra trailing zeros (at least one) after truncation.
 | 
				
			||||||
 | 
					            for (int i = maxDecimalPlaces + 1; i > 2; i--)
 | 
				
			||||||
 | 
					                if (buffer[i] != '0')
 | 
				
			||||||
 | 
					                    return &buffer[i + 1];
 | 
				
			||||||
 | 
					            return &buffer[3]; // Reserve one zero
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            return &buffer[length + offset];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (kk < -maxDecimalPlaces) {
 | 
				
			||||||
 | 
					        // Truncate to zero
 | 
				
			||||||
 | 
					        buffer[0] = '0';
 | 
				
			||||||
 | 
					        buffer[1] = '.';
 | 
				
			||||||
 | 
					        buffer[2] = '0';
 | 
				
			||||||
 | 
					        return &buffer[3];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (length == 1) {
 | 
					    else if (length == 1) {
 | 
				
			||||||
        // 1e30
 | 
					        // 1e30
 | 
				
			||||||
@@ -186,7 +211,8 @@ inline char* Prettify(char* buffer, int length, int k) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
inline char* dtoa(double value, char* buffer) {
 | 
					inline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) {
 | 
				
			||||||
 | 
					    RAPIDJSON_ASSERT(maxDecimalPlaces >= 1);
 | 
				
			||||||
    Double d(value);
 | 
					    Double d(value);
 | 
				
			||||||
    if (d.IsZero()) {
 | 
					    if (d.IsZero()) {
 | 
				
			||||||
        if (d.Sign())
 | 
					        if (d.Sign())
 | 
				
			||||||
@@ -203,7 +229,7 @@ inline char* dtoa(double value, char* buffer) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        int length, K;
 | 
					        int length, K;
 | 
				
			||||||
        Grisu2(value, buffer, &length, &K);
 | 
					        Grisu2(value, buffer, &length, &K);
 | 
				
			||||||
        return Prettify(buffer, length, K);
 | 
					        return Prettify(buffer, length, K, maxDecimalPlaces);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -146,6 +146,18 @@ public:
 | 
				
			|||||||
    bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
 | 
					    bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //@}
 | 
					    //@}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //! Write a raw JSON value.
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					        For user to write a stringified JSON as a value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range.
 | 
				
			||||||
 | 
					        \param length Length of the json.
 | 
				
			||||||
 | 
					        \param type Type of the root of json.
 | 
				
			||||||
 | 
					        \note When using PrettyWriter::RawValue(), the result json may not be indented correctly.
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					    bool RawValue(const Ch* json, size_t length, Type type) { PrettyPrefix(type); return Base::WriteRawValue(json, length); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
    void PrettyPrefix(Type type) {
 | 
					    void PrettyPrefix(Type type) {
 | 
				
			||||||
        (void)type;
 | 
					        (void)type;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -76,6 +76,8 @@ class Writer {
 | 
				
			|||||||
public:
 | 
					public:
 | 
				
			||||||
    typedef typename SourceEncoding::Ch Ch;
 | 
					    typedef typename SourceEncoding::Ch Ch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static const int kDefaultMaxDecimalPlaces = 324;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //! Constructor
 | 
					    //! Constructor
 | 
				
			||||||
    /*! \param os Output stream.
 | 
					    /*! \param os Output stream.
 | 
				
			||||||
        \param stackAllocator User supplied allocator. If it is null, it will create a private one.
 | 
					        \param stackAllocator User supplied allocator. If it is null, it will create a private one.
 | 
				
			||||||
@@ -83,11 +85,11 @@ public:
 | 
				
			|||||||
    */
 | 
					    */
 | 
				
			||||||
    explicit
 | 
					    explicit
 | 
				
			||||||
    Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : 
 | 
					    Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : 
 | 
				
			||||||
        os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), hasRoot_(false) {}
 | 
					        os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    explicit
 | 
					    explicit
 | 
				
			||||||
    Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
 | 
					    Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
 | 
				
			||||||
        os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), hasRoot_(false) {}
 | 
					        os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //! Reset the writer with a new stream.
 | 
					    //! Reset the writer with a new stream.
 | 
				
			||||||
    /*!
 | 
					    /*!
 | 
				
			||||||
@@ -121,6 +123,35 @@ public:
 | 
				
			|||||||
        return hasRoot_ && level_stack_.Empty();
 | 
					        return hasRoot_ && level_stack_.Empty();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int GetMaxDecimalPlaces() const {
 | 
				
			||||||
 | 
					        return maxDecimalPlaces_;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //! Sets the maximum number of decimal places for double output.
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					        This setting truncates the output with specified number of decimal places.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        For example, 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        \code
 | 
				
			||||||
 | 
					        writer.SetMaxDecimalPlaces(3);
 | 
				
			||||||
 | 
					        writer.StartArray();
 | 
				
			||||||
 | 
					        writer.Double(0.12345);                 // "0.123"
 | 
				
			||||||
 | 
					        writer.Double(0.0001);                  // "0.0"
 | 
				
			||||||
 | 
					        writer.Double(1.234567890123456e30);    // "1.234567890123456e30" (do not truncate significand for positive exponent)
 | 
				
			||||||
 | 
					        writer.Double(1.23e-4);                 // "0.0"                  (do truncate significand for negative exponent)
 | 
				
			||||||
 | 
					        writer.EndArray();
 | 
				
			||||||
 | 
					        \endcode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        The default setting does not truncate any decimal places. You can restore to this setting by calling
 | 
				
			||||||
 | 
					        \code
 | 
				
			||||||
 | 
					        writer.SetMaxDecimalPlaces(Writer::kDefaultMaxDecimalPlaces);
 | 
				
			||||||
 | 
					        \endcode
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					    void SetMaxDecimalPlaces(int maxDecimalPlaces) {
 | 
				
			||||||
 | 
					        maxDecimalPlaces_ = maxDecimalPlaces;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*!@name Implementation of Handler
 | 
					    /*!@name Implementation of Handler
 | 
				
			||||||
        \see Handler
 | 
					        \see Handler
 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
@@ -198,6 +229,16 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    //@}
 | 
					    //@}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //! Write a raw JSON value.
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					        For user to write a stringified JSON as a value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range.
 | 
				
			||||||
 | 
					        \param length Length of the json.
 | 
				
			||||||
 | 
					        \param type Type of the root of json.
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					    bool RawValue(const Ch* json, size_t length, Type type) { Prefix(type); return WriteRawValue(json, length); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
    //! Information for each nested level
 | 
					    //! Information for each nested level
 | 
				
			||||||
    struct Level {
 | 
					    struct Level {
 | 
				
			||||||
@@ -266,7 +307,7 @@ protected:
 | 
				
			|||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        char buffer[25];
 | 
					        char buffer[25];
 | 
				
			||||||
        char* end = internal::dtoa(d, buffer);
 | 
					        char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
 | 
				
			||||||
        PutReserve(*os_, static_cast<size_t>(end - buffer));
 | 
					        PutReserve(*os_, static_cast<size_t>(end - buffer));
 | 
				
			||||||
        for (char* p = buffer; p != end; ++p)
 | 
					        for (char* p = buffer; p != end; ++p)
 | 
				
			||||||
            PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
 | 
					            PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
 | 
				
			||||||
@@ -356,6 +397,15 @@ protected:
 | 
				
			|||||||
    bool WriteStartArray()  { os_->Put('['); return true; }
 | 
					    bool WriteStartArray()  { os_->Put('['); return true; }
 | 
				
			||||||
    bool WriteEndArray()    { os_->Put(']'); return true; }
 | 
					    bool WriteEndArray()    { os_->Put(']'); return true; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool WriteRawValue(const Ch* json, size_t length) {
 | 
				
			||||||
 | 
					        PutReserve(*os_, length);
 | 
				
			||||||
 | 
					        for (size_t i = 0; i < length; i++) {
 | 
				
			||||||
 | 
					            RAPIDJSON_ASSERT(json[i] != '\0');
 | 
				
			||||||
 | 
					            PutUnsafe(*os_, json[i]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Prefix(Type type) {
 | 
					    void Prefix(Type type) {
 | 
				
			||||||
        (void)type;
 | 
					        (void)type;
 | 
				
			||||||
        if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root
 | 
					        if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root
 | 
				
			||||||
@@ -378,6 +428,7 @@ protected:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    OutputStream* os_;
 | 
					    OutputStream* os_;
 | 
				
			||||||
    internal::Stack<StackAllocator> level_stack_;
 | 
					    internal::Stack<StackAllocator> level_stack_;
 | 
				
			||||||
 | 
					    int maxDecimalPlaces_;
 | 
				
			||||||
    bool hasRoot_;
 | 
					    bool hasRoot_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
@@ -426,7 +477,7 @@ inline bool Writer<StringBuffer>::WriteDouble(double d) {
 | 
				
			|||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    char *buffer = os_->Push(25);
 | 
					    char *buffer = os_->Push(25);
 | 
				
			||||||
    char* end = internal::dtoa(d, buffer);
 | 
					    char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
 | 
				
			||||||
    os_->Pop(static_cast<size_t>(25 - (end - buffer)));
 | 
					    os_->Pop(static_cast<size_t>(25 - (end - buffer)));
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ set(UNITTEST_SOURCES
 | 
				
			|||||||
	allocatorstest.cpp
 | 
						allocatorstest.cpp
 | 
				
			||||||
    bigintegertest.cpp
 | 
					    bigintegertest.cpp
 | 
				
			||||||
    documenttest.cpp
 | 
					    documenttest.cpp
 | 
				
			||||||
 | 
					    dtoatest.cpp
 | 
				
			||||||
    encodedstreamtest.cpp
 | 
					    encodedstreamtest.cpp
 | 
				
			||||||
    encodingstest.cpp
 | 
					    encodingstest.cpp
 | 
				
			||||||
    fwdtest.cpp
 | 
					    fwdtest.cpp
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										91
									
								
								test/unittest/dtoatest.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								test/unittest/dtoatest.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					// Tencent is pleased to support the open source community by making RapidJSON available.
 | 
				
			||||||
 | 
					// 
 | 
				
			||||||
 | 
					// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the MIT License (the "License"); you may not use this file except
 | 
				
			||||||
 | 
					// in compliance with the License. You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// http://opensource.org/licenses/MIT
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software distributed 
 | 
				
			||||||
 | 
					// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
 | 
				
			||||||
 | 
					// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
 | 
				
			||||||
 | 
					// specific language governing permissions and limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "unittest.h"
 | 
				
			||||||
 | 
					#include "rapidjson/internal/dtoa.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __GNUC__
 | 
				
			||||||
 | 
					RAPIDJSON_DIAG_PUSH
 | 
				
			||||||
 | 
					RAPIDJSON_DIAG_OFF(type-limits)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace rapidjson::internal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(dtoa, normal) {
 | 
				
			||||||
 | 
					    char buffer[30];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TEST_DTOA(d, a)\
 | 
				
			||||||
 | 
					    *dtoa(d, buffer) = '\0';\
 | 
				
			||||||
 | 
					    EXPECT_STREQ(a, buffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TEST_DTOA(0.0, "0.0");
 | 
				
			||||||
 | 
					    TEST_DTOA(-0.0, "-0.0");
 | 
				
			||||||
 | 
					    TEST_DTOA(1.0, "1.0");
 | 
				
			||||||
 | 
					    TEST_DTOA(-1.0, "-1.0");
 | 
				
			||||||
 | 
					    TEST_DTOA(1.2345, "1.2345");
 | 
				
			||||||
 | 
					    TEST_DTOA(1.2345678, "1.2345678");
 | 
				
			||||||
 | 
					    TEST_DTOA(0.123456789012, "0.123456789012");
 | 
				
			||||||
 | 
					    TEST_DTOA(1234567.8, "1234567.8");
 | 
				
			||||||
 | 
					    TEST_DTOA(0.000001, "0.000001");
 | 
				
			||||||
 | 
					    TEST_DTOA(0.0000001, "1e-7");
 | 
				
			||||||
 | 
					    TEST_DTOA(1e30, "1e30");
 | 
				
			||||||
 | 
					    TEST_DTOA(1.234567890123456e30, "1.234567890123456e30");
 | 
				
			||||||
 | 
					    TEST_DTOA(5e-324, "5e-324"); // Min subnormal positive double
 | 
				
			||||||
 | 
					    TEST_DTOA(2.225073858507201e-308, "2.225073858507201e-308"); // Max subnormal positive double
 | 
				
			||||||
 | 
					    TEST_DTOA(2.2250738585072014e-308, "2.2250738585072014e-308"); // Min normal positive double
 | 
				
			||||||
 | 
					    TEST_DTOA(1.7976931348623157e308, "1.7976931348623157e308"); // Max double
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef TEST_DTOA
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(dtoa, maxDecimalPlaces) {
 | 
				
			||||||
 | 
					    char buffer[30];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TEST_DTOA(m, d, a)\
 | 
				
			||||||
 | 
					    *dtoa(d, buffer, m) = '\0';\
 | 
				
			||||||
 | 
					    EXPECT_STREQ(a, buffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TEST_DTOA(3, 0.0, "0.0");
 | 
				
			||||||
 | 
					    TEST_DTOA(1, 0.0, "0.0");
 | 
				
			||||||
 | 
					    TEST_DTOA(3, -0.0, "-0.0");
 | 
				
			||||||
 | 
					    TEST_DTOA(3, 1.0, "1.0");
 | 
				
			||||||
 | 
					    TEST_DTOA(3, -1.0, "-1.0");
 | 
				
			||||||
 | 
					    TEST_DTOA(3, 1.2345, "1.234");
 | 
				
			||||||
 | 
					    TEST_DTOA(2, 1.2345, "1.23");
 | 
				
			||||||
 | 
					    TEST_DTOA(1, 1.2345, "1.2");
 | 
				
			||||||
 | 
					    TEST_DTOA(3, 1.2345678, "1.234");
 | 
				
			||||||
 | 
					    TEST_DTOA(3, 1.0001, "1.0");
 | 
				
			||||||
 | 
					    TEST_DTOA(2, 1.0001, "1.0");
 | 
				
			||||||
 | 
					    TEST_DTOA(1, 1.0001, "1.0");
 | 
				
			||||||
 | 
					    TEST_DTOA(3, 0.123456789012, "0.123");
 | 
				
			||||||
 | 
					    TEST_DTOA(2, 0.123456789012, "0.12");
 | 
				
			||||||
 | 
					    TEST_DTOA(1, 0.123456789012, "0.1");
 | 
				
			||||||
 | 
					    TEST_DTOA(4, 0.0001, "0.0001");
 | 
				
			||||||
 | 
					    TEST_DTOA(3, 0.0001, "0.0");
 | 
				
			||||||
 | 
					    TEST_DTOA(2, 0.0001, "0.0");
 | 
				
			||||||
 | 
					    TEST_DTOA(1, 0.0001, "0.0");
 | 
				
			||||||
 | 
					    TEST_DTOA(3, 1234567.8, "1234567.8");
 | 
				
			||||||
 | 
					    TEST_DTOA(3, 1e30, "1e30");
 | 
				
			||||||
 | 
					    TEST_DTOA(3, 5e-324, "0.0"); // Min subnormal positive double
 | 
				
			||||||
 | 
					    TEST_DTOA(3, 2.225073858507201e-308, "0.0"); // Max subnormal positive double
 | 
				
			||||||
 | 
					    TEST_DTOA(3, 2.2250738585072014e-308, "0.0"); // Min normal positive double
 | 
				
			||||||
 | 
					    TEST_DTOA(3, 1.7976931348623157e308, "1.7976931348623157e308"); // Max double
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef TEST_DTOA
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __GNUC__
 | 
				
			||||||
 | 
					RAPIDJSON_DIAG_POP
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@@ -159,3 +159,22 @@ TEST(PrettyWriter, FileWriteStream) {
 | 
				
			|||||||
    EXPECT_STREQ(kPrettyJson, json);
 | 
					    EXPECT_STREQ(kPrettyJson, json);
 | 
				
			||||||
    free(json);
 | 
					    free(json);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(PrettyWriter, RawValue) {
 | 
				
			||||||
 | 
					    StringBuffer buffer;
 | 
				
			||||||
 | 
					    PrettyWriter<StringBuffer> writer(buffer);
 | 
				
			||||||
 | 
					    writer.StartObject();
 | 
				
			||||||
 | 
					    writer.Key("a");
 | 
				
			||||||
 | 
					    writer.Int(1);
 | 
				
			||||||
 | 
					    writer.Key("raw");
 | 
				
			||||||
 | 
					    const char json[] = "[\"Hello\\nWorld\", 123.456]";
 | 
				
			||||||
 | 
					    writer.RawValue(json, strlen(json), kArrayType);
 | 
				
			||||||
 | 
					    writer.EndObject();
 | 
				
			||||||
 | 
					    EXPECT_TRUE(writer.IsComplete());
 | 
				
			||||||
 | 
					    EXPECT_STREQ(
 | 
				
			||||||
 | 
					        "{\n"
 | 
				
			||||||
 | 
					        "    \"a\": 1,\n"
 | 
				
			||||||
 | 
					        "    \"raw\": [\"Hello\\nWorld\", 123.456]\n" // no indentation within raw value
 | 
				
			||||||
 | 
					        "}",
 | 
				
			||||||
 | 
					        buffer.GetString());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -425,3 +425,17 @@ TEST(Writer, Inf) {
 | 
				
			|||||||
        EXPECT_FALSE(writer.Double(-inf));
 | 
					        EXPECT_FALSE(writer.Double(-inf));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(Writer, RawValue) {
 | 
				
			||||||
 | 
					    StringBuffer buffer;
 | 
				
			||||||
 | 
					    Writer<StringBuffer> writer(buffer);
 | 
				
			||||||
 | 
					    writer.StartObject();
 | 
				
			||||||
 | 
					    writer.Key("a");
 | 
				
			||||||
 | 
					    writer.Int(1);
 | 
				
			||||||
 | 
					    writer.Key("raw");
 | 
				
			||||||
 | 
					    const char json[] = "[\"Hello\\nWorld\", 123.456]";
 | 
				
			||||||
 | 
					    writer.RawValue(json, strlen(json), kArrayType);
 | 
				
			||||||
 | 
					    writer.EndObject();
 | 
				
			||||||
 | 
					    EXPECT_TRUE(writer.IsComplete());
 | 
				
			||||||
 | 
					    EXPECT_STREQ("{\"a\":1,\"raw\":[\"Hello\\nWorld\", 123.456]}", buffer.GetString());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user