Add encoding validation option for Writer/PrettyWriter
This commit is contained in:
parent
935e2ef7ed
commit
964d89e34b
@ -91,9 +91,14 @@ typedef GenericReader<UTF8<char>, UTF8<char>, CrtAllocator> Reader;
|
|||||||
|
|
||||||
// writer.h
|
// writer.h
|
||||||
|
|
||||||
template<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator>
|
template<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags>
|
||||||
class Writer;
|
class Writer;
|
||||||
|
|
||||||
|
// prettywriter.h
|
||||||
|
|
||||||
|
template<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags>
|
||||||
|
class PrettyWriter;
|
||||||
|
|
||||||
// document.h
|
// document.h
|
||||||
|
|
||||||
template <typename Encoding, typename Allocator>
|
template <typename Encoding, typename Allocator>
|
||||||
|
@ -31,8 +31,8 @@ RAPIDJSON_NAMESPACE_BEGIN
|
|||||||
\tparam TargetEncoding Encoding of output stream.
|
\tparam TargetEncoding Encoding of output stream.
|
||||||
\tparam StackAllocator Type of allocator for allocating memory of stack.
|
\tparam StackAllocator Type of allocator for allocating memory of stack.
|
||||||
*/
|
*/
|
||||||
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator>
|
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>
|
||||||
class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> {
|
class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> {
|
||||||
public:
|
public:
|
||||||
typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> Base;
|
typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> Base;
|
||||||
typedef typename Base::Ch Ch;
|
typedef typename Base::Ch Ch;
|
||||||
@ -42,9 +42,13 @@ public:
|
|||||||
\param allocator User supplied allocator. If it is null, it will create a private one.
|
\param allocator User supplied allocator. If it is null, it will create a private one.
|
||||||
\param levelDepth Initial capacity of stack.
|
\param levelDepth Initial capacity of stack.
|
||||||
*/
|
*/
|
||||||
PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
|
explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
|
||||||
Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
|
Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
|
||||||
|
|
||||||
|
|
||||||
|
explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
|
||||||
|
Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
|
||||||
|
|
||||||
//! Set custom indentation.
|
//! Set custom indentation.
|
||||||
/*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r').
|
/*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r').
|
||||||
\param indentCharCount Number of indent characters for each indentation level.
|
\param indentCharCount Number of indent characters for each indentation level.
|
||||||
|
@ -35,6 +35,26 @@ RAPIDJSON_DIAG_OFF(padded)
|
|||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// WriteFlag
|
||||||
|
|
||||||
|
/*! \def RAPIDJSON_WRITE_DEFAULT_FLAGS
|
||||||
|
\ingroup RAPIDJSON_CONFIG
|
||||||
|
\brief User-defined kWriteDefaultFlags definition.
|
||||||
|
|
||||||
|
User can define this as any \c WriteFlag combinations.
|
||||||
|
*/
|
||||||
|
#ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS
|
||||||
|
#define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//! Combination of writeFlags
|
||||||
|
enum WriteFlag {
|
||||||
|
kWriteNoFlags = 0, //!< No flags are set.
|
||||||
|
kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings.
|
||||||
|
kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS
|
||||||
|
};
|
||||||
|
|
||||||
//! JSON writer
|
//! JSON writer
|
||||||
/*! Writer implements the concept Handler.
|
/*! Writer implements the concept Handler.
|
||||||
It generates JSON text by events to an output os.
|
It generates JSON text by events to an output os.
|
||||||
@ -51,7 +71,7 @@ RAPIDJSON_NAMESPACE_BEGIN
|
|||||||
\tparam StackAllocator Type of allocator for allocating memory of stack.
|
\tparam StackAllocator Type of allocator for allocating memory of stack.
|
||||||
\note implements Handler concept
|
\note implements Handler concept
|
||||||
*/
|
*/
|
||||||
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator>
|
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>
|
||||||
class Writer {
|
class Writer {
|
||||||
public:
|
public:
|
||||||
typedef typename SourceEncoding::Ch Ch;
|
typedef typename SourceEncoding::Ch Ch;
|
||||||
@ -318,8 +338,9 @@ protected:
|
|||||||
PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) & 0xF]);
|
PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) & 0xF]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ?
|
||||||
if (RAPIDJSON_UNLIKELY(!(Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
|
Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :
|
||||||
|
Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
PutUnsafe(*os_, '\"');
|
PutUnsafe(*os_, '\"');
|
||||||
|
@ -69,7 +69,10 @@ struct Foo {
|
|||||||
Reader* reader;
|
Reader* reader;
|
||||||
|
|
||||||
// writer.h
|
// writer.h
|
||||||
Writer<StringBuffer, UTF8<char>, UTF8<char>, CrtAllocator>* writer;
|
Writer<StringBuffer, UTF8<char>, UTF8<char>, CrtAllocator, 0>* writer;
|
||||||
|
|
||||||
|
// prettywriter.h
|
||||||
|
PrettyWriter<StringBuffer, UTF8<char>, UTF8<char>, CrtAllocator, 0>* prettywriter;
|
||||||
|
|
||||||
// document.h
|
// document.h
|
||||||
Value* value;
|
Value* value;
|
||||||
@ -94,6 +97,7 @@ struct Foo {
|
|||||||
#include "rapidjson/memorystream.h"
|
#include "rapidjson/memorystream.h"
|
||||||
#include "rapidjson/document.h" // -> reader.h
|
#include "rapidjson/document.h" // -> reader.h
|
||||||
#include "rapidjson/writer.h"
|
#include "rapidjson/writer.h"
|
||||||
|
#include "rapidjson/prettywriter.h"
|
||||||
#include "rapidjson/schema.h" // -> pointer.h
|
#include "rapidjson/schema.h" // -> pointer.h
|
||||||
|
|
||||||
Foo::Foo() :
|
Foo::Foo() :
|
||||||
@ -139,6 +143,9 @@ Foo::Foo() :
|
|||||||
// writer.h
|
// writer.h
|
||||||
writer(RAPIDJSON_NEW((Writer<StringBuffer>))),
|
writer(RAPIDJSON_NEW((Writer<StringBuffer>))),
|
||||||
|
|
||||||
|
// prettywriter.h
|
||||||
|
prettywriter(RAPIDJSON_NEW((PrettyWriter<StringBuffer>))),
|
||||||
|
|
||||||
// document.h
|
// document.h
|
||||||
value(RAPIDJSON_NEW(Value)),
|
value(RAPIDJSON_NEW(Value)),
|
||||||
document(RAPIDJSON_NEW(Document)),
|
document(RAPIDJSON_NEW(Document)),
|
||||||
@ -196,6 +203,9 @@ Foo::~Foo() {
|
|||||||
// writer.h
|
// writer.h
|
||||||
RAPIDJSON_DELETE(writer);
|
RAPIDJSON_DELETE(writer);
|
||||||
|
|
||||||
|
// prettywriter.h
|
||||||
|
RAPIDJSON_DELETE(prettywriter);
|
||||||
|
|
||||||
// document.h
|
// document.h
|
||||||
RAPIDJSON_DELETE(value);
|
RAPIDJSON_DELETE(value);
|
||||||
RAPIDJSON_DELETE(document);
|
RAPIDJSON_DELETE(document);
|
||||||
|
@ -347,6 +347,31 @@ TEST(Writer, InvalidEncoding) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Writer, ValidateEncoding) {
|
||||||
|
{
|
||||||
|
StringBuffer buffer;
|
||||||
|
Writer<StringBuffer, UTF8<>, UTF8<>, CrtAllocator, kWriteValidateEncodingFlag> writer(buffer);
|
||||||
|
writer.StartArray();
|
||||||
|
EXPECT_TRUE(writer.String("\x24")); // Dollar sign U+0024
|
||||||
|
EXPECT_TRUE(writer.String("\xC2\xA2")); // Cents sign U+00A2
|
||||||
|
EXPECT_TRUE(writer.String("\xE2\x82\xAC")); // Euro sign U+20AC
|
||||||
|
EXPECT_TRUE(writer.String("\xF0\x9D\x84\x9E")); // G clef sign U+1D11E
|
||||||
|
writer.EndArray();
|
||||||
|
EXPECT_STREQ("[\"\x24\",\"\xC2\xA2\",\"\xE2\x82\xAC\",\"\xF0\x9D\x84\x9E\"]", buffer.GetString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fail in decoding invalid UTF-8 sequence http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
|
||||||
|
{
|
||||||
|
StringBuffer buffer;
|
||||||
|
Writer<StringBuffer, UTF8<>, UTF8<>, CrtAllocator, kWriteValidateEncodingFlag> writer(buffer);
|
||||||
|
writer.StartArray();
|
||||||
|
EXPECT_FALSE(writer.String("\xfe"));
|
||||||
|
EXPECT_FALSE(writer.String("\xff"));
|
||||||
|
EXPECT_FALSE(writer.String("\xfe\xfe\xff\xff"));
|
||||||
|
writer.EndArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Writer, InvalidEventSequence) {
|
TEST(Writer, InvalidEventSequence) {
|
||||||
// {]
|
// {]
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user