Added transcoding support in Writer and PrettyWriter

git-svn-id: https://rapidjson.googlecode.com/svn/trunk@47 c5894555-1306-4e8d-425f-1f6f381ee07c
This commit is contained in:
miloyip@gmail.com 2011-12-03 04:17:07 +00:00
parent 8bdcd74227
commit 55587d6f62
3 changed files with 26 additions and 13 deletions

View File

@ -11,10 +11,10 @@ namespace rapidjson {
\tparam Encoding Encoding of both source strings and output. \tparam Encoding Encoding of both source strings and output.
\tparam Allocator Type of allocator for allocating memory of stack. \tparam Allocator Type of allocator for allocating memory of stack.
*/ */
template<typename Stream, typename Encoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> > template<typename Stream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> >
class PrettyWriter : public Writer<Stream, Encoding, Allocator> { class PrettyWriter : public Writer<Stream, SourceEncoding, TargetEncoding, Allocator> {
public: public:
typedef Writer<Stream, Encoding, Allocator> Base; typedef Writer<Stream, SourceEncoding, TargetEncoding, Allocator> Base;
typedef typename Base::Ch Ch; typedef typename Base::Ch Ch;
//! Constructor //! Constructor

View File

@ -23,10 +23,10 @@ namespace rapidjson {
\tparam Encoding Encoding of both source strings and output. \tparam Encoding Encoding of both source strings and output.
\implements Handler \implements Handler
*/ */
template<typename Stream, typename Encoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> > template<typename Stream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> >
class Writer { class Writer {
public: public:
typedef typename Encoding::Ch Ch; typedef typename SourceEncoding::Ch Ch;
Writer(Stream& stream, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : Writer(Stream& stream, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
stream_(stream), level_stack_(allocator, levelDepth * sizeof(Level)) {} stream_(stream), level_stack_(allocator, levelDepth * sizeof(Level)) {}
@ -166,7 +166,7 @@ protected:
} }
void WriteString(const Ch* str, SizeType length) { void WriteString(const Ch* str, SizeType length) {
static const char hexDigits[] = "0123456789ABCDEF"; static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
static const char escape[256] = { static const char escape[256] = {
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
//0 1 2 3 4 5 6 7 8 9 A B C D E F //0 1 2 3 4 5 6 7 8 9 A B C D E F
@ -180,19 +180,22 @@ protected:
}; };
stream_.Put('\"'); stream_.Put('\"');
for (const Ch* p = str; p != str + length; ++p) { GenericStringStream<SourceEncoding> is(str);
if ((sizeof(Ch) == 1 || *p < 256) && escape[(unsigned char)*p]) { while (is.Tell() < length) {
const Ch c = is.Peek();
if ((sizeof(Ch) == 1 || (unsigned)c < 256) && escape[(unsigned char)c]) {
is.Take();
stream_.Put('\\'); stream_.Put('\\');
stream_.Put(escape[(unsigned char)*p]); stream_.Put(escape[(unsigned char)c]);
if (escape[(unsigned char)*p] == 'u') { if (escape[(unsigned char)c] == 'u') {
stream_.Put('0'); stream_.Put('0');
stream_.Put('0'); stream_.Put('0');
stream_.Put(hexDigits[(*p) >> 4]); stream_.Put(hexDigits[(unsigned char)c >> 4]);
stream_.Put(hexDigits[(*p) & 0xF]); stream_.Put(hexDigits[(unsigned char)c & 0xF]);
} }
} }
else else
stream_.Put(*p); Transcoder<SourceEncoding, TargetEncoding>::Transcode(is, stream_);
} }
stream_.Put('\"'); stream_.Put('\"');
} }

View File

@ -54,3 +54,13 @@ TEST(Writer, String) {
TEST_ROUNDTRIP("[\"Hello\\u0000World\"]"); TEST_ROUNDTRIP("[\"Hello\\u0000World\"]");
TEST_ROUNDTRIP("[\"\\\"\\\\/\\b\\f\\n\\r\\t\"]"); TEST_ROUNDTRIP("[\"\\\"\\\\/\\b\\f\\n\\r\\t\"]");
} }
TEST(Writer, Transcode) {
// UTF8 -> UTF16 -> UTF8
StringStream s("{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3], \"dollar\":\"\x24\", \"cents\":\"\xC2\xA2\", \"euro\":\"\xE2\x82\xAC\", \"gclef\":\"\xF0\x9D\x84\x9E\" } ");
StringBuffer buffer;
Writer<StringBuffer, UTF16<>, UTF8<> > writer(buffer);
GenericReader<UTF8<>, UTF16<> > reader;
reader.Parse<0>(s, writer);
EXPECT_STREQ("{\"hello\":\"world\",\"t\":true,\"f\":false,\"n\":null,\"i\":123,\"pi\":3.1416,\"a\":[1,2,3],\"dollar\":\"\x24\",\"cents\":\"\xC2\xA2\",\"euro\":\"\xE2\x82\xAC\",\"gclef\":\"\xF0\x9D\x84\x9E\"}", buffer.GetString());
}