Commit bf8fcd19 authored by miloyip@gmail.com's avatar miloyip@gmail.com

Added prettyauto example, which can handle UTF-8/UTF-16LE/UTF-16BE/UTF-32LE/UTF-32BE

Fixed a bug for using Reader with AutoUTFInputStream 

git-svn-id: https://rapidjson.googlecode.com/svn/trunk@50 c5894555-1306-4e8d-425f-1f6f381ee07c
parent 7c914a9d
...@@ -157,6 +157,11 @@ solution "example" ...@@ -157,6 +157,11 @@ solution "example"
files "../example/pretty/*" files "../example/pretty/*"
setTargetObjDir("../bin") setTargetObjDir("../bin")
project "prettyauto"
kind "ConsoleApp"
files "../example/prettyauto/*"
setTargetObjDir("../bin")
project "tutorial" project "tutorial"
kind "ConsoleApp" kind "ConsoleApp"
files "../example/tutorial/*" files "../example/tutorial/*"
......
// JSON pretty formatting example // JSON pretty formatting example
// This example can only handle UTF-8. For handling other encodings, see prettyauto example.
#include "rapidjson/reader.h" #include "rapidjson/reader.h"
#include "rapidjson/prettywriter.h" #include "rapidjson/prettywriter.h"
......
// JSON pretty formatting example
// This example can handle UTF-8/UTF-16LE/UTF-16BE/UTF-32LE/UTF-32BE.
// The input firstly convert to UTF8, and then write to the original encoding with pretty formatting.
#include "rapidjson/reader.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/filereadstream.h"
#include "rapidjson/filewritestream.h"
#include "rapidjson/encodedstream.h" // NEW
#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#endif
using namespace rapidjson;
int main(int argc, char* argv[]) {
#ifdef _WIN32
// Prevent Windows converting between CR+LF and LF
_setmode(_fileno(stdin), _O_BINARY); // NEW
_setmode(_fileno(stdout), _O_BINARY); // NEW
#endif
// Prepare reader and input stream.
//Reader reader;
GenericReader<AutoUTF<unsigned>, UTF8<> > reader; // CHANGED
char readBuffer[65536];
FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
AutoUTFInputStream<unsigned, FileReadStream> eis(is); // NEW
// Prepare writer and output stream.
char writeBuffer[65536];
FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
#if 1
// Use the same Encoding of the input. Also use BOM according to input.
typedef AutoUTFOutputStream<unsigned, FileWriteStream> OutputStream; // NEW
OutputStream eos(os, eis.GetType(), eis.HasBOM()); // NEW
PrettyWriter<OutputStream, UTF8<>, AutoUTF<unsigned> > writer(eos); // CHANGED
#else
// You may also use static bound encoding type, such as output to UTF-16LE with BOM
typedef EncodedOutputStream<UTF16LE<>,FileWriteStream> OutputStream; // NEW
OutputStream eos(os, true); // NEW
PrettyWriter<OutputStream, UTF8<>, UTF16LE<> > writer(eos); // CHANGED
#endif
// JSON reader parse from the input stream and let writer generate the output.
//if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) {
if (!reader.Parse<kParseValidateEncodingFlag>(eis, writer)) { // CHANGED
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), reader.GetParseError());
return 1;
}
return 0;
}
...@@ -83,19 +83,19 @@ public: ...@@ -83,19 +83,19 @@ public:
\param is input stream to be wrapped. \param is input stream to be wrapped.
\param type UTF encoding type if it is not detected from the stream. \param type UTF encoding type if it is not detected from the stream.
*/ */
AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(is), type_(type), hasBOM_(false) { AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) {
DetectType(is); DetectType();
static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) }; static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) };
takeFunc_ = f[type_]; takeFunc_ = f[type_];
current_ = takeFunc_(is_); current_ = takeFunc_(*is_);
} }
UTFType GetType() const { return type_; } UTFType GetType() const { return type_; }
bool HasBOM() const { return hasBOM_; } bool HasBOM() const { return hasBOM_; }
Ch Peek() const { return current_; } Ch Peek() const { return current_; }
Ch Take() { Ch c = current_; current_ = takeFunc_(is_); return c; } Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; }
size_t Tell() const { is_.Tell(); } size_t Tell() const { return is_->Tell(); }
// Not implemented // Not implemented
void Put(Ch c) { RAPIDJSON_ASSERT(false); } void Put(Ch c) { RAPIDJSON_ASSERT(false); }
...@@ -105,7 +105,7 @@ public: ...@@ -105,7 +105,7 @@ public:
private: private:
// Detect encoding type with BOM or RFC 4627 // Detect encoding type with BOM or RFC 4627
void DetectType(InputByteStream& is) { void DetectType() {
// BOM (Byte Order Mark): // BOM (Byte Order Mark):
// 00 00 FE FF UTF-32BE // 00 00 FE FF UTF-32BE
// FF FE 00 00 UTF-32LE // FF FE 00 00 UTF-32LE
...@@ -113,17 +113,17 @@ private: ...@@ -113,17 +113,17 @@ private:
// FF FE UTF-16LE // FF FE UTF-16LE
// EF BB BF UTF-8 // EF BB BF UTF-8
const unsigned char* c = (const unsigned char *)is.Peek4(); const unsigned char* c = (const unsigned char *)is_->Peek4();
if (!c) if (!c)
return; return;
unsigned bom = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); unsigned bom = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
hasBOM_ = false; hasBOM_ = false;
if (bom == 0xFFFE0000) { type_ = kUTF32BE; is.Take(); is.Take(); is.Take(); is.Take(); hasBOM_ = true; } if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
else if (bom == 0x0000FEFF) { type_ = kUTF32LE; is.Take(); is.Take(); is.Take(); is.Take(); hasBOM_ = true; } else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; is.Take(); is.Take(); hasBOM_ = true; } else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); }
else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; is.Take(); is.Take(); hasBOM_ = true; } else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); }
else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; is.Take(); is.Take(); is.Take(); hasBOM_ = true; } else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); }
// RFC 4627: Section 3 // RFC 4627: Section 3
// "Since the first two characters of a JSON text will always be ASCII // "Since the first two characters of a JSON text will always be ASCII
...@@ -161,7 +161,7 @@ private: ...@@ -161,7 +161,7 @@ private:
} }
typedef Ch (*TakeFunc)(InputByteStream& is); typedef Ch (*TakeFunc)(InputByteStream& is);
InputByteStream& is_; InputByteStream* is_;
UTFType type_; UTFType type_;
Ch current_; Ch current_;
TakeFunc takeFunc_; TakeFunc takeFunc_;
...@@ -185,7 +185,7 @@ public: ...@@ -185,7 +185,7 @@ public:
\param type UTF encoding type. \param type UTF encoding type.
\param putBOM Whether to write BOM at the beginning of the stream. \param putBOM Whether to write BOM at the beginning of the stream.
*/ */
AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(os), type_(type) { AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) {
// RUntime check whether the size of character type is sufficient. It only perform checks with assertion. // RUntime check whether the size of character type is sufficient. It only perform checks with assertion.
switch (type_) { switch (type_) {
case kUTF16LE: case kUTF16LE:
...@@ -207,8 +207,8 @@ public: ...@@ -207,8 +207,8 @@ public:
UTFType GetType() const { return type_; } UTFType GetType() const { return type_; }
void Put(Ch c) { putFunc_(os_, c); } void Put(Ch c) { putFunc_(*os_, c); }
void Flush() { os_.Flush(); } void Flush() { os_->Flush(); }
// Not implemented // Not implemented
Ch Peek() const { RAPIDJSON_ASSERT(false); } Ch Peek() const { RAPIDJSON_ASSERT(false); }
...@@ -221,12 +221,12 @@ private: ...@@ -221,12 +221,12 @@ private:
void PutBOM() { void PutBOM() {
typedef void (*PutBOMFunc)(OutputByteStream&); typedef void (*PutBOMFunc)(OutputByteStream&);
static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) }; static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) };
f[type_](os_); f[type_](*os_);
} }
typedef void (*PutFunc)(OutputByteStream&, Ch); typedef void (*PutFunc)(OutputByteStream&, Ch);
OutputByteStream& os_; OutputByteStream* os_;
UTFType type_; UTFType type_;
PutFunc putFunc_; PutFunc putFunc_;
}; };
......
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