diff --git a/include/rapidjson/prettywriter.h b/include/rapidjson/prettywriter.h index dd0e516d..4f8eba9e 100644 --- a/include/rapidjson/prettywriter.h +++ b/include/rapidjson/prettywriter.h @@ -146,6 +146,18 @@ public: 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: void PrettyPrefix(Type type) { (void)type; diff --git a/include/rapidjson/writer.h b/include/rapidjson/writer.h index dfa2599f..4bda076b 100644 --- a/include/rapidjson/writer.h +++ b/include/rapidjson/writer.h @@ -229,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: //! Information for each nested level struct Level { @@ -387,6 +397,15 @@ protected: bool WriteStartArray() { 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)type; if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root diff --git a/test/unittest/prettywritertest.cpp b/test/unittest/prettywritertest.cpp index d3c69c0e..e05d710f 100644 --- a/test/unittest/prettywritertest.cpp +++ b/test/unittest/prettywritertest.cpp @@ -159,3 +159,22 @@ TEST(PrettyWriter, FileWriteStream) { EXPECT_STREQ(kPrettyJson, json); free(json); } + +TEST(PrettyWriter, RawValue) { + StringBuffer buffer; + PrettyWriter 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()); +} diff --git a/test/unittest/writertest.cpp b/test/unittest/writertest.cpp index 3b1dfe87..3c63ea20 100644 --- a/test/unittest/writertest.cpp +++ b/test/unittest/writertest.cpp @@ -425,3 +425,17 @@ TEST(Writer, Inf) { EXPECT_FALSE(writer.Double(-inf)); } } + +TEST(Writer, RawValue) { + StringBuffer buffer; + Writer 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()); +}