Commit 0dbcc1cf authored by Milo Yip's avatar Milo Yip

Add license and change indents from tab to space.

parent adb3974e
function setTargetObjDir(outDir) function setTargetObjDir(outDir)
for _, cfg in ipairs(configurations()) do for _, cfg in ipairs(configurations()) do
for _, plat in ipairs(platforms()) do for _, plat in ipairs(platforms()) do
local action = _ACTION or "" local action = _ACTION or ""
local prj = project() local prj = project()
--"_debug_win32_vs2008" --"_debug_win32_vs2008"
local suffix = "_" .. cfg .. "_" .. plat .. "_" .. action local suffix = "_" .. cfg .. "_" .. plat .. "_" .. action
targetPath = outDir targetPath = outDir
suffix = string.lower(suffix) suffix = string.lower(suffix)
local obj_path = "../intermediate/" .. cfg .. "/" .. action .. "/" .. prj.name local obj_path = "../intermediate/" .. cfg .. "/" .. action .. "/" .. prj.name
obj_path = string.lower(obj_path) obj_path = string.lower(obj_path)
configuration {cfg, plat} configuration {cfg, plat}
targetdir(targetPath) targetdir(targetPath)
objdir(obj_path) objdir(obj_path)
targetsuffix(suffix) targetsuffix(suffix)
end end
end end
end end
function linkLib(libBaseName) function linkLib(libBaseName)
for _, cfg in ipairs(configurations()) do for _, cfg in ipairs(configurations()) do
for _, plat in ipairs(platforms()) do for _, plat in ipairs(platforms()) do
local action = _ACTION or "" local action = _ACTION or ""
local prj = project() local prj = project()
local cfgName = cfg local cfgName = cfg
--"_debug_win32_vs2008" --"_debug_win32_vs2008"
local suffix = "_" .. cfgName .. "_" .. plat .. "_" .. action local suffix = "_" .. cfgName .. "_" .. plat .. "_" .. action
libFullName = libBaseName .. string.lower(suffix) libFullName = libBaseName .. string.lower(suffix)
configuration {cfg, plat} configuration {cfg, plat}
links(libFullName) links(libFullName)
end end
end end
end end
solution "test" solution "test"
configurations { "debug", "release" } configurations { "debug", "release" }
platforms { "x32", "x64" } platforms { "x32", "x64" }
location ("./" .. (_ACTION or "")) location ("./" .. (_ACTION or ""))
language "C++" language "C++"
flags { "ExtraWarnings" } flags { "ExtraWarnings" }
configuration "debug" configuration "debug"
defines { "DEBUG" } defines { "DEBUG" }
flags { "Symbols" } flags { "Symbols" }
configuration "release" configuration "release"
defines { "NDEBUG" } defines { "NDEBUG" }
flags { "Optimize" } flags { "Optimize" }
configuration "vs*" configuration "vs*"
defines { "_CRT_SECURE_NO_WARNINGS" } defines { "_CRT_SECURE_NO_WARNINGS" }
configuration "gmake" configuration "gmake"
buildoptions "-msse4.2 -Wall -Wextra" buildoptions "-msse4.2 -Wall -Wextra"
project "gtest" project "gtest"
kind "StaticLib" kind "StaticLib"
defines { "GTEST_HAS_PTHREAD=0" } defines { "GTEST_HAS_PTHREAD=0" }
files { files {
"../thirdparty/gtest/src/gtest-all.cc", "../thirdparty/gtest/src/gtest-all.cc",
"../thirdparty/gtest/src/**.h", "../thirdparty/gtest/src/**.h",
} }
includedirs { includedirs {
"../thirdparty/gtest/", "../thirdparty/gtest/",
"../thirdparty/gtest/include", "../thirdparty/gtest/include",
} }
setTargetObjDir("../thirdparty/lib") setTargetObjDir("../thirdparty/lib")
project "unittest" project "unittest"
kind "ConsoleApp" kind "ConsoleApp"
if _ACTION == "gmake" then if _ACTION == "gmake" then
buildoptions "-Werror -Weffc++ -Wswitch-default" buildoptions "-Werror -Weffc++ -Wswitch-default"
end end
files { files {
"../include/**.h", "../include/**.h",
"../test/unittest/**.cpp", "../test/unittest/**.cpp",
"../test/unittest/**.h", "../test/unittest/**.h",
} }
includedirs { includedirs {
"../include/", "../include/",
"../thirdparty/gtest/include/", "../thirdparty/gtest/include/",
} }
libdirs "../thirdparty/lib" libdirs "../thirdparty/lib"
setTargetObjDir("../bin") setTargetObjDir("../bin")
linkLib "gtest" linkLib "gtest"
links "gtest" links "gtest"
project "perftest" project "perftest"
kind "ConsoleApp" kind "ConsoleApp"
files { files {
"../include/**.h", "../include/**.h",
"../test/perftest/**.cpp", "../test/perftest/**.cpp",
"../test/perftest/**.c", "../test/perftest/**.c",
"../test/perftest/**.h", "../test/perftest/**.h",
} }
includedirs { includedirs {
"../include/", "../include/",
"../thirdparty/gtest/include/", "../thirdparty/gtest/include/",
"../thirdparty/", "../thirdparty/",
"../thirdparty/jsoncpp/include/", "../thirdparty/jsoncpp/include/",
"../thirdparty/libjson/", "../thirdparty/libjson/",
"../thirdparty/yajl/include/", "../thirdparty/yajl/include/",
} }
libdirs "../thirdparty/lib" libdirs "../thirdparty/lib"
setTargetObjDir("../bin") setTargetObjDir("../bin")
linkLib "gtest" linkLib "gtest"
links "gtest" links "gtest"
solution "example" solution "example"
configurations { "debug", "release" } configurations { "debug", "release" }
platforms { "x32", "x64" } platforms { "x32", "x64" }
location ("./" .. (_ACTION or "")) location ("./" .. (_ACTION or ""))
language "C++" language "C++"
flags { "ExtraWarnings" } flags { "ExtraWarnings" }
includedirs "../include/" includedirs "../include/"
configuration "debug" configuration "debug"
defines { "DEBUG" } defines { "DEBUG" }
flags { "Symbols" } flags { "Symbols" }
configuration "release" configuration "release"
defines { "NDEBUG" } defines { "NDEBUG" }
flags { "Optimize", "EnableSSE2" } flags { "Optimize", "EnableSSE2" }
configuration "vs*" configuration "vs*"
defines { "_CRT_SECURE_NO_WARNINGS" } defines { "_CRT_SECURE_NO_WARNINGS" }
configuration "gmake" configuration "gmake"
buildoptions "-Werror -Wall -Wextra -Weffc++ -Wswitch-default" buildoptions "-Werror -Wall -Wextra -Weffc++ -Wswitch-default"
local examplepaths = os.matchdirs("../example/*") local examplepaths = os.matchdirs("../example/*")
for _, examplepath in ipairs(examplepaths) do for _, examplepath in ipairs(examplepaths) do
project(path.getname(examplepath)) project(path.getname(examplepath))
kind "ConsoleApp" kind "ConsoleApp"
files(examplepath .. "/*") files(examplepath .. "/*")
setTargetObjDir("../bin") setTargetObjDir("../bin")
end end
...@@ -15,51 +15,51 @@ using namespace rapidjson; ...@@ -15,51 +15,51 @@ using namespace rapidjson;
template<typename OutputHandler> template<typename OutputHandler>
struct CapitalizeFilter { struct CapitalizeFilter {
CapitalizeFilter(OutputHandler& out) : out_(out), buffer_() {} CapitalizeFilter(OutputHandler& out) : out_(out), buffer_() {}
bool Null() { return out_.Null(); } bool Null() { return out_.Null(); }
bool Bool(bool b) { return out_.Bool(b); } bool Bool(bool b) { return out_.Bool(b); }
bool Int(int i) { return out_.Int(i); } bool Int(int i) { return out_.Int(i); }
bool Uint(unsigned u) { return out_.Uint(u); } bool Uint(unsigned u) { return out_.Uint(u); }
bool Int64(int64_t i) { return out_.Int64(i); } bool Int64(int64_t i) { return out_.Int64(i); }
bool Uint64(uint64_t u) { return out_.Uint64(u); } bool Uint64(uint64_t u) { return out_.Uint64(u); }
bool Double(double d) { return out_.Double(d); } bool Double(double d) { return out_.Double(d); }
bool String(const char* str, SizeType length, bool) { bool String(const char* str, SizeType length, bool) {
buffer_.clear(); buffer_.clear();
for (SizeType i = 0; i < length; i++) for (SizeType i = 0; i < length; i++)
buffer_.push_back(std::toupper(str[i])); buffer_.push_back(std::toupper(str[i]));
return out_.String(&buffer_.front(), length, true); // true = output handler need to copy the string return out_.String(&buffer_.front(), length, true); // true = output handler need to copy the string
} }
bool StartObject() { return out_.StartObject(); } bool StartObject() { return out_.StartObject(); }
bool EndObject(SizeType memberCount) { return out_.EndObject(memberCount); } bool EndObject(SizeType memberCount) { return out_.EndObject(memberCount); }
bool StartArray() { return out_.StartArray(); } bool StartArray() { return out_.StartArray(); }
bool EndArray(SizeType elementCount) { return out_.EndArray(elementCount); } bool EndArray(SizeType elementCount) { return out_.EndArray(elementCount); }
OutputHandler& out_; OutputHandler& out_;
std::vector<char> buffer_; std::vector<char> buffer_;
private: private:
CapitalizeFilter(const CapitalizeFilter&); CapitalizeFilter(const CapitalizeFilter&);
CapitalizeFilter& operator=(const CapitalizeFilter&); CapitalizeFilter& operator=(const CapitalizeFilter&);
}; };
int main(int, char*[]) { int main(int, char*[]) {
// Prepare JSON reader and input stream. // Prepare JSON reader and input stream.
Reader reader; Reader reader;
char readBuffer[65536]; char readBuffer[65536];
FileReadStream is(stdin, readBuffer, sizeof(readBuffer)); FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
// Prepare JSON writer and output stream. // Prepare JSON writer and output stream.
char writeBuffer[65536]; char writeBuffer[65536];
FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer)); FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
Writer<FileWriteStream> writer(os); Writer<FileWriteStream> writer(os);
// JSON reader parse from the input stream and let writer generate the output. // JSON reader parse from the input stream and let writer generate the output.
CapitalizeFilter<Writer<FileWriteStream> > filter(writer); CapitalizeFilter<Writer<FileWriteStream> > filter(writer);
if (!reader.Parse(is, filter)) { if (!reader.Parse(is, filter)) {
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode())); fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode()));
return 1; return 1;
} }
return 0; return 0;
} }
...@@ -12,21 +12,21 @@ ...@@ -12,21 +12,21 @@
using namespace rapidjson; using namespace rapidjson;
int main(int, char*[]) { int main(int, char*[]) {
// Prepare JSON reader and input stream. // Prepare JSON reader and input stream.
Reader reader; Reader reader;
char readBuffer[65536]; char readBuffer[65536];
FileReadStream is(stdin, readBuffer, sizeof(readBuffer)); FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
// Prepare JSON writer and output stream. // Prepare JSON writer and output stream.
char writeBuffer[65536]; char writeBuffer[65536];
FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer)); FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
Writer<FileWriteStream> writer(os); Writer<FileWriteStream> writer(os);
// JSON reader parse from the input stream and let writer generate the output. // JSON reader parse from the input stream and let writer generate the output.
if (!reader.Parse(is, writer)) { if (!reader.Parse(is, writer)) {
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode())); fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode()));
return 1; return 1;
} }
return 0; return 0;
} }
...@@ -18,38 +18,38 @@ RAPIDJSON_DIAG_OFF(effc++) ...@@ -18,38 +18,38 @@ RAPIDJSON_DIAG_OFF(effc++)
#endif #endif
struct MessageHandler : public BaseReaderHandler<> { struct MessageHandler : public BaseReaderHandler<> {
MessageHandler() : messages_(), state_(kExpectObjectStart), name_() {} MessageHandler() : messages_(), state_(kExpectObjectStart), name_() {}
bool StartObject() { bool StartObject() {
switch (state_) { switch (state_) {
case kExpectObjectStart: case kExpectObjectStart:
state_ = kExpectNameOrObjectEnd; state_ = kExpectNameOrObjectEnd;
return true; return true;
default: default:
return false; return false;
} }
} }
bool String(const char* str, SizeType length, bool) { bool String(const char* str, SizeType length, bool) {
switch (state_) { switch (state_) {
case kExpectNameOrObjectEnd: case kExpectNameOrObjectEnd:
name_ = string(str, length); name_ = string(str, length);
state_ = kExpectValue; state_ = kExpectValue;
return true; return true;
case kExpectValue: case kExpectValue:
messages_.insert(MessageMap::value_type(name_, string(str, length))); messages_.insert(MessageMap::value_type(name_, string(str, length)));
state_ = kExpectNameOrObjectEnd; state_ = kExpectNameOrObjectEnd;
return true; return true;
default: default:
return false; return false;
} }
} }
bool EndObject(SizeType) { return state_ == kExpectNameOrObjectEnd; } bool EndObject(SizeType) { return state_ == kExpectNameOrObjectEnd; }
bool Default() { return false; } // All other events are invalid. bool Default() { return false; } // All other events are invalid.
MessageMap messages_; MessageMap messages_;
enum State { enum State {
kExpectObjectStart, kExpectObjectStart,
kExpectNameOrObjectEnd, kExpectNameOrObjectEnd,
...@@ -66,30 +66,30 @@ void ParseMessages(const char* json, MessageMap& messages) { ...@@ -66,30 +66,30 @@ void ParseMessages(const char* json, MessageMap& messages) {
Reader reader; Reader reader;
MessageHandler handler; MessageHandler handler;
StringStream ss(json); StringStream ss(json);
if (reader.Parse(ss, handler)) if (reader.Parse(ss, handler))
messages.swap(handler.messages_); // Only change it if success. messages.swap(handler.messages_); // Only change it if success.
else { else {
ParseErrorCode e = reader.GetParseErrorCode(); ParseErrorCode e = reader.GetParseErrorCode();
size_t o = reader.GetErrorOffset(); size_t o = reader.GetErrorOffset();
cout << "Error: " << GetParseError_En(e) << endl;; cout << "Error: " << GetParseError_En(e) << endl;;
cout << " at offset " << o << " near '" << string(json).substr(o, 10) << "...'" << endl; cout << " at offset " << o << " near '" << string(json).substr(o, 10) << "...'" << endl;
} }
} }
int main() { int main() {
MessageMap messages; MessageMap messages;
const char* json1 = "{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\" }"; const char* json1 = "{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\" }";
cout << json1 << endl; cout << json1 << endl;
ParseMessages(json1, messages); ParseMessages(json1, messages);
for (MessageMap::const_iterator itr = messages.begin(); itr != messages.end(); ++itr) for (MessageMap::const_iterator itr = messages.begin(); itr != messages.end(); ++itr)
cout << itr->first << ": " << itr->second << endl; cout << itr->first << ": " << itr->second << endl;
cout << endl << "Parse a JSON with invalid schema." << endl; cout << endl << "Parse a JSON with invalid schema." << endl;
const char* json2 = "{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\", \"foo\" : {} }"; const char* json2 = "{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\", \"foo\" : {} }";
cout << json2 << endl; cout << json2 << endl;
ParseMessages(json2, messages); ParseMessages(json2, messages);
return 0; return 0;
} }
...@@ -10,21 +10,21 @@ ...@@ -10,21 +10,21 @@
using namespace rapidjson; using namespace rapidjson;
int main(int, char*[]) { int main(int, char*[]) {
// Prepare reader and input stream. // Prepare reader and input stream.
Reader reader; Reader reader;
char readBuffer[65536]; char readBuffer[65536];
FileReadStream is(stdin, readBuffer, sizeof(readBuffer)); FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
// Prepare writer and output stream. // Prepare writer and output stream.
char writeBuffer[65536]; char writeBuffer[65536];
FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer)); FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
PrettyWriter<FileWriteStream> writer(os); PrettyWriter<FileWriteStream> writer(os);
// JSON reader parse from the input stream and let writer generate the output. // JSON reader parse from the input stream and let writer generate the output.
if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) { if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) {
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode())); fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode()));
return 1; return 1;
} }
return 0; return 0;
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include "rapidjson/prettywriter.h" #include "rapidjson/prettywriter.h"
#include "rapidjson/filereadstream.h" #include "rapidjson/filereadstream.h"
#include "rapidjson/filewritestream.h" #include "rapidjson/filewritestream.h"
#include "rapidjson/encodedstream.h" // NEW #include "rapidjson/encodedstream.h" // NEW
#include "rapidjson/error/en.h" #include "rapidjson/error/en.h"
#ifdef _WIN32 #ifdef _WIN32
#include <fcntl.h> #include <fcntl.h>
...@@ -17,40 +17,40 @@ using namespace rapidjson; ...@@ -17,40 +17,40 @@ using namespace rapidjson;
int main(int, char*[]) { int main(int, char*[]) {
#ifdef _WIN32 #ifdef _WIN32
// Prevent Windows converting between CR+LF and LF // Prevent Windows converting between CR+LF and LF
_setmode(_fileno(stdin), _O_BINARY); // NEW _setmode(_fileno(stdin), _O_BINARY); // NEW
_setmode(_fileno(stdout), _O_BINARY); // NEW _setmode(_fileno(stdout), _O_BINARY); // NEW
#endif #endif
// Prepare reader and input stream. // Prepare reader and input stream.
//Reader reader; //Reader reader;
GenericReader<AutoUTF<unsigned>, UTF8<> > reader; // CHANGED GenericReader<AutoUTF<unsigned>, UTF8<> > reader; // CHANGED
char readBuffer[65536]; char readBuffer[65536];
FileReadStream is(stdin, readBuffer, sizeof(readBuffer)); FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
AutoUTFInputStream<unsigned, FileReadStream> eis(is); // NEW AutoUTFInputStream<unsigned, FileReadStream> eis(is); // NEW
// Prepare writer and output stream. // Prepare writer and output stream.
char writeBuffer[65536]; char writeBuffer[65536];
FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer)); FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
#if 1 #if 1
// Use the same Encoding of the input. Also use BOM according to input. // Use the same Encoding of the input. Also use BOM according to input.
typedef AutoUTFOutputStream<unsigned, FileWriteStream> OutputStream; // NEW typedef AutoUTFOutputStream<unsigned, FileWriteStream> OutputStream; // NEW
OutputStream eos(os, eis.GetType(), eis.HasBOM()); // NEW OutputStream eos(os, eis.GetType(), eis.HasBOM()); // NEW
PrettyWriter<OutputStream, UTF8<>, AutoUTF<unsigned> > writer(eos); // CHANGED PrettyWriter<OutputStream, UTF8<>, AutoUTF<unsigned> > writer(eos); // CHANGED
#else #else
// You may also use static bound encoding type, such as output to UTF-16LE with BOM // You may also use static bound encoding type, such as output to UTF-16LE with BOM
typedef EncodedOutputStream<UTF16LE<>,FileWriteStream> OutputStream; // NEW typedef EncodedOutputStream<UTF16LE<>,FileWriteStream> OutputStream; // NEW
OutputStream eos(os, true); // NEW OutputStream eos(os, true); // NEW
PrettyWriter<OutputStream, UTF8<>, UTF16LE<> > writer(eos); // CHANGED PrettyWriter<OutputStream, UTF8<>, UTF16LE<> > writer(eos); // CHANGED
#endif #endif
// JSON reader parse from the input stream and let writer generate the output. // JSON reader parse from the input stream and let writer generate the output.
//if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) { //if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) {
if (!reader.Parse<kParseValidateEncodingFlag>(eis, writer)) { // CHANGED if (!reader.Parse<kParseValidateEncodingFlag>(eis, writer)) { // CHANGED
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode())); fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode()));
return 1; return 1;
} }
return 0; return 0;
} }
// Serialize example // Serialize example
// This example shows writing JSON string with writer directly. // This example shows writing JSON string with writer directly.
#include "rapidjson/prettywriter.h" // for stringify JSON #include "rapidjson/prettywriter.h" // for stringify JSON
#include "rapidjson/filestream.h" // wrapper of C stream for prettywriter as output #include "rapidjson/filestream.h" // wrapper of C stream for prettywriter as output
#include <cstdio> #include <cstdio>
#include <string> #include <string>
#include <vector> #include <vector>
...@@ -11,23 +11,23 @@ using namespace rapidjson; ...@@ -11,23 +11,23 @@ using namespace rapidjson;
class Person { class Person {
public: public:
Person(const std::string& name, unsigned age) : name_(name), age_(age) {} Person(const std::string& name, unsigned age) : name_(name), age_(age) {}
virtual ~Person(); virtual ~Person();
protected: protected:
template <typename Writer> template <typename Writer>
void Serialize(Writer& writer) const { void Serialize(Writer& writer) const {
// This base class just write out name-value pairs, without wrapping within an object. // This base class just write out name-value pairs, without wrapping within an object.
writer.String("name"); writer.String("name");
writer.String(name_.c_str(), (SizeType)name_.length()); // Suppling length of string is faster. writer.String(name_.c_str(), (SizeType)name_.length()); // Suppling length of string is faster.
writer.String("age"); writer.String("age");
writer.Uint(age_); writer.Uint(age_);
} }
private: private:
std::string name_; std::string name_;
unsigned age_; unsigned age_;
}; };
Person::~Person() { Person::~Person() {
...@@ -35,115 +35,115 @@ Person::~Person() { ...@@ -35,115 +35,115 @@ Person::~Person() {
class Education { class Education {
public: public:
Education(const std::string& school, double GPA) : school_(school), GPA_(GPA) {} Education(const std::string& school, double GPA) : school_(school), GPA_(GPA) {}
template <typename Writer> template <typename Writer>
void Serialize(Writer& writer) const { void Serialize(Writer& writer) const {
writer.StartObject(); writer.StartObject();
writer.String("school"); writer.String("school");
writer.String(school_.c_str(), (SizeType)school_.length()); writer.String(school_.c_str(), (SizeType)school_.length());
writer.String("GPA"); writer.String("GPA");
writer.Double(GPA_); writer.Double(GPA_);
writer.EndObject(); writer.EndObject();
} }
private: private:
std::string school_; std::string school_;
double GPA_; double GPA_;
}; };
class Dependent : public Person { class Dependent : public Person {
public: public:
Dependent(const std::string& name, unsigned age, Education* education = 0) : Person(name, age), education_(education) {} Dependent(const std::string& name, unsigned age, Education* education = 0) : Person(name, age), education_(education) {}
Dependent(const Dependent& rhs) : Person(rhs), education_(0) { education_ = (rhs.education_ == 0) ? 0 : new Education(*rhs.education_); } Dependent(const Dependent& rhs) : Person(rhs), education_(0) { education_ = (rhs.education_ == 0) ? 0 : new Education(*rhs.education_); }
virtual ~Dependent(); virtual ~Dependent();
Dependent& operator=(const Dependent& rhs) { Dependent& operator=(const Dependent& rhs) {
if (this == &rhs) if (this == &rhs)
return *this; return *this;
delete education_; delete education_;
education_ = (rhs.education_ == 0) ? 0 : new Education(*rhs.education_); education_ = (rhs.education_ == 0) ? 0 : new Education(*rhs.education_);
return *this; return *this;
} }
template <typename Writer> template <typename Writer>
void Serialize(Writer& writer) const { void Serialize(Writer& writer) const {
writer.StartObject(); writer.StartObject();
Person::Serialize(writer); Person::Serialize(writer);
writer.String("education"); writer.String("education");
if (education_) if (education_)
education_->Serialize(writer); education_->Serialize(writer);
else else
writer.Null(); writer.Null();
writer.EndObject(); writer.EndObject();
} }
private: private:
Education *education_; Education *education_;
}; };
Dependent::~Dependent() { Dependent::~Dependent() {
delete education_; delete education_;
} }
class Employee : public Person { class Employee : public Person {
public: public:
Employee(const std::string& name, unsigned age, bool married) : Person(name, age), dependents_(), married_(married) {} Employee(const std::string& name, unsigned age, bool married) : Person(name, age), dependents_(), married_(married) {}
virtual ~Employee(); virtual ~Employee();
void AddDependent(const Dependent& dependent) { void AddDependent(const Dependent& dependent) {
dependents_.push_back(dependent); dependents_.push_back(dependent);
} }
template <typename Writer> template <typename Writer>
void Serialize(Writer& writer) const { void Serialize(Writer& writer) const {
writer.StartObject(); writer.StartObject();
Person::Serialize(writer); Person::Serialize(writer);
writer.String("married"); writer.String("married");
writer.Bool(married_); writer.Bool(married_);
writer.String(("dependents")); writer.String(("dependents"));
writer.StartArray(); writer.StartArray();
for (std::vector<Dependent>::const_iterator dependentItr = dependents_.begin(); dependentItr != dependents_.end(); ++dependentItr) for (std::vector<Dependent>::const_iterator dependentItr = dependents_.begin(); dependentItr != dependents_.end(); ++dependentItr)
dependentItr->Serialize(writer); dependentItr->Serialize(writer);
writer.EndArray(); writer.EndArray();
writer.EndObject(); writer.EndObject();
} }
private: private:
std::vector<Dependent> dependents_; std::vector<Dependent> dependents_;
bool married_; bool married_;
}; };
Employee::~Employee() { Employee::~Employee() {
} }
int main(int, char*[]) { int main(int, char*[]) {
std::vector<Employee> employees; std::vector<Employee> employees;
employees.push_back(Employee("Milo YIP", 34, true)); employees.push_back(Employee("Milo YIP", 34, true));
employees.back().AddDependent(Dependent("Lua YIP", 3, new Education("Happy Kindergarten", 3.5))); employees.back().AddDependent(Dependent("Lua YIP", 3, new Education("Happy Kindergarten", 3.5)));
employees.back().AddDependent(Dependent("Mio YIP", 1)); employees.back().AddDependent(Dependent("Mio YIP", 1));
employees.push_back(Employee("Percy TSE", 30, false)); employees.push_back(Employee("Percy TSE", 30, false));
FileStream s(stdout); FileStream s(stdout);
PrettyWriter<FileStream> writer(s); // Can also use Writer for condensed formatting PrettyWriter<FileStream> writer(s); // Can also use Writer for condensed formatting
writer.StartArray(); writer.StartArray();
for (std::vector<Employee>::const_iterator employeeItr = employees.begin(); employeeItr != employees.end(); ++employeeItr) for (std::vector<Employee>::const_iterator employeeItr = employees.begin(); employeeItr != employees.end(); ++employeeItr)
employeeItr->Serialize(writer); employeeItr->Serialize(writer);
writer.EndArray(); writer.EndArray();
return 0; return 0;
} }
...@@ -9,21 +9,21 @@ ...@@ -9,21 +9,21 @@
using namespace rapidjson; using namespace rapidjson;
int main() { int main() {
// 1. Parse a JSON string into DOM. // 1. Parse a JSON string into DOM.
const char* json = "{\"project\":\"rapidjson\",\"stars\":10}"; const char* json = "{\"project\":\"rapidjson\",\"stars\":10}";
Document d; Document d;
d.Parse(json); d.Parse(json);
// 2. Modify it by DOM. // 2. Modify it by DOM.
Value& s = d["stars"]; Value& s = d["stars"];
s.SetInt(s.GetInt() + 1); s.SetInt(s.GetInt() + 1);
// 3. Stringify the DOM // 3. Stringify the DOM
StringBuffer buffer; StringBuffer buffer;
Writer<StringBuffer> writer(buffer); Writer<StringBuffer> writer(buffer);
d.Accept(writer); d.Accept(writer);
// Output {"project":"rapidjson","stars":11} // Output {"project":"rapidjson","stars":11}
std::cout << buffer.GetString() << std::endl; std::cout << buffer.GetString() << std::endl;
return 0; return 0;
} }
...@@ -5,21 +5,21 @@ using namespace rapidjson; ...@@ -5,21 +5,21 @@ using namespace rapidjson;
using namespace std; using namespace std;
struct MyHandler { struct MyHandler {
bool Null() { cout << "Null()" << endl; return true; } bool Null() { cout << "Null()" << endl; return true; }
bool Bool(bool b) { cout << "Bool(" << boolalpha << b << ")" << endl; return true; } bool Bool(bool b) { cout << "Bool(" << boolalpha << b << ")" << endl; return true; }
bool Int(int i) { cout << "Int(" << i << ")" << endl; return true; } bool Int(int i) { cout << "Int(" << i << ")" << endl; return true; }
bool Uint(unsigned u) { cout << "Uint(" << u << ")" << endl; return true; } bool Uint(unsigned u) { cout << "Uint(" << u << ")" << endl; return true; }
bool Int64(int64_t i) { cout << "Int64(" << i << ")" << endl; return true; } bool Int64(int64_t i) { cout << "Int64(" << i << ")" << endl; return true; }
bool Uint64(uint64_t u) { cout << "Uint64(" << u << ")" << endl; return true; } bool Uint64(uint64_t u) { cout << "Uint64(" << u << ")" << endl; return true; }
bool Double(double d) { cout << "Double(" << d << ")" << endl; return true; } bool Double(double d) { cout << "Double(" << d << ")" << endl; return true; }
bool String(const char* str, SizeType length, bool copy) { bool String(const char* str, SizeType length, bool copy) {
cout << "String(" << str << ", " << length << ", " << boolalpha << copy << ")" << endl; cout << "String(" << str << ", " << length << ", " << boolalpha << copy << ")" << endl;
return true; return true;
} }
bool StartObject() { cout << "StartObject()" << endl; return true; } bool StartObject() { cout << "StartObject()" << endl; return true; }
bool EndObject(SizeType memberCount) { cout << "EndObject(" << memberCount << ")" << endl; return true; } bool EndObject(SizeType memberCount) { cout << "EndObject(" << memberCount << ")" << endl; return true; }
bool StartArray() { cout << "StartArray()" << endl; return true; } bool StartArray() { cout << "StartArray()" << endl; return true; }
bool EndArray(SizeType elementCount) { cout << "EndArray(" << elementCount << ")" << endl; return true; } bool EndArray(SizeType elementCount) { cout << "EndArray(" << elementCount << ")" << endl; return true; }
}; };
int main() { int main() {
...@@ -28,7 +28,7 @@ int main() { ...@@ -28,7 +28,7 @@ int main() {
MyHandler handler; MyHandler handler;
Reader reader; Reader reader;
StringStream ss(json); StringStream ss(json);
reader.Parse(ss, handler); reader.Parse(ss, handler);
return 0; return 0;
} }
...@@ -31,5 +31,5 @@ int main() { ...@@ -31,5 +31,5 @@ int main() {
cout << s.GetString() << endl; cout << s.GetString() << endl;
return 0; return 0;
} }
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
// Copyright (C) 2011 Milo Yip
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef RAPIDJSON_ERROR_EN_H__ #ifndef RAPIDJSON_ERROR_EN_H__
#define RAPIDJSON_ERROR_EN_H__ #define RAPIDJSON_ERROR_EN_H__
...@@ -7,43 +27,43 @@ namespace rapidjson { ...@@ -7,43 +27,43 @@ namespace rapidjson {
//! Maps error code of parsing into error message. //! Maps error code of parsing into error message.
/*! /*!
\param parseErrorCode Error code obtained in parsing. \param parseErrorCode Error code obtained in parsing.
\return the error message. \return the error message.
\note User can make a copy of this function for localization. \note User can make a copy of this function for localization.
Using switch-case is safer for future modification of error codes. Using switch-case is safer for future modification of error codes.
*/ */
inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) { inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {
switch (parseErrorCode) { switch (parseErrorCode) {
case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty.");
case kParseErrorDocumentRootNotObjectOrArray: return RAPIDJSON_ERROR_STRING("The document root must be either object or array."); case kParseErrorDocumentRootNotObjectOrArray: return RAPIDJSON_ERROR_STRING("The document root must be either object or array.");
case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not follow by other values."); case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not follow by other values.");
case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member."); case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member."); case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member."); case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element."); case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string."); case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid."); case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid.");
case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string."); case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string.");
case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string."); case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string.");
case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string."); case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string.");
case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double."); case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double.");
case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number."); case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number.");
case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number."); case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number.");
case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
default: default:
return RAPIDJSON_ERROR_STRING("Unknown error."); return RAPIDJSON_ERROR_STRING("Unknown error.");
} }
} }
} // namespace rapidjson } // namespace rapidjson
......
// Copyright (C) 2011 Milo Yip
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef RAPIDJSON_ERROR_ERROR_H__ #ifndef RAPIDJSON_ERROR_ERROR_H__
#define RAPIDJSON_ERROR_ERROR_H__ #define RAPIDJSON_ERROR_ERROR_H__
...@@ -6,8 +26,8 @@ ...@@ -6,8 +26,8 @@
//! Character type of error messages. //! Character type of error messages.
/*! The default charater type is char. /*! The default charater type is char.
On Windows, user can define this macro as TCHAR for supporting both On Windows, user can define this macro as TCHAR for supporting both
unicode/non-unicode settings. unicode/non-unicode settings.
*/ */
#ifndef RAPIDJSON_ERROR_CHARTYPE #ifndef RAPIDJSON_ERROR_CHARTYPE
#define RAPIDJSON_ERROR_CHARTYPE char #define RAPIDJSON_ERROR_CHARTYPE char
...@@ -18,8 +38,8 @@ ...@@ -18,8 +38,8 @@
//! Macro for converting string literial to RAPIDJSON_ERROR_CHARTYPE[]. //! Macro for converting string literial to RAPIDJSON_ERROR_CHARTYPE[].
/*! By default this conversion macro does nothing. /*! By default this conversion macro does nothing.
On Windows, user can define this macro as _T(x) for supporting both On Windows, user can define this macro as _T(x) for supporting both
unicode/non-unicode settings. unicode/non-unicode settings.
*/ */
#ifndef RAPIDJSON_ERROR_STRING #ifndef RAPIDJSON_ERROR_STRING
#define RAPIDJSON_ERROR_STRING(x) x #define RAPIDJSON_ERROR_STRING(x) x
...@@ -34,85 +54,85 @@ namespace rapidjson { ...@@ -34,85 +54,85 @@ namespace rapidjson {
/*! \see GenericReader::Parse, GenericReader::GetParseErrorCode /*! \see GenericReader::Parse, GenericReader::GetParseErrorCode
*/ */
enum ParseErrorCode { enum ParseErrorCode {
kParseErrorNone = 0, //!< No error. kParseErrorNone = 0, //!< No error.
kParseErrorDocumentEmpty, //!< The document is empty. kParseErrorDocumentEmpty, //!< The document is empty.
kParseErrorDocumentRootNotObjectOrArray, //!< The document root must be either object or array. kParseErrorDocumentRootNotObjectOrArray, //!< The document root must be either object or array.
kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values. kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values.
kParseErrorValueInvalid, //!< Invalid value. kParseErrorValueInvalid, //!< Invalid value.
kParseErrorObjectMissName, //!< Missing a name for object member. kParseErrorObjectMissName, //!< Missing a name for object member.
kParseErrorObjectMissColon, //!< Missing a colon after a name of object member. kParseErrorObjectMissColon, //!< Missing a colon after a name of object member.
kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member. kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member.
kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element. kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element.
kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string. kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string.
kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid. kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid.
kParseErrorStringEscapeInvalid, //!< Invalid escape character in string. kParseErrorStringEscapeInvalid, //!< Invalid escape character in string.
kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string. kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string.
kParseErrorStringInvalidEncoding, //!< Invalid encoding in string. kParseErrorStringInvalidEncoding, //!< Invalid encoding in string.
kParseErrorNumberTooBig, //!< Number too big to be stored in double. kParseErrorNumberTooBig, //!< Number too big to be stored in double.
kParseErrorNumberMissFraction, //!< Miss fraction part in number. kParseErrorNumberMissFraction, //!< Miss fraction part in number.
kParseErrorNumberMissExponent, //!< Miss exponent in number. kParseErrorNumberMissExponent, //!< Miss exponent in number.
kParseErrorTermination, //!< Parsing was terminated. kParseErrorTermination, //!< Parsing was terminated.
kParseErrorUnspecificSyntaxError, //!< Unspecific syntax error. kParseErrorUnspecificSyntaxError, //!< Unspecific syntax error.
}; };
//! Result of parsing (wraps ParseErrorCode) //! Result of parsing (wraps ParseErrorCode)
/*! /*!
\code \code
Document doc; Document doc;
ParseResult ok = doc.Parse("[42]"); ParseResult ok = doc.Parse("[42]");
if (!ok) { if (!ok) {
fprintf(stderr, "JSON parse error: %s (%u)", fprintf(stderr, "JSON parse error: %s (%u)",
GetParseError_En(ok.Code()), ok.Offset()); GetParseError_En(ok.Code()), ok.Offset());
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
\endcode \endcode
\see GenericReader::Parse, GenericDocument::Parse \see GenericReader::Parse, GenericDocument::Parse
*/ */
struct ParseResult { struct ParseResult {
//! Default constructor, no error. //! Default constructor, no error.
ParseResult() : code_(kParseErrorNone), offset_(0) {} ParseResult() : code_(kParseErrorNone), offset_(0) {}
//! Constructor to set an error. //! Constructor to set an error.
ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {} ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {}
//! Get the error code. //! Get the error code.
ParseErrorCode Code() const { return code_; } ParseErrorCode Code() const { return code_; }
//! Get the error offset, if \ref IsError(), 0 otherwise. //! Get the error offset, if \ref IsError(), 0 otherwise.
size_t Offset() const { return offset_; } size_t Offset() const { return offset_; }
//! Conversion to \c bool, returns \c true, iff !\ref IsError(). //! Conversion to \c bool, returns \c true, iff !\ref IsError().
operator bool() const { return !IsError(); } operator bool() const { return !IsError(); }
//! Whether the result is an error. //! Whether the result is an error.
bool IsError() const { return code_ != kParseErrorNone; } bool IsError() const { return code_ != kParseErrorNone; }
bool operator==(const ParseResult& that) const { return code_ == that.code_; } bool operator==(const ParseResult& that) const { return code_ == that.code_; }
bool operator==(ParseErrorCode code) const { return code_ == code; } bool operator==(ParseErrorCode code) const { return code_ == code; }
friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; } friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; }
//! Reset error code. //! Reset error code.
void Clear() { Set(kParseErrorNone); } void Clear() { Set(kParseErrorNone); }
//! Update error code and offset. //! Update error code and offset.
void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; } void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; }
private: private:
ParseErrorCode code_; ParseErrorCode code_;
size_t offset_; size_t offset_;
}; };
//! Function pointer type of GetParseError(). //! Function pointer type of GetParseError().
/*! This is the prototype for GetParseError_X(), where X is a locale. /*! This is the prototype for GetParseError_X(), where X is a locale.
User can dynamically change locale in runtime, e.g.: User can dynamically change locale in runtime, e.g.:
\code \code
GetParseErrorFunc GetParseError = GetParseError_En; // or whatever GetParseErrorFunc GetParseError = GetParseError_En; // or whatever
const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode()); const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode());
\endcode \endcode
*/ */
......
// Copyright (C) 2011 Milo Yip
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef RAPIDJSON_FILEREADSTREAM_H_ #ifndef RAPIDJSON_FILEREADSTREAM_H_
#define RAPIDJSON_FILEREADSTREAM_H_ #define RAPIDJSON_FILEREADSTREAM_H_
...@@ -8,65 +28,65 @@ namespace rapidjson { ...@@ -8,65 +28,65 @@ namespace rapidjson {
//! File byte stream for input using fread(). //! File byte stream for input using fread().
/*! /*!
\note implements Stream concept \note implements Stream concept
*/ */
class FileReadStream { class FileReadStream {
public: public:
typedef char Ch; //!< Character type (byte). typedef char Ch; //!< Character type (byte).
//! Constructor. //! Constructor.
/*! /*!
\param fp File pointer opened for read. \param fp File pointer opened for read.
\param buffer user-supplied buffer. \param buffer user-supplied buffer.
\param bufferSize size of buffer in bytes. Must >=4 bytes. \param bufferSize size of buffer in bytes. Must >=4 bytes.
*/ */
FileReadStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { FileReadStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
RAPIDJSON_ASSERT(fp_ != 0); RAPIDJSON_ASSERT(fp_ != 0);
RAPIDJSON_ASSERT(bufferSize >= 4); RAPIDJSON_ASSERT(bufferSize >= 4);
Read(); Read();
} }
Ch Peek() const { return *current_; } Ch Peek() const { return *current_; }
Ch Take() { Ch c = *current_; Read(); return c; } Ch Take() { Ch c = *current_; Read(); return c; }
size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); } size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
// Not implemented // Not implemented
void Put(Ch) { RAPIDJSON_ASSERT(false); } void Put(Ch) { RAPIDJSON_ASSERT(false); }
void Flush() { RAPIDJSON_ASSERT(false); } void Flush() { RAPIDJSON_ASSERT(false); }
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
// For encoding detection only. // For encoding detection only.
const Ch* Peek4() const { const Ch* Peek4() const {
return (current_ + 4 <= bufferLast_) ? current_ : 0; return (current_ + 4 <= bufferLast_) ? current_ : 0;
} }
private: private:
void Read() { void Read() {
if (current_ < bufferLast_) if (current_ < bufferLast_)
++current_; ++current_;
else if (!eof_) { else if (!eof_) {
count_ += readCount_; count_ += readCount_;
readCount_ = fread(buffer_, 1, bufferSize_, fp_); readCount_ = fread(buffer_, 1, bufferSize_, fp_);
bufferLast_ = buffer_ + readCount_ - 1; bufferLast_ = buffer_ + readCount_ - 1;
current_ = buffer_; current_ = buffer_;
if (readCount_ < bufferSize_) { if (readCount_ < bufferSize_) {
buffer_[readCount_] = '\0'; buffer_[readCount_] = '\0';
++bufferLast_; ++bufferLast_;
eof_ = true; eof_ = true;
} }
} }
} }
FILE* fp_; FILE* fp_;
Ch *buffer_; Ch *buffer_;
size_t bufferSize_; size_t bufferSize_;
Ch *bufferLast_; Ch *bufferLast_;
Ch *current_; Ch *current_;
size_t readCount_; size_t readCount_;
size_t count_; //!< Number of characters read size_t count_; //!< Number of characters read
bool eof_; bool eof_;
}; };
} // namespace rapidjson } // namespace rapidjson
......
// Copyright (C) 2011 Milo Yip
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef RAPIDJSON_FILESTREAM_H_ #ifndef RAPIDJSON_FILESTREAM_H_
#define RAPIDJSON_FILESTREAM_H_ #define RAPIDJSON_FILESTREAM_H_
...@@ -8,44 +28,44 @@ namespace rapidjson { ...@@ -8,44 +28,44 @@ namespace rapidjson {
//! (Depreciated) Wrapper of C file stream for input or output. //! (Depreciated) Wrapper of C file stream for input or output.
/*! /*!
This simple wrapper does not check the validity of the stream. This simple wrapper does not check the validity of the stream.
\note implements Stream concept \note implements Stream concept
\note deprecated: This was only for basic testing in version 0.1, it is found that the performance is very low by using fgetc(). Use FileReadStream instead. \note deprecated: This was only for basic testing in version 0.1, it is found that the performance is very low by using fgetc(). Use FileReadStream instead.
*/ */
class FileStream { class FileStream {
public: public:
typedef char Ch; //!< Character type. Only support char. typedef char Ch; //!< Character type. Only support char.
FileStream(FILE* fp) : fp_(fp), current_('\0'), count_(0) { Read(); } FileStream(FILE* fp) : fp_(fp), current_('\0'), count_(0) { Read(); }
char Peek() const { return current_; } char Peek() const { return current_; }
char Take() { char c = current_; Read(); return c; } char Take() { char c = current_; Read(); return c; }
size_t Tell() const { return count_; } size_t Tell() const { return count_; }
void Put(char c) { fputc(c, fp_); } void Put(char c) { fputc(c, fp_); }
void Flush() { fflush(fp_); } void Flush() { fflush(fp_); }
// Not implemented // Not implemented
char* PutBegin() { return 0; } char* PutBegin() { return 0; }
size_t PutEnd(char*) { return 0; } size_t PutEnd(char*) { return 0; }
private: private:
// Prohibit copy constructor & assignment operator. // Prohibit copy constructor & assignment operator.
FileStream(const FileStream&); FileStream(const FileStream&);
FileStream& operator=(const FileStream&); FileStream& operator=(const FileStream&);
void Read() { void Read() {
RAPIDJSON_ASSERT(fp_ != 0); RAPIDJSON_ASSERT(fp_ != 0);
int c = fgetc(fp_); int c = fgetc(fp_);
if (c != EOF) { if (c != EOF) {
current_ = (char)c; current_ = (char)c;
count_++; count_++;
} }
else if (current_ != '\0') else if (current_ != '\0')
current_ = '\0'; current_ = '\0';
} }
FILE* fp_; FILE* fp_;
char current_; char current_;
size_t count_; size_t count_;
}; };
} // namespace rapidjson } // namespace rapidjson
......
// Copyright (C) 2011 Milo Yip
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef RAPIDJSON_FILEWRITESTREAM_H_ #ifndef RAPIDJSON_FILEWRITESTREAM_H_
#define RAPIDJSON_FILEWRITESTREAM_H_ #define RAPIDJSON_FILEWRITESTREAM_H_
...@@ -8,68 +28,68 @@ namespace rapidjson { ...@@ -8,68 +28,68 @@ namespace rapidjson {
//! Wrapper of C file stream for input using fread(). //! Wrapper of C file stream for input using fread().
/*! /*!
\note implements Stream concept \note implements Stream concept
*/ */
class FileWriteStream { class FileWriteStream {
public: public:
typedef char Ch; //!< Character type. Only support char. typedef char Ch; //!< Character type. Only support char.
FileWriteStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { FileWriteStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) {
RAPIDJSON_ASSERT(fp_ != 0); RAPIDJSON_ASSERT(fp_ != 0);
} }
void Put(char c) { void Put(char c) {
if (current_ >= bufferEnd_) if (current_ >= bufferEnd_)
Flush(); Flush();
*current_++ = c; *current_++ = c;
} }
void PutN(char c, size_t n) { void PutN(char c, size_t n) {
size_t avail = static_cast<size_t>(bufferEnd_ - current_); size_t avail = static_cast<size_t>(bufferEnd_ - current_);
while (n > avail) { while (n > avail) {
memset(current_, c, avail); memset(current_, c, avail);
current_ += avail; current_ += avail;
Flush(); Flush();
n -= avail; n -= avail;
avail = static_cast<size_t>(bufferEnd_ - current_); avail = static_cast<size_t>(bufferEnd_ - current_);
} }
if (n > 0) { if (n > 0) {
memset(current_, c, n); memset(current_, c, n);
current_ += n; current_ += n;
} }
} }
void Flush() { void Flush() {
if (current_ != buffer_) { if (current_ != buffer_) {
fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_); fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
current_ = buffer_; current_ = buffer_;
} }
} }
// Not implemented // Not implemented
char Peek() const { RAPIDJSON_ASSERT(false); return 0; } char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
char Take() { RAPIDJSON_ASSERT(false); return 0; } char Take() { RAPIDJSON_ASSERT(false); return 0; }
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
private: private:
// Prohibit copy constructor & assignment operator. // Prohibit copy constructor & assignment operator.
FileWriteStream(const FileWriteStream&); FileWriteStream(const FileWriteStream&);
FileWriteStream& operator=(const FileWriteStream&); FileWriteStream& operator=(const FileWriteStream&);
FILE* fp_; FILE* fp_;
char *buffer_; char *buffer_;
char *bufferEnd_; char *bufferEnd_;
char *current_; char *current_;
}; };
//! Implement specialized version of PutN() with memset() for better performance. //! Implement specialized version of PutN() with memset() for better performance.
template<> template<>
inline void PutN(FileWriteStream& stream, char c, size_t n) { inline void PutN(FileWriteStream& stream, char c, size_t n) {
stream.PutN(c, n); stream.PutN(c, n);
} }
} // namespace rapidjson } // namespace rapidjson
......
This diff is collapsed.
// Copyright (C) 2011 Milo Yip
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef RAPIDJSON_ITOA_ #ifndef RAPIDJSON_ITOA_
#define RAPIDJSON_ITOA_ #define RAPIDJSON_ITOA_
namespace rapidjson { namespace rapidjson {
namespace internal { namespace internal {
// Modified from https://github.com/miloyip/itoa-benchmark/blob/master/src/branchlut.cpp
// API is changed to return the character passed the end of string, without writing '\0'
inline const char* GetDigitsLut() { inline const char* GetDigitsLut() {
static const char cDigitsLut[200] = { static const char cDigitsLut[200] = {
'0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9', '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9',
...@@ -98,12 +115,12 @@ inline char* u32toa(uint32_t value, char* buffer) { ...@@ -98,12 +115,12 @@ inline char* u32toa(uint32_t value, char* buffer) {
} }
inline char* i32toa(int32_t value, char* buffer) { inline char* i32toa(int32_t value, char* buffer) {
if (value < 0) { if (value < 0) {
*buffer++ = '-'; *buffer++ = '-';
value = -value; value = -value;
} }
return u32toa(static_cast<uint32_t>(value), buffer); return u32toa(static_cast<uint32_t>(value), buffer);
} }
inline char* u64toa(uint64_t value, char* buffer) { inline char* u64toa(uint64_t value, char* buffer) {
...@@ -271,16 +288,16 @@ inline char* u64toa(uint64_t value, char* buffer) { ...@@ -271,16 +288,16 @@ inline char* u64toa(uint64_t value, char* buffer) {
*buffer++ = cDigitsLut[d8 + 1]; *buffer++ = cDigitsLut[d8 + 1];
} }
return buffer; return buffer;
} }
inline char* i64toa(int64_t value, char* buffer) { inline char* i64toa(int64_t value, char* buffer) {
if (value < 0) { if (value < 0) {
*buffer++ = '-'; *buffer++ = '-';
value = -value; value = -value;
} }
return u64toa(static_cast<uint64_t>(value), buffer); return u64toa(static_cast<uint64_t>(value), buffer);
} }
} // namespace internal } // namespace internal
......
// Copyright (C) 2011 Milo Yip
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef RAPIDJSON_INTERNAL_META_H_ #ifndef RAPIDJSON_INTERNAL_META_H_
#define RAPIDJSON_INTERNAL_META_H_ #define RAPIDJSON_INTERNAL_META_H_
...@@ -35,10 +55,10 @@ template <typename T> struct IsPointer<T*> : TrueType {}; ...@@ -35,10 +55,10 @@ template <typename T> struct IsPointer<T*> : TrueType {};
template <typename CT, typename T> template <typename CT, typename T>
struct IsMoreConst { struct IsMoreConst {
enum { Value = enum { Value =
( IsSame< typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>::Value ( IsSame< typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>::Value
&& ( IsConst<CT>::Value >= IsConst<T>::Value ) ) && ( IsConst<CT>::Value >= IsConst<T>::Value ) )
}; };
}; };
template <bool Condition, typename T = void> struct EnableIfCond; template <bool Condition, typename T = void> struct EnableIfCond;
...@@ -60,15 +80,15 @@ template <typename T> struct RemoveSfinaeFptr {}; ...@@ -60,15 +80,15 @@ template <typename T> struct RemoveSfinaeFptr {};
template <typename T> struct RemoveSfinaeFptr<SfinaeResultTag&(*)(T)> { typedef T Type; }; template <typename T> struct RemoveSfinaeFptr<SfinaeResultTag&(*)(T)> { typedef T Type; };
#define RAPIDJSON_REMOVEFPTR_(type) \ #define RAPIDJSON_REMOVEFPTR_(type) \
typename ::rapidjson::internal::RemoveSfinaeFptr \ typename ::rapidjson::internal::RemoveSfinaeFptr \
< ::rapidjson::internal::SfinaeResultTag&(*) type>::Type < ::rapidjson::internal::SfinaeResultTag&(*) type>::Type
#define RAPIDJSON_ENABLEIF(cond) \ #define RAPIDJSON_ENABLEIF(cond) \
typename ::rapidjson::internal::EnableIf \ typename ::rapidjson::internal::EnableIf \
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \ #define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
typename ::rapidjson::internal::DisableIf<cond,returntype>::Type typename ::rapidjson::internal::DisableIf<cond,returntype>::Type
} // namespace internal } // namespace internal
} // namespace rapidjson } // namespace rapidjson
......
// Copyright (C) 2011 Milo Yip
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef RAPIDJSON_POW10_ #ifndef RAPIDJSON_POW10_
#define RAPIDJSON_POW10_ #define RAPIDJSON_POW10_
...@@ -6,31 +26,31 @@ namespace internal { ...@@ -6,31 +26,31 @@ namespace internal {
//! Computes integer powers of 10 in double (10.0^n). //! Computes integer powers of 10 in double (10.0^n).
/*! This function uses lookup table for fast and accurate results. /*! This function uses lookup table for fast and accurate results.
\param n non-negative exponent. Must <= 308. \param n non-negative exponent. Must <= 308.
\return 10.0^n \return 10.0^n
*/ */
inline double Pow10(int n) { inline double Pow10(int n) {
static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes
1e+0, 1e+0,
1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20,
1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,
1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,
1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,
1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,
1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,
1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,
1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,
1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,
1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,
1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,
1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,
1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,
1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,
1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,
1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
}; };
RAPIDJSON_ASSERT(n >= 0 && n <= 308); RAPIDJSON_ASSERT(n >= 0 && n <= 308);
return e[n]; return e[n];
} }
} // namespace internal } // namespace internal
......
// Copyright (C) 2011 Milo Yip
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef RAPIDJSON_INTERNAL_STACK_H_ #ifndef RAPIDJSON_INTERNAL_STACK_H_
#define RAPIDJSON_INTERNAL_STACK_H_ #define RAPIDJSON_INTERNAL_STACK_H_
...@@ -13,79 +33,79 @@ namespace internal { ...@@ -13,79 +33,79 @@ namespace internal {
template <typename Allocator> template <typename Allocator>
class Stack { class Stack {
public: public:
Stack(Allocator* allocator, size_t stack_capacity) : allocator_(allocator), own_allocator_(0), stack_(0), stack_top_(0), stack_end_(0), stack_capacity_(stack_capacity) { Stack(Allocator* allocator, size_t stack_capacity) : allocator_(allocator), own_allocator_(0), stack_(0), stack_top_(0), stack_end_(0), stack_capacity_(stack_capacity) {
RAPIDJSON_ASSERT(stack_capacity_ > 0); RAPIDJSON_ASSERT(stack_capacity_ > 0);
if (!allocator_) if (!allocator_)
own_allocator_ = allocator_ = new Allocator(); own_allocator_ = allocator_ = new Allocator();
stack_top_ = stack_ = (char*)allocator_->Malloc(stack_capacity_); stack_top_ = stack_ = (char*)allocator_->Malloc(stack_capacity_);
stack_end_ = stack_ + stack_capacity_; stack_end_ = stack_ + stack_capacity_;
} }
~Stack() { ~Stack() {
Allocator::Free(stack_); Allocator::Free(stack_);
delete own_allocator_; // Only delete if it is owned by the stack delete own_allocator_; // Only delete if it is owned by the stack
} }
void Clear() { /*stack_top_ = 0;*/ stack_top_ = stack_; } void Clear() { /*stack_top_ = 0;*/ stack_top_ = stack_; }
// Optimization note: try to minimize the size of this function for force inline. // Optimization note: try to minimize the size of this function for force inline.
// Expansion is run very infrequently, so it is moved to another (probably non-inline) function. // Expansion is run very infrequently, so it is moved to another (probably non-inline) function.
template<typename T> template<typename T>
RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) { RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {
// Expand the stack if needed // Expand the stack if needed
if (stack_top_ + sizeof(T) * count >= stack_end_) if (stack_top_ + sizeof(T) * count >= stack_end_)
Expand<T>(count); Expand<T>(count);
T* ret = reinterpret_cast<T*>(stack_top_); T* ret = reinterpret_cast<T*>(stack_top_);
stack_top_ += sizeof(T) * count; stack_top_ += sizeof(T) * count;
return ret; return ret;
} }
template<typename T> template<typename T>
T* Pop(size_t count) { T* Pop(size_t count) {
RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
stack_top_ -= count * sizeof(T); stack_top_ -= count * sizeof(T);
return reinterpret_cast<T*>(stack_top_); return reinterpret_cast<T*>(stack_top_);
} }
template<typename T> template<typename T>
T* Top() { T* Top() {
RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
return reinterpret_cast<T*>(stack_top_ - sizeof(T)); return reinterpret_cast<T*>(stack_top_ - sizeof(T));
} }
template<typename T> template<typename T>
T* Bottom() { return (T*)stack_; } T* Bottom() { return (T*)stack_; }
Allocator& GetAllocator() { return *allocator_; } Allocator& GetAllocator() { return *allocator_; }
bool Empty() const { return stack_top_ == stack_; } bool Empty() const { return stack_top_ == stack_; }
size_t GetSize() const { return static_cast<size_t>(stack_top_ - stack_); } size_t GetSize() const { return static_cast<size_t>(stack_top_ - stack_); }
size_t GetCapacity() const { return stack_capacity_; } size_t GetCapacity() const { return stack_capacity_; }
private: private:
template<typename T> template<typename T>
void Expand(size_t count) { void Expand(size_t count) {
size_t new_capacity = stack_capacity_ * 2; size_t new_capacity = stack_capacity_ * 2;
size_t size = GetSize(); size_t size = GetSize();
size_t new_size = GetSize() + sizeof(T) * count; size_t new_size = GetSize() + sizeof(T) * count;
if (new_capacity < new_size) if (new_capacity < new_size)
new_capacity = new_size; new_capacity = new_size;
stack_ = (char*)allocator_->Realloc(stack_, stack_capacity_, new_capacity); stack_ = (char*)allocator_->Realloc(stack_, stack_capacity_, new_capacity);
stack_capacity_ = new_capacity; stack_capacity_ = new_capacity;
stack_top_ = stack_ + size; stack_top_ = stack_ + size;
stack_end_ = stack_ + stack_capacity_; stack_end_ = stack_ + stack_capacity_;
} }
// Prohibit copy constructor & assignment operator. // Prohibit copy constructor & assignment operator.
Stack(const Stack&); Stack(const Stack&);
Stack& operator=(const Stack&); Stack& operator=(const Stack&);
Allocator* allocator_; Allocator* allocator_;
Allocator* own_allocator_; Allocator* own_allocator_;
char *stack_; char *stack_;
char *stack_top_; char *stack_top_;
char *stack_end_; char *stack_end_;
size_t stack_capacity_; size_t stack_capacity_;
}; };
} // namespace internal } // namespace internal
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Copyright (C) 2011 Milo Yip
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "perftest.h" #include "perftest.h"
int main(int argc, char **argv) { int main(int argc, char **argv) {
#if _MSC_VER #if _MSC_VER
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
//void *testWhetherMemoryLeakDetectionWorks = malloc(1); //void *testWhetherMemoryLeakDetectionWorks = malloc(1);
#endif #endif
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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