diff options
Diffstat (limited to '3rdparty/rapidjson/example')
6 files changed, 203 insertions, 16 deletions
diff --git a/3rdparty/rapidjson/example/CMakeLists.txt b/3rdparty/rapidjson/example/CMakeLists.txt index c6b8449ffb1..8c546cf7911 100644 --- a/3rdparty/rapidjson/example/CMakeLists.txt +++ b/3rdparty/rapidjson/example/CMakeLists.txt @@ -1,6 +1,3 @@ -# Copyright (c) 2011 Milo Yip (miloyip@gmail.com) -# Copyright (c) 2013 Rafal Jeczalik (rjeczalik@gmail.com) -# Distributed under the MIT License (see license.txt file) cmake_minimum_required(VERSION 2.8) set(EXAMPLES @@ -8,6 +5,7 @@ set(EXAMPLES condense jsonx messagereader + parsebyparts pretty prettyauto schemavalidator @@ -22,7 +20,7 @@ include_directories("../include/") add_definitions(-D__STDC_FORMAT_MACROS) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -Werror -Wall -Wextra -Weffc++ -Wswitch-default") elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal -Wimplicit-fallthrough -Weverything") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") @@ -33,4 +31,8 @@ foreach (example ${EXAMPLES}) add_executable(${example} ${example}/${example}.cpp) endforeach() +if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + target_link_libraries(parsebyparts pthread) +endif() + add_custom_target(examples ALL DEPENDS ${EXAMPLES}) diff --git a/3rdparty/rapidjson/example/capitalize/capitalize.cpp b/3rdparty/rapidjson/example/capitalize/capitalize.cpp index adc32b52da1..7da37e9c504 100644 --- a/3rdparty/rapidjson/example/capitalize/capitalize.cpp +++ b/3rdparty/rapidjson/example/capitalize/capitalize.cpp @@ -24,7 +24,8 @@ struct CapitalizeFilter { bool Int64(int64_t i) { return out_.Int64(i); } bool Uint64(uint64_t u) { return out_.Uint64(u); } bool Double(double d) { return out_.Double(d); } - bool String(const char* str, SizeType length, bool) { + bool RawNumber(const char* str, SizeType length, bool copy) { return out_.RawNumber(str, length, copy); } + bool String(const char* str, SizeType length, bool) { buffer_.clear(); for (SizeType i = 0; i < length; i++) buffer_.push_back(static_cast<char>(std::toupper(str[i]))); diff --git a/3rdparty/rapidjson/example/jsonx/jsonx.cpp b/3rdparty/rapidjson/example/jsonx/jsonx.cpp index c253ac096df..1346b578c39 100644 --- a/3rdparty/rapidjson/example/jsonx/jsonx.cpp +++ b/3rdparty/rapidjson/example/jsonx/jsonx.cpp @@ -57,6 +57,13 @@ public: return WriteNumberElement(buffer, sprintf(buffer, "%.17g", d)); } + bool RawNumber(const char* str, SizeType length, bool) { + return + WriteStartElement("number") && + WriteEscapedText(str, length) && + WriteEndElement("number"); + } + bool String(const char* str, SizeType length, bool) { return WriteStartElement("string") && diff --git a/3rdparty/rapidjson/example/parsebyparts/parsebyparts.cpp b/3rdparty/rapidjson/example/parsebyparts/parsebyparts.cpp new file mode 100644 index 00000000000..919d9083458 --- /dev/null +++ b/3rdparty/rapidjson/example/parsebyparts/parsebyparts.cpp @@ -0,0 +1,172 @@ +// Example of parsing JSON to document by parts. + +// Using C++11 threads +#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1700) + +#include "rapidjson/document.h" +#include "rapidjson/error/en.h" +#include "rapidjson/writer.h" +#include "rapidjson/ostreamwrapper.h" +#include <condition_variable> +#include <iostream> +#include <mutex> +#include <thread> + +using namespace rapidjson; + +template<unsigned parseFlags = kParseDefaultFlags> +class AsyncDocumentParser { +public: + AsyncDocumentParser(Document& d) + : stream_(*this) + , d_(d) + , parseThread_(&AsyncDocumentParser::Parse, this) + , mutex_() + , notEmpty_() + , finish_() + , completed_() + {} + + ~AsyncDocumentParser() { + if (!parseThread_.joinable()) + return; + + { + std::unique_lock<std::mutex> lock(mutex_); + + // Wait until the buffer is read up (or parsing is completed) + while (!stream_.Empty() && !completed_) + finish_.wait(lock); + + // Automatically append '\0' as the terminator in the stream. + static const char terminator[] = ""; + stream_.src_ = terminator; + stream_.end_ = terminator + 1; + notEmpty_.notify_one(); // unblock the AsyncStringStream + } + + parseThread_.join(); + } + + void ParsePart(const char* buffer, size_t length) { + std::unique_lock<std::mutex> lock(mutex_); + + // Wait until the buffer is read up (or parsing is completed) + while (!stream_.Empty() && !completed_) + finish_.wait(lock); + + // Stop further parsing if the parsing process is completed. + if (completed_) + return; + + // Set the buffer to stream and unblock the AsyncStringStream + stream_.src_ = buffer; + stream_.end_ = buffer + length; + notEmpty_.notify_one(); + } + +private: + void Parse() { + d_.ParseStream<parseFlags>(stream_); + + // The stream may not be fully read, notify finish anyway to unblock ParsePart() + std::unique_lock<std::mutex> lock(mutex_); + completed_ = true; // Parsing process is completed + finish_.notify_one(); // Unblock ParsePart() or destructor if they are waiting. + } + + struct AsyncStringStream { + typedef char Ch; + + AsyncStringStream(AsyncDocumentParser& parser) : parser_(parser), src_(), end_(), count_() {} + + char Peek() const { + std::unique_lock<std::mutex> lock(parser_.mutex_); + + // If nothing in stream, block to wait. + while (Empty()) + parser_.notEmpty_.wait(lock); + + return *src_; + } + + char Take() { + std::unique_lock<std::mutex> lock(parser_.mutex_); + + // If nothing in stream, block to wait. + while (Empty()) + parser_.notEmpty_.wait(lock); + + count_++; + char c = *src_++; + + // If all stream is read up, notify that the stream is finish. + if (Empty()) + parser_.finish_.notify_one(); + + return c; + } + + size_t Tell() const { return count_; } + + // Not implemented + char* PutBegin() { return 0; } + void Put(char) {} + void Flush() {} + size_t PutEnd(char*) { return 0; } + + bool Empty() const { return src_ == end_; } + + AsyncDocumentParser& parser_; + const char* src_; //!< Current read position. + const char* end_; //!< End of buffer + size_t count_; //!< Number of characters taken so far. + }; + + AsyncStringStream stream_; + Document& d_; + std::thread parseThread_; + std::mutex mutex_; + std::condition_variable notEmpty_; + std::condition_variable finish_; + bool completed_; +}; + +int main() { + Document d; + + { + AsyncDocumentParser<> parser(d); + + const char json1[] = " { \"hello\" : \"world\", \"t\" : tr"; + //const char json1[] = " { \"hello\" : \"world\", \"t\" : trX"; // Fot test parsing error + const char json2[] = "ue, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.14"; + const char json3[] = "16, \"a\":[1, 2, 3, 4] } "; + + parser.ParsePart(json1, sizeof(json1) - 1); + parser.ParsePart(json2, sizeof(json2) - 1); + parser.ParsePart(json3, sizeof(json3) - 1); + } + + if (d.HasParseError()) { + std::cout << "Error at offset " << d.GetErrorOffset() << ": " << GetParseError_En(d.GetParseError()) << std::endl; + return EXIT_FAILURE; + } + + // Stringify the JSON to cout + OStreamWrapper os(std::cout); + Writer<OStreamWrapper> writer(os); + d.Accept(writer); + std::cout << std::endl; + + return EXIT_SUCCESS; +} + +#else // Not supporting C++11 + +#include <iostream> +int main() { + std::cout << "This example requires C++11 compiler" << std::endl; +} + +#endif diff --git a/3rdparty/rapidjson/example/simplereader/simplereader.cpp b/3rdparty/rapidjson/example/simplereader/simplereader.cpp index edbdb6352c5..5aae8a1c0ac 100644 --- a/3rdparty/rapidjson/example/simplereader/simplereader.cpp +++ b/3rdparty/rapidjson/example/simplereader/simplereader.cpp @@ -12,6 +12,10 @@ struct MyHandler { bool Int64(int64_t i) { cout << "Int64(" << i << ")" << 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 RawNumber(const char* str, SizeType length, bool copy) { + cout << "Number(" << str << ", " << length << ", " << boolalpha << copy << ")" << endl; + return true; + } bool String(const char* str, SizeType length, bool copy) { cout << "String(" << str << ", " << length << ", " << boolalpha << copy << ")" << endl; return true; diff --git a/3rdparty/rapidjson/example/simplewriter/simplewriter.cpp b/3rdparty/rapidjson/example/simplewriter/simplewriter.cpp index f8891504bc8..8d1275c2923 100644 --- a/3rdparty/rapidjson/example/simplewriter/simplewriter.cpp +++ b/3rdparty/rapidjson/example/simplewriter/simplewriter.cpp @@ -9,26 +9,27 @@ int main() { StringBuffer s; Writer<StringBuffer> writer(s); - writer.StartObject(); - writer.String("hello"); - writer.String("world"); - writer.String("t"); + writer.StartObject(); // Between StartObject()/EndObject(), + writer.Key("hello"); // output a key, + writer.String("world"); // follow by a value. + writer.Key("t"); writer.Bool(true); - writer.String("f"); + writer.Key("f"); writer.Bool(false); - writer.String("n"); + writer.Key("n"); writer.Null(); - writer.String("i"); + writer.Key("i"); writer.Uint(123); - writer.String("pi"); + writer.Key("pi"); writer.Double(3.1416); - writer.String("a"); - writer.StartArray(); + writer.Key("a"); + writer.StartArray(); // Between StartArray()/EndArray(), for (unsigned i = 0; i < 4; i++) - writer.Uint(i); + writer.Uint(i); // all values are elements of the array. writer.EndArray(); writer.EndObject(); + // {"hello":"world","t":true,"f":false,"n":null,"i":123,"pi":3.1416,"a":[0,1,2,3]} cout << s.GetString() << endl; return 0; |