Merge branch 'master' into issue23errorcode
Conflicts: example/condense/condense.cpp include/rapidjson/reader.h test/unittest/readertest.cpp
This commit is contained in:
commit
389fe87cd8
@ -21,6 +21,8 @@ before_script:
|
||||
- cd "${TRAVIS_BUILD_DIR}"
|
||||
|
||||
script:
|
||||
- make -C build/gmake -f test.make unittest
|
||||
- make -C build/gmake -f test.make
|
||||
- make -C build/gmake -f example.make
|
||||
- cd bin
|
||||
- ./unittest_${config_suffix}
|
||||
- ./perftest_${config_suffix}
|
||||
|
@ -149,8 +149,8 @@ solution "example"
|
||||
configuration "vs*"
|
||||
defines { "_CRT_SECURE_NO_WARNINGS" }
|
||||
|
||||
configuration "gmake"
|
||||
buildoptions "-Weverything"
|
||||
-- configuration "gmake"
|
||||
-- buildoptions "-Weverything"
|
||||
|
||||
project "condense"
|
||||
kind "ConsoleApp"
|
||||
@ -176,3 +176,8 @@ solution "example"
|
||||
kind "ConsoleApp"
|
||||
files "../example/serialize/*"
|
||||
setTargetObjDir("../bin")
|
||||
|
||||
project "simpledom"
|
||||
kind "ConsoleApp"
|
||||
files "../example/simpledom/*"
|
||||
setTargetObjDir("../bin")
|
||||
|
8
doc/diagram/makefile
Normal file
8
doc/diagram/makefile
Normal file
@ -0,0 +1,8 @@
|
||||
%.pdf: %.dot
|
||||
dot $< -Tpdf -o $@
|
||||
|
||||
%.png: %.dot
|
||||
dot $< -Tpng -o $@
|
||||
|
||||
DOTFILES = $(basename $(wildcard *.dot))
|
||||
all: $(addsuffix .png, $(DOTFILES)) #$(addsuffix .pdf, $(DOTFILES))
|
54
doc/diagram/simpledom.dot
Normal file
54
doc/diagram/simpledom.dot
Normal file
@ -0,0 +1,54 @@
|
||||
digraph {
|
||||
compound=true
|
||||
fontname="Inconsolata, Consolas"
|
||||
fontsize=10
|
||||
margin="0,0"
|
||||
ranksep=0.2
|
||||
penwidth=0.5
|
||||
|
||||
node [fontname="Inconsolata, Consolas", fontsize=10, penwidth=0.5]
|
||||
edge [fontname="Inconsolata, Consolas", fontsize=10, arrowhead=normal]
|
||||
|
||||
{
|
||||
node [shape=record, fontsize="8", margin="0.04", height=0.2, color=gray]
|
||||
srcjson [label="\{|p|r|o|j|e|c|t|\"|:|\"|r|a|p|i|d|j|s|o|n|\"|,|\"|s|t|a|r|s|\"|:|1|0|\}"]
|
||||
dstjson [label="\{|p|r|o|j|e|c|t|\"|:|\"|r|a|p|i|d|j|s|o|n|\"|,|\"|s|t|a|r|s|\"|:|1|1|\}"]
|
||||
}
|
||||
|
||||
{
|
||||
node [shape="box", style="filled", fillcolor="gray95"]
|
||||
Document2 [label="(Modified) Document"]
|
||||
Writer
|
||||
}
|
||||
|
||||
subgraph cluster1 {
|
||||
margin="10,10"
|
||||
labeljust="left"
|
||||
label = "Document"
|
||||
style=filled
|
||||
fillcolor=gray95
|
||||
node [shape=Mrecord, style=filled, colorscheme=spectral7]
|
||||
|
||||
root [label="{object|}", fillcolor=3]
|
||||
|
||||
{
|
||||
project [label="{string|\"project\"}", fillcolor=5]
|
||||
rapidjson [label="{string|\"rapidjson\"}", fillcolor=5]
|
||||
stars [label="{string|\"stars\"}", fillcolor=5]
|
||||
ten [label="{number|10}", fillcolor=6]
|
||||
}
|
||||
|
||||
edge [arrowhead=vee]
|
||||
root -> { project, stars }
|
||||
|
||||
edge [arrowhead="none"]
|
||||
project -> rapidjson
|
||||
stars -> ten
|
||||
}
|
||||
|
||||
srcjson -> root [label=" Parse()", lhead="cluster1"]
|
||||
|
||||
ten -> Document2 [label=" Increase \"stars\"", ltail="cluster1" ]
|
||||
Document2 -> Writer [label=" Traverse DOM by Accept()"]
|
||||
Writer -> dstjson [label=" Output to StringBuffer"]
|
||||
}
|
BIN
doc/diagram/simpledom.png
Normal file
BIN
doc/diagram/simpledom.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
79
doc/features.md
Normal file
79
doc/features.md
Normal file
@ -0,0 +1,79 @@
|
||||
# RapidJSON Features
|
||||
|
||||
## General
|
||||
|
||||
* Cross-platform
|
||||
* Compilers: Visual Studio, gcc, clang, etc.
|
||||
* Architectures: x86, x64, ARM, etc.
|
||||
* Operating systems: Windows, Mac OS X, Linux, iOS, Android, etc.
|
||||
* Easy installation
|
||||
* Header files only library. Just copy the headers to your project.
|
||||
* Self-contained, minimal dependences
|
||||
* No STL, BOOST, etc.
|
||||
* Only included `<cstdio>`, `<cstdlib>`, `<cstring>`, `<inttypes.h>`, `<new>`, `<stdint.h>`. *
|
||||
* Without C++ exception, RTTI
|
||||
* High performance
|
||||
* Use template and inline functions to reduce function call overheads.
|
||||
* Optional SSE2/SSE4.1 support.
|
||||
|
||||
## Standard compliance
|
||||
|
||||
* RapidJSON should be fully RFC4627/ECMA-404 compliance.
|
||||
* Support unicode surrogate.
|
||||
* Support null character (`"\u0000"`)
|
||||
* For example, `["Hello\u0000World"]` can be parsed and handled gracefully. There is API for getting/setting lengths of string.
|
||||
|
||||
## Unicode
|
||||
|
||||
* Support UTF-8, UTF-16, UTF-32 encodings, including little endian and big endian.
|
||||
* These encodings are used in input/output streams and in-memory representation.
|
||||
* Support automatic detection of encodings in input stream.
|
||||
* Support transcoding between encodings internally.
|
||||
* For example, you can read a UTF-8 file and let RapidJSON transcode the JSON strings into UTF-16 in the DOM.
|
||||
* Support encoding validation internally.
|
||||
* For example, you can read a UTF-8 file, and let RapidJSON check whether all JSON strings are valid UTF-8 byte sequence.
|
||||
* Support custom character types.
|
||||
* By default the character types are `char` for UTF8, `wchar_t` for UTF16, `uint32_t` for UTF32.
|
||||
* Support custom encodings.
|
||||
|
||||
## API styles
|
||||
|
||||
* SAX (Simple API for XML) style API
|
||||
* Similar to [SAX](http://en.wikipedia.org/wiki/Simple_API_for_XML), RapidJSON provides a event sequential access parser API (`GenericReader`). It also provides a generator API (`GenericWriter`) which consumes the same set of events.
|
||||
* DOM (Document Object Model) style API
|
||||
* Similar to [DOM](http://en.wikipedia.org/wiki/Document_Object_Model) for HTML/XML, RapidJSON can parse JSON into a DOM representation (`GenericDocument`), for easy manipulation, and finally stringify back to JSON if needed.
|
||||
* The DOM style API (`GenericDocument`) is actually implemented with SAX style API (`GenericReader`). SAX is faster but sometimes DOM is easier. Users can pick their choices according to scenarios.
|
||||
|
||||
## DOM (Document)
|
||||
|
||||
* Support insitu parsing.
|
||||
* Parse JSON string values in-place at the source JSON, and then the DOM points to addresses of those strings.
|
||||
* Faster than convention parsing: no allocation for strings, no copy (if string does not contain escapes), cache-friendly.
|
||||
* Support 32-bit/64-bit signed/unsigned integer and `double` for JSON number type.
|
||||
* RapidJSON checks range of numerical values for conversions.
|
||||
|
||||
## SAX (Reader)
|
||||
|
||||
* Support comprehensive error code if parsing failed.
|
||||
* Support localizable error message.
|
||||
|
||||
## SAX (Writer)
|
||||
|
||||
* Support PrettyWriter for adding newlines and indentations.
|
||||
* Support custom precision for floating point values.
|
||||
|
||||
## Stream
|
||||
|
||||
* Support `GenericStringBuffer` for storing the output JSON as string.
|
||||
* Support `FileReadStream`/`FileWriteStream` for input/output `FILE` object.
|
||||
* Support custom streams.
|
||||
|
||||
## Memory
|
||||
|
||||
* Minimize memory overheads for DOM.
|
||||
* Each JSON value occupies exactly 16/20 bytes for most 32/64-bit machines (excluding text string).
|
||||
* Support fast default allocator.
|
||||
* A stack-based allocator (allocate sequentially, prohibit to free individual allocations, suitable for parsing).
|
||||
* User can provide a pre-allocated buffer. (Possible to parse a number of JSONs without any CRT allocation)
|
||||
* Support standard CRT(C-runtime) allocator.
|
||||
* Support custom allocators.
|
@ -23,7 +23,7 @@ int main(int, char*[]) {
|
||||
Writer<FileWriteStream> writer(os);
|
||||
|
||||
// JSON reader parse from the input stream and let writer generate the output.
|
||||
if (!reader.Parse<0>(is, writer)) {
|
||||
if (!reader.Parse(is, writer)) {
|
||||
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode()));
|
||||
return 1;
|
||||
}
|
||||
|
29
example/simpledom/simpledom.cpp
Normal file
29
example/simpledom/simpledom.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
// JSON simple example
|
||||
// This example does not handle errors.
|
||||
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/writer.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
int main() {
|
||||
// 1. Parse a JSON string into DOM.
|
||||
const char* json = "{\"project\":\"rapidjson\",\"stars\":10}";
|
||||
Document d;
|
||||
d.Parse(json);
|
||||
|
||||
// 2. Modify it by DOM.
|
||||
Value& s = d["stars"];
|
||||
s.SetInt(s.GetInt() + 1);
|
||||
|
||||
// 3. Stringify the DOM
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
d.Accept(writer);
|
||||
|
||||
// Output {"project":"rapidjson","stars":11}
|
||||
std::cout << buffer.GetString() << std::endl;
|
||||
return 0;
|
||||
}
|
@ -19,14 +19,14 @@ int main(int, char*[]) {
|
||||
|
||||
#if 0
|
||||
// "normal" parsing, decode strings to new buffers. Can use other input stream via ParseStream().
|
||||
if (document.Parse<0>(json).HasParseError())
|
||||
if (document.Parse(json).HasParseError())
|
||||
return 1;
|
||||
#else
|
||||
// In-situ parsing, decode strings directly in the source string. Source must be string.
|
||||
{
|
||||
char buffer[sizeof(json)];
|
||||
memcpy(buffer, json, sizeof(json));
|
||||
if (document.ParseInsitu<0>(buffer).HasParseError())
|
||||
if (document.ParseInsitu(buffer).HasParseError())
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
@ -202,7 +202,7 @@ public:
|
||||
*/
|
||||
template <typename SourceAllocator>
|
||||
GenericValue& CopyFrom(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator) {
|
||||
RAPIDJSON_ASSERT((void*)this != (void*)&rhs);
|
||||
RAPIDJSON_ASSERT((void*)this != (void const*)&rhs);
|
||||
this->~GenericValue();
|
||||
new (this) GenericValue(rhs,allocator);
|
||||
return *this;
|
||||
@ -818,6 +818,11 @@ public:
|
||||
return ParseStream<parseFlags,Encoding,InputStream>(is);
|
||||
}
|
||||
|
||||
template <typename InputStream>
|
||||
GenericDocument& ParseStream(InputStream& is) {
|
||||
return ParseStream<0, Encoding, InputStream>(is);
|
||||
}
|
||||
|
||||
//! Parse JSON text from a mutable string.
|
||||
/*! \tparam parseFlags Combination of ParseFlag.
|
||||
\param str Mutable zero-terminated string to be parsed.
|
||||
@ -834,6 +839,10 @@ public:
|
||||
return ParseInsitu<parseFlags, Encoding>(str);
|
||||
}
|
||||
|
||||
GenericDocument& ParseInsitu(Ch* str) {
|
||||
return ParseInsitu<0, Encoding>(str);
|
||||
}
|
||||
|
||||
//! Parse JSON text from a read-only string.
|
||||
/*! \tparam parseFlags Combination of ParseFlag (must not contain kParseInsituFlag).
|
||||
\param str Read-only zero-terminated string to be parsed.
|
||||
@ -850,6 +859,10 @@ public:
|
||||
return Parse<parseFlags, Encoding>(str);
|
||||
}
|
||||
|
||||
GenericDocument& Parse(const Ch* str) {
|
||||
return Parse<0>(str);
|
||||
}
|
||||
|
||||
//! Whether a parse error was occured in the last parsing.
|
||||
bool HasParseError() const { return parseErrorCode_ != kParseErrorNone; }
|
||||
|
||||
|
@ -69,6 +69,11 @@ private:
|
||||
bool eof_;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct StreamTraits<FileReadStream> {
|
||||
typedef FileReadStream StreamCopyType; // Enable stream copy optimization.
|
||||
};
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_FILESTREAM_H_
|
||||
|
@ -193,6 +193,24 @@ concept Stream {
|
||||
\endcode
|
||||
*/
|
||||
|
||||
//! Provides additional information for stream.
|
||||
/*!
|
||||
By using traits pattern, this type provides a default configuration for stream.
|
||||
For custom stream, this type can be specialized for other configuration.
|
||||
See TEST(Reader, CustomStringStream) in readertest.cpp for example.
|
||||
*/
|
||||
template<typename Stream>
|
||||
struct StreamTraits {
|
||||
//! Whether to make local copy of stream for optimization during parsing.
|
||||
/*!
|
||||
If it is defined as Stream&, it will not make a local copy.
|
||||
If it is defined as Stream, it will make a local copy for optimization.
|
||||
By default, for safety, streams do not use local copy optimization, i.e. it is defined as Stream&.
|
||||
Stream that can be copied fast should specialize this, like StreamTraits<StringStream>.
|
||||
*/
|
||||
typedef Stream& StreamCopyType;
|
||||
};
|
||||
|
||||
//! Put N copies of a character to a stream.
|
||||
template<typename Stream, typename Ch>
|
||||
inline void PutN(Stream& stream, Ch c, size_t n) {
|
||||
@ -225,6 +243,11 @@ struct GenericStringStream {
|
||||
const Ch* head_; //!< Original head of the string.
|
||||
};
|
||||
|
||||
template <typename Encoding>
|
||||
struct StreamTraits<GenericStringStream<Encoding> > {
|
||||
typedef GenericStringStream<Encoding> StreamCopyType; // Enable stream copy optimization.
|
||||
};
|
||||
|
||||
typedef GenericStringStream<UTF8<> > StringStream;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -256,6 +279,11 @@ struct GenericInsituStringStream {
|
||||
Ch* head_;
|
||||
};
|
||||
|
||||
template <typename Encoding>
|
||||
struct StreamTraits<GenericInsituStringStream<Encoding> > {
|
||||
typedef GenericInsituStringStream<Encoding> StreamCopyType; // Enable stream copy optimization.
|
||||
};
|
||||
|
||||
typedef GenericInsituStringStream<UTF8<> > InsituStringStream;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -135,7 +135,7 @@ struct BaseReaderHandler {
|
||||
*/
|
||||
template<typename InputStream>
|
||||
void SkipWhitespace(InputStream& is) {
|
||||
InputStream s = is; // Use a local copy for optimization
|
||||
typename StreamTraits<InputStream>::StreamCopyType s = is; // Use a local copy for optimization
|
||||
while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t')
|
||||
s.Take();
|
||||
is = s;
|
||||
@ -283,8 +283,15 @@ public:
|
||||
return !HasParseError();
|
||||
}
|
||||
|
||||
template <typename InputStream, typename Handler>
|
||||
bool Parse(InputStream& is, Handler& handler) {
|
||||
return Parse<0>(is, handler);
|
||||
}
|
||||
|
||||
bool HasParseError() const { return parseErrorCode_ != kParseErrorNone; }
|
||||
|
||||
ParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
|
||||
|
||||
size_t GetErrorOffset() const { return errorOffset_; }
|
||||
|
||||
private:
|
||||
@ -399,7 +406,7 @@ private:
|
||||
// Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
|
||||
template<typename InputStream>
|
||||
unsigned ParseHex4(InputStream& is) {
|
||||
InputStream s = is; // Use a local copy for optimization
|
||||
typename StreamTraits<InputStream>::StreamCopyType s = is; // Use a local copy for optimization
|
||||
unsigned codepoint = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Ch c = s.Take();
|
||||
@ -440,7 +447,7 @@ private:
|
||||
// Parse string and generate String event. Different code paths for kParseInsituFlag.
|
||||
template<unsigned parseFlags, typename InputStream, typename Handler>
|
||||
void ParseString(InputStream& is, Handler& handler) {
|
||||
InputStream s = is; // Local copy for optimization
|
||||
typename StreamTraits<InputStream>::StreamCopyType s = is; // Local copy for optimization
|
||||
if (parseFlags & kParseInsituFlag) {
|
||||
Ch *head = s.PutBegin();
|
||||
ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
|
||||
@ -520,7 +527,7 @@ private:
|
||||
|
||||
template<unsigned parseFlags, typename InputStream, typename Handler>
|
||||
void ParseNumber(InputStream& is, Handler& handler) {
|
||||
InputStream s = is; // Local copy for optimization
|
||||
typename StreamTraits<InputStream>::StreamCopyType s = is; // Local copy for optimization
|
||||
// Parse minus
|
||||
bool minus = false;
|
||||
if (s.Peek() == '-') {
|
||||
|
48
readme.md
48
readme.md
@ -16,7 +16,9 @@ Rapidjson is a JSON parser and generator for C++. It was inspired by [rapidxml](
|
||||
|
||||
* Rapidjson is memory friendly. Each JSON value occupies exactly 16/20 bytes for most 32/64-bit machines (excluding text string). By default it uses a fast memory allocator, and the parser allocates memory compactly during parsing.
|
||||
|
||||
For the full features please refer to the user guide.
|
||||
* Rapidjson is Unicode friendly. It supports UTF-8, UTF-16, UTF-32 (LE & BE), and their detection, validataton and transcoding internally. For example, you can read a UTF-8 file and let rapidjson transcode the JSON strings into UTF-16 in the DOM. It also supports surrogates and "\u0000" (null character).
|
||||
|
||||
More features can be read [here](doc/features.md).
|
||||
|
||||
JSON(JavaScript Object Notation) is a light-weight data exchange format. Rapidjson should be in fully compliance with RFC4627/ECMA-404. More information about JSON can be obtained at
|
||||
* [Introducing JSON](http://json.org/)
|
||||
@ -39,9 +41,51 @@ Rapidjson is a header-only C++ library. Just copy the `rapidjson/include/rapidjs
|
||||
|
||||
To build the tests and examples:
|
||||
|
||||
1. Obtain [premake4] (http://industriousone.com/premake/download).
|
||||
1. Obtain [premake4](http://industriousone.com/premake/download).
|
||||
2. Copy premake4 executable to rapidjson/build (or system path)
|
||||
3. Run `rapidjson/build/premake.bat` on Windows, `rapidjson/build/premake.sh` on Linux or other platforms
|
||||
4. On Windows, build the solution at `rapidjson/build/vs2008/` or `/vs2010/`
|
||||
5. On other platforms, run GNU make at `rapidjson/build/gmake/` (e.g., `make -f test.make config=release32`, `make -f example.make config=debug32`)
|
||||
6. On success, the executable are generated at `rapidjson/bin`
|
||||
|
||||
## Usage at a glance
|
||||
|
||||
This simple example parses a JSON string into a document (DOM), make a simple modification of the DOM, and finally stringify the DOM to a JSON string.
|
||||
|
||||
```cpp
|
||||
// example/simpledom/simpledom.cpp
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/writer.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
int main() {
|
||||
// 1. Parse a JSON string into DOM.
|
||||
const char* json = "{\"project\":\"rapidjson\",\"stars\":10}";
|
||||
Document d;
|
||||
d.Parse(json);
|
||||
|
||||
// 2. Modify it by DOM.
|
||||
Value& s = d["stars"];
|
||||
s.SetInt(s.GetInt() + 1);
|
||||
|
||||
// 3. Stringify the DOM
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
d.Accept(writer);
|
||||
|
||||
// Output {"project":"rapidjson","stars":11}
|
||||
std::cout << buffer.GetString() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
Note that this exmample did not handle potential errors.
|
||||
|
||||
The following diagram shows the process.
|
||||
|
||||

|
||||
|
||||
More [examples](example/) are avaliable.
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
temp_ = (char *)malloc(length_ + 1);
|
||||
|
||||
// Parse as a document
|
||||
EXPECT_FALSE(doc_.Parse<0>(json_).IsNull());
|
||||
EXPECT_FALSE(doc_.Parse(json_).IsNull());
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
@ -66,7 +66,7 @@ TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler)) {
|
||||
StringStream s(json_);
|
||||
BaseReaderHandler<> h;
|
||||
Reader reader;
|
||||
EXPECT_TRUE(reader.Parse<0>(s, h));
|
||||
EXPECT_TRUE(reader.Parse(s, h));
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ TEST_F(RapidJson, SIMD_SUFFIX(DoucmentParseInsitu_MemoryPoolAllocator)) {
|
||||
//MemoryPoolAllocator<> allocator(userBuffer, userBufferSize);
|
||||
//Document doc(&allocator);
|
||||
Document doc;
|
||||
doc.ParseInsitu<0>(temp_);
|
||||
doc.ParseInsitu(temp_);
|
||||
ASSERT_TRUE(doc.IsObject());
|
||||
//if (i == 0) {
|
||||
// size_t size = doc.GetAllocator().Size();
|
||||
@ -110,7 +110,7 @@ TEST_F(RapidJson, SIMD_SUFFIX(DoucmentParse_MemoryPoolAllocator)) {
|
||||
//MemoryPoolAllocator<> allocator(userBuffer, userBufferSize);
|
||||
//Document doc(&allocator);
|
||||
Document doc;
|
||||
doc.Parse<0>(json_);
|
||||
doc.Parse(json_);
|
||||
ASSERT_TRUE(doc.IsObject());
|
||||
//if (i == 0) {
|
||||
// size_t size = doc.GetAllocator().Size();
|
||||
@ -128,7 +128,7 @@ TEST_F(RapidJson, SIMD_SUFFIX(DoucmentParse_CrtAllocator)) {
|
||||
for (size_t i = 0; i < kTrialCount; i++) {
|
||||
memcpy(temp_, json_, length_ + 1);
|
||||
GenericDocument<UTF8<>, CrtAllocator> doc;
|
||||
doc.Parse<0>(temp_);
|
||||
doc.Parse(temp_);
|
||||
ASSERT_TRUE(doc.IsObject());
|
||||
}
|
||||
}
|
||||
@ -234,7 +234,7 @@ TEST_F(RapidJson, internal_Pow10) {
|
||||
TEST_F(RapidJson, SIMD_SUFFIX(Whitespace)) {
|
||||
for (size_t i = 0; i < kTrialCount; i++) {
|
||||
Document doc;
|
||||
ASSERT_TRUE(doc.Parse<0>(whitespace_).IsArray());
|
||||
ASSERT_TRUE(doc.Parse(whitespace_).IsArray());
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,7 +279,7 @@ TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_FileReadStream)) {
|
||||
FileReadStream s(fp, buffer, sizeof(buffer));
|
||||
BaseReaderHandler<> h;
|
||||
Reader reader;
|
||||
reader.Parse<0>(s, h);
|
||||
reader.Parse(s, h);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ using namespace rapidjson;
|
||||
TEST(Document, Parse) {
|
||||
Document doc;
|
||||
|
||||
doc.Parse<0>(" { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ");
|
||||
doc.Parse(" { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ");
|
||||
|
||||
EXPECT_TRUE(doc.IsObject());
|
||||
|
||||
@ -59,7 +59,7 @@ struct OutputStringStream : public std::ostringstream {
|
||||
|
||||
TEST(Document, AcceptWriter) {
|
||||
Document doc;
|
||||
doc.Parse<0>(" { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ");
|
||||
doc.Parse(" { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ");
|
||||
|
||||
OutputStringStream os;
|
||||
Writer<OutputStringStream> writer(os);
|
||||
|
@ -42,7 +42,7 @@ TEST(JsonChecker, Reader) {
|
||||
}
|
||||
|
||||
GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak)
|
||||
if (!document.Parse<0>((const char*)json).HasParseError())
|
||||
if (!document.Parse((const char*)json).HasParseError())
|
||||
FAIL();
|
||||
//printf("%s(%u):%s\n", filename, (unsigned)document.GetErrorOffset(), document.GetParseError());
|
||||
free(json);
|
||||
@ -63,7 +63,7 @@ TEST(JsonChecker, Reader) {
|
||||
}
|
||||
|
||||
GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak)
|
||||
document.Parse<0>((const char*)json);
|
||||
document.Parse((const char*)json);
|
||||
EXPECT_TRUE(!document.HasParseError());
|
||||
free(json);
|
||||
}
|
||||
|
@ -603,3 +603,51 @@ TEST(Reader, SkipWhitespace) {
|
||||
EXPECT_EQ(expected[i], ss.Take());
|
||||
}
|
||||
}
|
||||
|
||||
// Test implementing a stream without copy stream optimization.
|
||||
// Clone from GenericStringStream except that copy constructor is disabled.
|
||||
template <typename Encoding>
|
||||
class CustomStringStream {
|
||||
public:
|
||||
typedef typename Encoding::Ch Ch;
|
||||
|
||||
CustomStringStream(const Ch *src) : src_(src), head_(src) {}
|
||||
|
||||
Ch Peek() const { return *src_; }
|
||||
Ch Take() { return *src_++; }
|
||||
size_t Tell() const { return static_cast<size_t>(src_ - head_); }
|
||||
|
||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||
|
||||
private:
|
||||
// Not support copy constructor.
|
||||
CustomStringStream(const CustomStringStream&);
|
||||
|
||||
const Ch* src_; //!< Current read position.
|
||||
const Ch* head_; //!< Original head of the string.
|
||||
};
|
||||
|
||||
// If the following code is compiled, it should generate compilation error as predicted.
|
||||
// Because CustomStringStream<> is not copyable via making copy constructor private.
|
||||
#if 0
|
||||
namespace rapidjson {
|
||||
|
||||
template <typename Encoding>
|
||||
struct StreamTraits<CustomStringStream<Encoding> > {
|
||||
typedef CustomStringStream<Encoding> StreamCopyType;
|
||||
};
|
||||
|
||||
} // namespace rapdijson
|
||||
#endif
|
||||
|
||||
TEST(Reader, CustomStringStream) {
|
||||
const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } ";
|
||||
CustomStringStream<UTF8<char> > s(json);
|
||||
ParseObjectHandler h;
|
||||
Reader reader;
|
||||
reader.ParseObject<0>(s, h);
|
||||
EXPECT_EQ(20u, h.step_);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user