http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/stream.zh-cn.md ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/stream.zh-cn.md b/thirdparty/rapidjson-1.1.0/doc/stream.zh-cn.md new file mode 100644 index 0000000..f2c54f7 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/stream.zh-cn.md @@ -0,0 +1,426 @@ +# æµ + +å¨ RapidJSON ä¸ï¼`rapidjson::Stream` æ¯ç¨æ¼è¯»å JSON çæ¦å¿µï¼æ¦å¿µæ¯æ C++ ç conceptï¼ãå¨è¿éæä»¬å ä»ç»å¦ä½ä½¿ç¨ RapidJSON æä¾çåç§æµãç¶ååççå¦ä½èªè¡å®ä¹æµã + +[TOC] + +# å åæµ {#MemoryStreams} + +å åæµæ JSON åå¨å¨å åä¹ä¸ã + +## StringStreamï¼è¾å ¥ï¼{#StringStream} + +`StringStream` æ¯æåºæ¬çè¾å ¥æµï¼å®è¡¨ç¤ºä¸ä¸ªå®æ´çãåªè¯»çãåå¨äºå åç JSONãå®å¨ `rapidjson/rapidjson.h` ä¸å®ä¹ã + +~~~~~~~~~~cpp +#include "rapidjson/document.h" // ä¼å å« "rapidjson/rapidjson.h" + +using namespace rapidjson; + +// ... +const char json[] = "[1, 2, 3, 4]"; +StringStream s(json); + +Document d; +d.ParseStream(s); +~~~~~~~~~~ + +ç±äºè¿æ¯é常常ç¨çç¨æ³ï¼RapidJSON æä¾ `Document::Parse(const char*)` å»åå®å ¨ç¸åçäºæ ï¼ + +~~~~~~~~~~cpp +// ... +const char json[] = "[1, 2, 3, 4]"; +Document d; +d.Parse(json); +~~~~~~~~~~ + +éè¦æ³¨æï¼`StringStream` æ¯ `GenericStringStream<UTF8<> >` ç typedefï¼ä½¿ç¨è å¯ç¨å ¶ä»ç¼ç ç±»å»ä»£è¡¨æµæä½¿ç¨çå符éã + +## StringBufferï¼è¾åºï¼{#StringBuffer} + +`StringBuffer` æ¯ä¸ä¸ªç®åçè¾åºæµãå®åé ä¸ä¸ªå åç¼å²åºï¼ä¾åå ¥æ´ä¸ª JSONãå¯ä½¿ç¨ `GetString()` æ¥è·å该ç¼å²åºã + +~~~~~~~~~~cpp +#include "rapidjson/stringbuffer.h" + +StringBuffer buffer; +Writer<StringBuffer> writer(buffer); +d.Accept(writer); + +const char* output = buffer.GetString(); +~~~~~~~~~~ + +å½ç¼å²åºæ»¡æº¢ï¼å®å°èªå¨å¢å 容éã缺ç容鿝 256 个å符ï¼UTF8 æ¯ 256 åèï¼UTF16 æ¯ 512 åèçï¼ã使ç¨è è½èªè¡æä¾åé å¨ååå§å®¹éã + +~~~~~~~~~~cpp +StringBuffer buffer1(0, 1024); // 使ç¨å®çåé å¨ï¼åå§å¤§å° = 1024 +StringBuffer buffer2(allocator, 1024); +~~~~~~~~~~ + +妿 设置åé å¨ï¼`StringBuffer` ä¼èªè¡å®ä¾åä¸ä¸ªå é¨åé å¨ã + +ç¸ä¼¼å°ï¼`StringBuffer` æ¯ `GenericStringBuffer<UTF8<> >` ç typedefã + +# æä»¶æµ {#FileStreams} + +å½è¦ä»æä»¶è§£æä¸ä¸ª JSONï¼ä½ å¯ä»¥ææ´ä¸ª JSON è¯»å ¥å å并使ç¨ä¸è¿°ç `StringStream`ã + +ç¶èï¼è¥ JSON å¾å¤§ï¼ææ¯å åæéï¼ä½ å¯ä»¥æ¹ç¨ `FileReadStream`ãå®åªä¼ä»æä»¶è¯»åä¸é¨åè³ç¼å²åºï¼ç¶å让é£é¨å被解æãè¥ç¼å²åºçå符é½è¢«è¯»å®ï¼å®ä¼åä»æä»¶è¯»åä¸ä¸é¨åã + +## FileReadStreamï¼è¾å ¥ï¼ {#FileReadStream} + +`FileReadStream` éè¿ `FILE` æé读åæä»¶ã使ç¨è éè¦æä¾ä¸ä¸ªç¼å²åºã + +~~~~~~~~~~cpp +#include "rapidjson/filereadstream.h" +#include <cstdio> + +using namespace rapidjson; + +FILE* fp = fopen("big.json", "rb"); // é Windows å¹³å°ä½¿ç¨ "r" + +char readBuffer[65536]; +FileReadStream is(fp, readBuffer, sizeof(readBuffer)); + +Document d; +d.ParseStream(is); + +fclose(fp); +~~~~~~~~~~ + +ä¸ `StringStreams` ä¸ä¸æ ·ï¼`FileReadStream` æ¯ä¸ä¸ªåèæµãå®ä¸å¤çç¼ç ãè¥æä»¶å¹¶é UTF-8 ç¼ç ï¼å¯ä»¥æåèæµç¨ `EncodedInputStream` å è£ ãæä»¬å¾å¿«ä¼è®¨è®ºè¿ä¸ªé®é¢ã + +é¤äºè¯»åæä»¶ï¼ä½¿ç¨è ä¹å¯ä»¥ä½¿ç¨ `FileReadStream` æ¥è¯»å `stdin`ã + +## FileWriteStreamï¼è¾åºï¼{#FileWriteStream} + +`FileWriteStream` æ¯ä¸ä¸ªå«ç¼å²åè½çè¾åºæµãå®çç¨æ³ä¸ `FileReadStream` é常ç¸ä¼¼ã + +~~~~~~~~~~cpp +#include "rapidjson/filewritestream.h" +#include <cstdio> + +using namespace rapidjson; + +Document d; +d.Parse(json); +// ... + +FILE* fp = fopen("output.json", "wb"); // é Windows å¹³å°ä½¿ç¨ "w" + +char writeBuffer[65536]; +FileWriteStream os(fp, writeBuffer, sizeof(writeBuffer)); + +Writer<FileWriteStream> writer(os); +d.Accept(writer); + +fclose(fp); +~~~~~~~~~~ + +å®ä¹å¯ä»¥æè¾åºå¯¼å `stdout`ã + +# iostream å è£ ç±» {#iostreamWrapper} + +åºäºç¨æ·çè¦æ±ï¼RapidJSON æä¾äºæ£å¼ç `std::basic_istream` å `std::basic_ostream` å è£ ç±»ãç¶èï¼è¯·æ³¨æå ¶æ§è½ä¼å¤§å¤§ä½äºä»¥ä¸çå ¶ä»æµã + +## IStreamWrapper {#IStreamWrapper} + +`IStreamWrapper` æä»»ä½ç»§æ¿èª `std::istream` çç±»ï¼å¦ `std::istringstream`ã`std::stringstream`ã`std::ifstream`ã`std::fstream`ï¼å è£ æ RapidJSON çè¾å ¥æµã + +~~~cpp +#include <rapidjson/document.h> +#include <rapidjson/istreamwrapper.h> +#include <fstream> + +using namespace rapidjson; +using namespace std; + +ifstream ifs("test.json"); +IStreamWrapper isw(ifs); + +Document d; +d.ParseStream(isw); +~~~ + +对äºç»§æ¿èª `std::wistream` çç±»ï¼åä½¿ç¨ `WIStreamWrapper`ã + +## OStreamWrapper {#OStreamWrapper} + +ç¸ä¼¼å°ï¼`OStreamWrapper` æä»»ä½ç»§æ¿èª `std::ostream` çç±»ï¼å¦ `std::ostringstream`ã`std::stringstream`ã`std::ofstream`ã`std::fstream`ï¼å è£ æ RapidJSON çè¾åºæµã + +~~~cpp +#include <rapidjson/document.h> +#include <rapidjson/ostreamwrapper.h> +#include <rapidjson/writer.h> +#include <fstream> + +using namespace rapidjson; +using namespace std; + +Document d; +d.Parse(json); + +// ... + +ofstream ofs("output.json"); +OStreamWrapper osw(ofs); + +Writer<OStreamWrapper> writer(osw); +d.Accept(writer); +~~~ + +对äºç»§æ¿èª `std::wistream` çç±»ï¼åä½¿ç¨ `WIStreamWrapper`ã + +# ç¼ç æµ {#EncodedStreams} + +ç¼ç æµï¼encoded streamsï¼æ¬èº«ä¸åå¨ JSONï¼å®ä»¬æ¯éè¿å è£ åèæµæ¥æä¾åºæ¬çç¼ç ï¼è§£ç åè½ã + +å¦ä¸æè¿°ï¼æä»¬å¯ä»¥ç´æ¥è¯»å ¥ UTF-8 åèæµãç¶èï¼UTF-16 å UTF-32 æåèåºï¼endianï¼é®é¢ãè¦æ£ç¡®å°å¤çåèåºï¼éè¦å¨è¯»åæ¶æåèè½¬æ¢æå符ï¼å¦å¯¹ UTF-16 ä½¿ç¨ `wchar_t`ï¼ï¼ä»¥åå¨åå ¥æ¶æå符转æ¢ä¸ºåèã + +餿¤ä»¥å¤ï¼æä»¬ä¹éè¦å¤ç [åèé¡ºåºæ è®°ï¼byte order mark, BOMï¼](http://en.wikipedia.org/wiki/Byte_order_mark)ãå½ä»ä¸ä¸ªåèæµè¯»åæ¶ï¼éè¦æ£æµ BOMï¼æè ä» ä» æ¯æåå¨ç BOM æ¶å»ã彿 JSON åå ¥åèæµæ¶ï¼ä¹å¯éæ©åå ¥ BOMã + +è¥ä¸ä¸ªæµçç¼ç å¨ç¼è¯æå·²ç¥ï¼ä½ å¯ä½¿ç¨ `EncodedInputStream` å `EncodedOutputStream`ãè¥ä¸ä¸ªæµå¯è½åå¨ UTF-8ãUTF-16LEãUTF-16BEãUTF-32LEãUTF-32BE ç JSONï¼å¹¶ä¸ç¼ç åªè½å¨è¿è¡æ¶å¾ç¥ï¼ä½ 便å¯ä»¥ä½¿ç¨ `AutoUTFInputStream` å `AutoUTFOutputStream`ãè¿äºæµå®ä¹å¨ `rapidjson/encodedstream.h`ã + +注æå°ï¼è¿äºç¼ç æµå¯ä»¥æ½äºæä»¶ä»¥å¤çæµãä¾å¦ï¼ä½ å¯ä»¥ç¨ç¼ç æµå è£ å åä¸çæä»¶æèªå®ä¹çåèæµã + +## EncodedInputStream {#EncodedInputStream} + +`EncodedInputStream` å«ä¸¤ä¸ªæ¨¡æ¿åæ°ã第ä¸ä¸ªæ¯ `Encoding` ç±»åï¼ä¾å¦å®ä¹äº `rapidjson/encodings.h` ç `UTF8`ã`UTF16LE`ã第äºä¸ªåæ°æ¯è¢«å è£ çæµçç±»åã + +~~~~~~~~~~cpp +#include "rapidjson/document.h" +#include "rapidjson/filereadstream.h" // FileReadStream +#include "rapidjson/encodedstream.h" // EncodedInputStream +#include <cstdio> + +using namespace rapidjson; + +FILE* fp = fopen("utf16le.json", "rb"); // é Windows å¹³å°ä½¿ç¨ "r" + +char readBuffer[256]; +FileReadStream bis(fp, readBuffer, sizeof(readBuffer)); + +EncodedInputStream<UTF16LE<>, FileReadStream> eis(bis); // ç¨ eis å è£ bis + +Document d; // Document 为 GenericDocument<UTF8<> > +d.ParseStream<0, UTF16LE<> >(eis); // æ UTF-16LE æä»¶è§£æè³å åä¸ç UTF-8 + +fclose(fp); +~~~~~~~~~~ + +## EncodedOutputStream {#EncodedOutputStream} + +`EncodedOutputStream` 乿¯ç¸ä¼¼çï¼ä½å®çæé 彿°æä¸ä¸ª `bool putBOM` åæ°ï¼ç¨äºæ§å¶æ¯å¦å¨è¾åºåèæµåå ¥ BOMã + +~~~~~~~~~~cpp +#include "rapidjson/filewritestream.h" // FileWriteStream +#include "rapidjson/encodedstream.h" // EncodedOutputStream +#include <cstdio> + +Document d; // Document 为 GenericDocument<UTF8<> > +// ... + +FILE* fp = fopen("output_utf32le.json", "wb"); // é Windows å¹³å°ä½¿ç¨ "w" + +char writeBuffer[256]; +FileWriteStream bos(fp, writeBuffer, sizeof(writeBuffer)); + +typedef EncodedOutputStream<UTF32LE<>, FileWriteStream> OutputStream; +OutputStream eos(bos, true); // åå ¥ BOM + +Writer<OutputStream, UTF32LE<>, UTF8<>> writer(eos); +d.Accept(writer); // è¿éä»å åç UTF-8 çæ UTF32-LE æä»¶ + +fclose(fp); +~~~~~~~~~~ + +## AutoUTFInputStream {#AutoUTFInputStream} + +ææ¶åï¼åºç¨è½¯ä»¶å¯è½éè¦ã²çææå¯æ¯æç JSON ç¼ç ã`AutoUTFInputStream` ä¼å ä½¿ç¨ BOM æ¥æ£æµç¼ç ãè¥ BOM ä¸åå¨ï¼å®ä¾¿ä¼ä½¿ç¨åæ³ JSON çç¹æ§æ¥æ£æµãè¥ä¸¤ç§æ¹æ³é½å¤±è´¥ï¼å®å°±ä¼åéè³æé 彿°æä¾ç UTF ç±»åã + +ç±äºå符ï¼ç¼ç åå ï¼code unitï¼å¯è½æ¯ 8 ä½ã16 使 32 ä½ï¼`AutoUTFInputStream` éè¦ä¸ä¸ªè½è³å°å¨å 32 ä½çå符类åãæä»¬å¯ä»¥ä½¿ç¨ `unsigned` ä½ä¸ºæ¨¡æ¿åæ°ï¼ + +~~~~~~~~~~cpp +#include "rapidjson/document.h" +#include "rapidjson/filereadstream.h" // FileReadStream +#include "rapidjson/encodedstream.h" // AutoUTFInputStream +#include <cstdio> + +using namespace rapidjson; + +FILE* fp = fopen("any.json", "rb"); // é Windows å¹³å°ä½¿ç¨ "r" + +char readBuffer[256]; +FileReadStream bis(fp, readBuffer, sizeof(readBuffer)); + +AutoUTFInputStream<unsigned, FileReadStream> eis(bis); // ç¨ eis å è£ bis + +Document d; // Document 为 GenericDocument<UTF8<> > +d.ParseStream<0, AutoUTF<unsigned> >(eis); // æä»»ä½ UTF ç¼ç çæä»¶è§£æè³å åä¸ç UTF-8 + +fclose(fp); +~~~~~~~~~~ + +å½è¦æå®æµçç¼ç ï¼å¯ä½¿ç¨ä¸é¢ä¾åä¸ `ParseStream()` çåæ° `AutoUTF<CharType>`ã + +ä½ å¯ä»¥ä½¿ç¨ `UTFType GetType()` å»è·å UTF ç±»åï¼å¹¶ä¸ç¨ `HasBOM()` æ£æµè¾å ¥æµæ¯å¦å«æ BOMã + +## AutoUTFOutputStream {#AutoUTFOutputStream} + +ç¸ä¼¼å°ï¼è¦å¨è¿è¡æ¶éæ©è¾åºçç¼ç ï¼æä»¬å¯ä½¿ç¨ `AutoUTFOutputStream`ãè¿ä¸ªç±»æ¬èº«å¹¶éãèªå¨ããä½ éè¦å¨è¿è¡æ¶æå® UTF ç±»åï¼ä»¥åæ¯å¦åå ¥ BOMã + +~~~~~~~~~~cpp +using namespace rapidjson; + +void WriteJSONFile(FILE* fp, UTFType type, bool putBOM, const Document& d) { + char writeBuffer[256]; + FileWriteStream bos(fp, writeBuffer, sizeof(writeBuffer)); + + typedef AutoUTFOutputStream<unsigned, FileWriteStream> OutputStream; + OutputStream eos(bos, type, putBOM); + + Writer<OutputStream, UTF8<>, AutoUTF<> > writer; + d.Accept(writer); +} +~~~~~~~~~~ + +`AutoUTFInputStream`ï¼`AutoUTFOutputStream` æ¯æ¯ `EncodedInputStream`ï¼`EncodedOutputStream` æ¹ä¾¿ãä½åè ä¼äº§çä¸ç¹è¿è¡æé¢å¤å¼éã + +# èªå®ä¹æµ {#CustomStream} + +é¤äºå åï¼æä»¶æµï¼ä½¿ç¨è å¯å建èªè¡å®ä¹éé RapidJSON API çæµç±»ãä¾å¦ï¼ä½ å¯ä»¥å建ç½ç»æµãä»å缩æä»¶è¯»åçæµççã + +RapidJSON å©ç¨æ¨¡æ¿ç»åä¸åçç±»åãåªè¦ä¸ä¸ªç±»å 嫿ææéçæ¥å£ï¼å°±å¯ä»¥ä½ä¸ºä¸ä¸ªæµãæµçæ¥åå®ä¹å¨ `rapidjson/rapidjson.h` çæ³¨ééï¼ + +~~~~~~~~~~cpp +concept Stream { + typename Ch; //!< æµçå符类å + + //! 仿µè¯»åå½åå符ï¼ä¸ç§»å¨è¯»åæéï¼read cursorï¼ + Ch Peek() const; + + //! 仿µè¯»åå½åå符ï¼ç§»å¨è¯»åæéè³ä¸ä¸å符ã + Ch Take(); + + //! è·å读åæéã + //! \return ä»å¼å§ä»¥æ¥æè¯»è¿çå符æ°éã + size_t Tell(); + + //! ä»å½å读åæéå¼å§åå ¥æä½ã + //! \return è¿åå¼å§åå ¥çæéã + Ch* PutBegin(); + + //! åå ¥ä¸ä¸ªå符ã + void Put(Ch c); + + //! æ¸ ç©ºç¼å²åºã + void Flush(); + + //! 宿å使ä½ã + //! \param begin PutBegin() è¿åçå¼å§åå ¥æéã + //! \return å·²åå ¥çå符æ°éã + size_t PutEnd(Ch* begin); +} +~~~~~~~~~~ + +è¾å ¥æµå¿ é¡»å®ç° `Peek()`ã`Take()` å `Tell()`ã +è¾åºæµå¿ é¡»å®ç° `Put()` å `Flush()`ã +`PutBegin()` å `PutEnd()` æ¯ç¹æ®çæ¥å£ï¼ä» ç¨äºåä½ï¼*in situ*ï¼è§£æãä¸è¬çæµä¸éå®ç°å®ä»¬ãç¶èï¼å³ä½¿æ¥å£ä¸éç¨äºæäºæµï¼ä»ç¶éè¦æä¾ç©ºå®ç°ï¼å¦åä¼äº§çç¼è¯é误ã + +## ä¾åï¼istream çå è£ ç±» {#ExampleIStreamWrapper} + +以ä¸çç®åä¾åæ¯ `std::istream` çå è£ ç±»ï¼å®åªéç° 3 ä¸ªå½æ°ã + +~~~~~~~~~~cpp +class MyIStreamWrapper { +public: + typedef char Ch; + + MyIStreamWrapper(std::istream& is) : is_(is) { + } + + Ch Peek() const { // 1 + int c = is_.peek(); + return c == std::char_traits<char>::eof() ? '\0' : (Ch)c; + } + + Ch Take() { // 2 + int c = is_.get(); + return c == std::char_traits<char>::eof() ? '\0' : (Ch)c; + } + + size_t Tell() const { return (size_t)is_.tellg(); } // 3 + + Ch* PutBegin() { assert(false); return 0; } + void Put(Ch) { assert(false); } + void Flush() { assert(false); } + size_t PutEnd(Ch*) { assert(false); return 0; } + +private: + MyIStreamWrapper(const MyIStreamWrapper&); + MyIStreamWrapper& operator=(const MyIStreamWrapper&); + + std::istream& is_; +}; +~~~~~~~~~~ + +使ç¨è è½ç¨å®æ¥å è£ `std::stringstream`ã`std::ifstream` çå®ä¾ã + +~~~~~~~~~~cpp +const char* json = "[1,2,3,4]"; +std::stringstream ss(json); +MyIStreamWrapper is(ss); + +Document d; +d.ParseStream(is); +~~~~~~~~~~ + +ä½è¦æ³¨æï¼ç±äºæ ååºçå é¨å¼éé®ï¼æ¤å®ç°çæ§è½å¯è½ä¸å¦ RapidJSON çå åï¼æä»¶æµã + +## ä¾åï¼ostream çå è£ ç±» {#ExampleOStreamWrapper} + +以ä¸çä¾åæ¯ `std::istream` çå è£ ç±»ï¼å®åªéå®ç° 2 ä¸ªå½æ°ã + +~~~~~~~~~~cpp +class MyOStreamWrapper { +public: + typedef char Ch; + + OStreamWrapper(std::ostream& os) : os_(os) { + } + + Ch Peek() const { assert(false); return '\0'; } + Ch Take() { assert(false); return '\0'; } + size_t Tell() const { } + + Ch* PutBegin() { assert(false); return 0; } + void Put(Ch c) { os_.put(c); } // 1 + void Flush() { os_.flush(); } // 2 + size_t PutEnd(Ch*) { assert(false); return 0; } + +private: + MyOStreamWrapper(const MyOStreamWrapper&); + MyOStreamWrapper& operator=(const MyOStreamWrapper&); + + std::ostream& os_; +}; +~~~~~~~~~~ + +使ç¨è è½ç¨å®æ¥å è£ `std::stringstream`ã`std::ofstream` çå®ä¾ã + +~~~~~~~~~~cpp +Document d; +// ... + +std::stringstream ss; +MyOStreamWrapper os(ss); + +Writer<MyOStreamWrapper> writer(os); +d.Accept(writer); +~~~~~~~~~~ + +ä½è¦æ³¨æï¼ç±äºæ ååºçå é¨å¼éé®ï¼æ¤å®ç°çæ§è½å¯è½ä¸å¦ RapidJSON çå åï¼æä»¶æµã + +# æ»ç» {#Summary} + +æ¬èæè¿°äº RapidJSON æä¾çåç§æµçç±»ãå åæµå¾ç®åãè¥ JSON åå¨å¨æä»¶ä¸ï¼æä»¶æµå¯åå° JSON è§£æåçææéçå åéãç¼ç æµå¨åèæµåå符æµä¹é´ä½è½¬æ¢ãæåï¼ä½¿ç¨è å¯ä½¿ç¨ä¸ä¸ªç®åæ¥å£å建èªå®ä¹çæµã
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/tutorial.md ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/tutorial.md b/thirdparty/rapidjson-1.1.0/doc/tutorial.md new file mode 100644 index 0000000..cb76b4b --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/tutorial.md @@ -0,0 +1,536 @@ +# Tutorial + +This tutorial introduces the basics of the Document Object Model(DOM) API. + +As shown in [Usage at a glance](@ref index), a JSON can be parsed into DOM, and then the DOM can be queried and modified easily, and finally be converted back to JSON. + +[TOC] + +# Value & Document {#ValueDocument} + +Each JSON value is stored in a type called `Value`. A `Document`, representing the DOM, contains the root `Value` of the DOM tree. All public types and functions of RapidJSON are defined in the `rapidjson` namespace. + +# Query Value {#QueryValue} + +In this section, we will use excerpt of `example/tutorial/tutorial.cpp`. + +Assumes we have a JSON stored in a C string (`const char* json`): +~~~~~~~~~~js +{ + "hello": "world", + "t": true , + "f": false, + "n": null, + "i": 123, + "pi": 3.1416, + "a": [1, 2, 3, 4] +} +~~~~~~~~~~ + +Parse it into a `Document`: +~~~~~~~~~~cpp +#include "rapidjson/document.h" + +using namespace rapidjson; + +// ... +Document document; +document.Parse(json); +~~~~~~~~~~ + +The JSON is now parsed into `document` as a *DOM tree*: + + + +Since the update to RFC 7159, the root of a conforming JSON document can be any JSON value. In earlier RFC 4627, only objects or arrays were allowed as root values. In this case, the root is an object. +~~~~~~~~~~cpp +assert(document.IsObject()); +~~~~~~~~~~ + +Let's query whether a `"hello"` member exists in the root object. Since a `Value` can contain different types of value, we may need to verify its type and use suitable API to obtain the value. In this example, `"hello"` member associates with a JSON string. +~~~~~~~~~~cpp +assert(document.HasMember("hello")); +assert(document["hello"].IsString()); +printf("hello = %s\n", document["hello"].GetString()); +~~~~~~~~~~ + +~~~~~~~~~~ +world +~~~~~~~~~~ + +JSON true/false values are represented as `bool`. +~~~~~~~~~~cpp +assert(document["t"].IsBool()); +printf("t = %s\n", document["t"].GetBool() ? "true" : "false"); +~~~~~~~~~~ + +~~~~~~~~~~ +true +~~~~~~~~~~ + +JSON null can be queryed by `IsNull()`. +~~~~~~~~~~cpp +printf("n = %s\n", document["n"].IsNull() ? "null" : "?"); +~~~~~~~~~~ + +~~~~~~~~~~ +null +~~~~~~~~~~ + +JSON number type represents all numeric values. However, C++ needs more specific type for manipulation. + +~~~~~~~~~~cpp +assert(document["i"].IsNumber()); + +// In this case, IsUint()/IsInt64()/IsUInt64() also return true. +assert(document["i"].IsInt()); +printf("i = %d\n", document["i"].GetInt()); +// Alternative (int)document["i"] + +assert(document["pi"].IsNumber()); +assert(document["pi"].IsDouble()); +printf("pi = %g\n", document["pi"].GetDouble()); +~~~~~~~~~~ + +~~~~~~~~~~ +i = 123 +pi = 3.1416 +~~~~~~~~~~ + +JSON array contains a number of elements. +~~~~~~~~~~cpp +// Using a reference for consecutive access is handy and faster. +const Value& a = document["a"]; +assert(a.IsArray()); +for (SizeType i = 0; i < a.Size(); i++) // Uses SizeType instead of size_t + printf("a[%d] = %d\n", i, a[i].GetInt()); +~~~~~~~~~~ + +~~~~~~~~~~ +a[0] = 1 +a[1] = 2 +a[2] = 3 +a[3] = 4 +~~~~~~~~~~ + +Note that, RapidJSON does not automatically convert values between JSON types. If a value is a string, it is invalid to call `GetInt()`, for example. In debug mode it will fail an assertion. In release mode, the behavior is undefined. + +In the following, details about querying individual types are discussed. + +## Query Array {#QueryArray} + +By default, `SizeType` is typedef of `unsigned`. In most systems, array is limited to store up to 2^32-1 elements. + +You may access the elements in array by integer literal, for example, `a[0]`, `a[1]`, `a[2]`. + +Array is similar to `std::vector`, instead of using indices, you may also use iterator to access all the elements. +~~~~~~~~~~cpp +for (Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr) + printf("%d ", itr->GetInt()); +~~~~~~~~~~ + +And other familiar query functions: +* `SizeType Capacity() const` +* `bool Empty() const` + +### Range-based For Loop (New in v1.1.0) + +When C++11 is enabled, you can use range-based for loop to access all elements in an array. + +~~~~~~~~~~cpp +for (auto& v : a.GetArray()) + printf("%d ", v.GetInt()); +~~~~~~~~~~ + +## Query Object {#QueryObject} + +Similar to array, we can access all object members by iterator: + +~~~~~~~~~~cpp +static const char* kTypeNames[] = + { "Null", "False", "True", "Object", "Array", "String", "Number" }; + +for (Value::ConstMemberIterator itr = document.MemberBegin(); + itr != document.MemberEnd(); ++itr) +{ + printf("Type of member %s is %s\n", + itr->name.GetString(), kTypeNames[itr->value.GetType()]); +} +~~~~~~~~~~ + +~~~~~~~~~~ +Type of member hello is String +Type of member t is True +Type of member f is False +Type of member n is Null +Type of member i is Number +Type of member pi is Number +Type of member a is Array +~~~~~~~~~~ + +Note that, when `operator[](const char*)` cannot find the member, it will fail an assertion. + +If we are unsure whether a member exists, we need to call `HasMember()` before calling `operator[](const char*)`. However, this incurs two lookup. A better way is to call `FindMember()`, which can check the existence of member and obtain its value at once: + +~~~~~~~~~~cpp +Value::ConstMemberIterator itr = document.FindMember("hello"); +if (itr != document.MemberEnd()) + printf("%s\n", itr->value.GetString()); +~~~~~~~~~~ + +### Range-based For Loop (New in v1.1.0) + +When C++11 is enabled, you can use range-based for loop to access all members in an object. + +~~~~~~~~~~cpp +for (auto& m : document.GetObject()) + printf("Type of member %s is %s\n", + m.name.GetString(), kTypeNames[m.value.GetType()]); +~~~~~~~~~~ + +## Querying Number {#QueryNumber} + +JSON provide a single numerical type called Number. Number can be integer or real numbers. RFC 4627 says the range of Number is specified by parser. + +As C++ provides several integer and floating point number types, the DOM tries to handle these with widest possible range and good performance. + +When a Number is parsed, it is stored in the DOM as either one of the following type: + +Type | Description +-----------|--------------------------------------- +`unsigned` | 32-bit unsigned integer +`int` | 32-bit signed integer +`uint64_t` | 64-bit unsigned integer +`int64_t` | 64-bit signed integer +`double` | 64-bit double precision floating point + +When querying a number, you can check whether the number can be obtained as target type: + +Checking | Obtaining +------------------|--------------------- +`bool IsNumber()` | N/A +`bool IsUint()` | `unsigned GetUint()` +`bool IsInt()` | `int GetInt()` +`bool IsUint64()` | `uint64_t GetUint64()` +`bool IsInt64()` | `int64_t GetInt64()` +`bool IsDouble()` | `double GetDouble()` + +Note that, an integer value may be obtained in various ways without conversion. For example, A value `x` containing 123 will make `x.IsInt() == x.IsUint() == x.IsInt64() == x.IsUint64() == true`. But a value `y` containing -3000000000 will only makes `x.IsInt64() == true`. + +When obtaining the numeric values, `GetDouble()` will convert internal integer representation to a `double`. Note that, `int` and `unsigned` can be safely convert to `double`, but `int64_t` and `uint64_t` may lose precision (since mantissa of `double` is only 52-bits). + +## Query String {#QueryString} + +In addition to `GetString()`, the `Value` class also contains `GetStringLength()`. Here explains why. + +According to RFC 4627, JSON strings can contain Unicode character `U+0000`, which must be escaped as `"\u0000"`. The problem is that, C/C++ often uses null-terminated string, which treats ``\0'` as the terminator symbol. + +To conform RFC 4627, RapidJSON supports string containing `U+0000`. If you need to handle this, you can use `GetStringLength()` API to obtain the correct length of string. + +For example, after parsing a the following JSON to `Document d`: + +~~~~~~~~~~js +{ "s" : "a\u0000b" } +~~~~~~~~~~ +The correct length of the value `"a\u0000b"` is 3. But `strlen()` returns 1. + +`GetStringLength()` can also improve performance, as user may often need to call `strlen()` for allocating buffer. + +Besides, `std::string` also support a constructor: + +~~~~~~~~~~cpp +string(const char* s, size_t count); +~~~~~~~~~~ + +which accepts the length of string as parameter. This constructor supports storing null character within the string, and should also provide better performance. + +## Comparing values + +You can use `==` and `!=` to compare values. Two values are equal if and only if they are have same type and contents. You can also compare values with primitive types. Here is an example. + +~~~~~~~~~~cpp +if (document["hello"] == document["n"]) /*...*/; // Compare values +if (document["hello"] == "world") /*...*/; // Compare value with literal string +if (document["i"] != 123) /*...*/; // Compare with integers +if (document["pi"] != 3.14) /*...*/; // Compare with double. +~~~~~~~~~~ + +Array/object compares their elements/members in order. They are equal if and only if their whole subtrees are equal. + +Note that, currently if an object contains duplicated named member, comparing equality with any object is always `false`. + +# Create/Modify Values {#CreateModifyValues} + +There are several ways to create values. After a DOM tree is created and/or modified, it can be saved as JSON again using `Writer`. + +## Change Value Type {#ChangeValueType} +When creating a Value or Document by default constructor, its type is Null. To change its type, call `SetXXX()` or assignment operator, for example: + +~~~~~~~~~~cpp +Document d; // Null +d.SetObject(); + +Value v; // Null +v.SetInt(10); +v = 10; // Shortcut, same as above +~~~~~~~~~~ + +### Overloaded Constructors +There are also overloaded constructors for several types: + +~~~~~~~~~~cpp +Value b(true); // calls Value(bool) +Value i(-123); // calls Value(int) +Value u(123u); // calls Value(unsigned) +Value d(1.5); // calls Value(double) +~~~~~~~~~~ + +To create empty object or array, you may use `SetObject()`/`SetArray()` after default constructor, or using the `Value(Type)` in one shot: + +~~~~~~~~~~cpp +Value o(kObjectType); +Value a(kArrayType); +~~~~~~~~~~ + +## Move Semantics {#MoveSemantics} + +A very special decision during design of RapidJSON is that, assignment of value does not copy the source value to destination value. Instead, the value from source is moved to the destination. For example, + +~~~~~~~~~~cpp +Value a(123); +Value b(456); +b = a; // a becomes a Null value, b becomes number 123. +~~~~~~~~~~ + + + +Why? What is the advantage of this semantics? + +The simple answer is performance. For fixed size JSON types (Number, True, False, Null), copying them is fast and easy. However, For variable size JSON types (String, Array, Object), copying them will incur a lot of overheads. And these overheads are often unnoticed. Especially when we need to create temporary object, copy it to another variable, and then destruct it. + +For example, if normal *copy* semantics was used: + +~~~~~~~~~~cpp +Document d; +Value o(kObjectType); +{ + Value contacts(kArrayType); + // adding elements to contacts array. + // ... + o.AddMember("contacts", contacts, d.GetAllocator()); // deep clone contacts (may be with lots of allocations) + // destruct contacts. +} +~~~~~~~~~~ + + + +The object `o` needs to allocate a buffer of same size as contacts, makes a deep clone of it, and then finally contacts is destructed. This will incur a lot of unnecessary allocations/deallocations and memory copying. + +There are solutions to prevent actual copying these data, such as reference counting and garbage collection(GC). + +To make RapidJSON simple and fast, we chose to use *move* semantics for assignment. It is similar to `std::auto_ptr` which transfer ownership during assignment. Move is much faster and simpler, it just destructs the original value, `memcpy()` the source to destination, and finally sets the source as Null type. + +So, with move semantics, the above example becomes: + +~~~~~~~~~~cpp +Document d; +Value o(kObjectType); +{ + Value contacts(kArrayType); + // adding elements to contacts array. + o.AddMember("contacts", contacts, d.GetAllocator()); // just memcpy() of contacts itself to the value of new member (16 bytes) + // contacts became Null here. Its destruction is trivial. +} +~~~~~~~~~~ + + + +This is called move assignment operator in C++11. As RapidJSON supports C++03, it adopts move semantics using assignment operator, and all other modifying function like `AddMember()`, `PushBack()`. + +### Move semantics and temporary values {#TemporaryValues} + +Sometimes, it is convenient to construct a Value in place, before passing it to one of the "moving" functions, like `PushBack()` or `AddMember()`. As temporary objects can't be converted to proper Value references, the convenience function `Move()` is available: + +~~~~~~~~~~cpp +Value a(kArrayType); +Document::AllocatorType& allocator = document.GetAllocator(); +// a.PushBack(Value(42), allocator); // will not compile +a.PushBack(Value().SetInt(42), allocator); // fluent API +a.PushBack(Value(42).Move(), allocator); // same as above +~~~~~~~~~~ + +## Create String {#CreateString} +RapidJSON provide two strategies for storing string. + +1. copy-string: allocates a buffer, and then copy the source data into it. +2. const-string: simply store a pointer of string. + +Copy-string is always safe because it owns a copy of the data. Const-string can be used for storing string literal, and in-situ parsing which we will mentioned in Document section. + +To make memory allocation customizable, RapidJSON requires user to pass an instance of allocator, whenever an operation may require allocation. This design is needed to prevent storing a allocator (or Document) pointer per Value. + +Therefore, when we assign a copy-string, we call this overloaded `SetString()` with allocator: + +~~~~~~~~~~cpp +Document document; +Value author; +char buffer[10]; +int len = sprintf(buffer, "%s %s", "Milo", "Yip"); // dynamically created string. +author.SetString(buffer, len, document.GetAllocator()); +memset(buffer, 0, sizeof(buffer)); +// author.GetString() still contains "Milo Yip" after buffer is destroyed +~~~~~~~~~~ + +In this example, we get the allocator from a `Document` instance. This is a common idiom when using RapidJSON. But you may use other instances of allocator. + +Besides, the above `SetString()` requires length. This can handle null characters within a string. There is another `SetString()` overloaded function without the length parameter. And it assumes the input is null-terminated and calls a `strlen()`-like function to obtain the length. + +Finally, for string literal or string with safe life-cycle can use const-string version of `SetString()`, which lacks allocator parameter. For string literals (or constant character arrays), simply passing the literal as parameter is safe and efficient: + +~~~~~~~~~~cpp +Value s; +s.SetString("rapidjson"); // can contain null character, length derived at compile time +s = "rapidjson"; // shortcut, same as above +~~~~~~~~~~ + +For character pointer, the RapidJSON requires to mark it as safe before using it without copying. This can be achieved by using the `StringRef` function: + +~~~~~~~~~cpp +const char * cstr = getenv("USER"); +size_t cstr_len = ...; // in case length is available +Value s; +// s.SetString(cstr); // will not compile +s.SetString(StringRef(cstr)); // ok, assume safe lifetime, null-terminated +s = StringRef(cstr); // shortcut, same as above +s.SetString(StringRef(cstr,cstr_len)); // faster, can contain null character +s = StringRef(cstr,cstr_len); // shortcut, same as above + +~~~~~~~~~ + +## Modify Array {#ModifyArray} +Value with array type provides similar APIs as `std::vector`. + +* `Clear()` +* `Reserve(SizeType, Allocator&)` +* `Value& PushBack(Value&, Allocator&)` +* `template <typename T> GenericValue& PushBack(T, Allocator&)` +* `Value& PopBack()` +* `ValueIterator Erase(ConstValueIterator pos)` +* `ValueIterator Erase(ConstValueIterator first, ConstValueIterator last)` + +Note that, `Reserve(...)` and `PushBack(...)` may allocate memory for the array elements, therefore require an allocator. + +Here is an example of `PushBack()`: + +~~~~~~~~~~cpp +Value a(kArrayType); +Document::AllocatorType& allocator = document.GetAllocator(); + +for (int i = 5; i <= 10; i++) + a.PushBack(i, allocator); // allocator is needed for potential realloc(). + +// Fluent interface +a.PushBack("Lua", allocator).PushBack("Mio", allocator); +~~~~~~~~~~ + +Differs from STL, `PushBack()`/`PopBack()` returns the array reference itself. This is called _fluent interface_. + +If you want to add a non-constant string or a string without sufficient lifetime (see [Create String](#CreateString)) to the array, you need to create a string Value by using the copy-string API. To avoid the need for an intermediate variable, you can use a [temporary value](#TemporaryValues) in place: + +~~~~~~~~~~cpp +// in-place Value parameter +contact.PushBack(Value("copy", document.GetAllocator()).Move(), // copy string + document.GetAllocator()); + +// explicit parameters +Value val("key", document.GetAllocator()); // copy string +contact.PushBack(val, document.GetAllocator()); +~~~~~~~~~~ + +## Modify Object {#ModifyObject} +Object is a collection of key-value pairs (members). Each key must be a string value. To modify an object, either add or remove members. THe following APIs are for adding members: + +* `Value& AddMember(Value&, Value&, Allocator& allocator)` +* `Value& AddMember(StringRefType, Value&, Allocator&)` +* `template <typename T> Value& AddMember(StringRefType, T value, Allocator&)` + +Here is an example. + +~~~~~~~~~~cpp +Value contact(kObject); +contact.AddMember("name", "Milo", document.GetAllocator()); +contact.AddMember("married", true, document.GetAllocator()); +~~~~~~~~~~ + +The name parameter with `StringRefType` is similar to the interface of `SetString` function for string values. These overloads are used to avoid the need for copying the `name` string, as constant key names are very common in JSON objects. + +If you need to create a name from a non-constant string or a string without sufficient lifetime (see [Create String](#CreateString)), you need to create a string Value by using the copy-string API. To avoid the need for an intermediate variable, you can use a [temporary value](#TemporaryValues) in place: + +~~~~~~~~~~cpp +// in-place Value parameter +contact.AddMember(Value("copy", document.GetAllocator()).Move(), // copy string + Value().Move(), // null value + document.GetAllocator()); + +// explicit parameters +Value key("key", document.GetAllocator()); // copy string name +Value val(42); // some value +contact.AddMember(key, val, document.GetAllocator()); +~~~~~~~~~~ + +For removing members, there are several choices: + +* `bool RemoveMember(const Ch* name)`: Remove a member by search its name (linear time complexity). +* `bool RemoveMember(const Value& name)`: same as above but `name` is a Value. +* `MemberIterator RemoveMember(MemberIterator)`: Remove a member by iterator (_constant_ time complexity). +* `MemberIterator EraseMember(MemberIterator)`: similar to the above but it preserves order of members (linear time complexity). +* `MemberIterator EraseMember(MemberIterator first, MemberIterator last)`: remove a range of members, preserves order (linear time complexity). + +`MemberIterator RemoveMember(MemberIterator)` uses a "move-last" trick to achieve constant time complexity. Basically the member at iterator is destructed, and then the last element is moved to that position. So the order of the remaining members are changed. + +## Deep Copy Value {#DeepCopyValue} +If we really need to copy a DOM tree, we can use two APIs for deep copy: constructor with allocator, and `CopyFrom()`. + +~~~~~~~~~~cpp +Document d; +Document::AllocatorType& a = d.GetAllocator(); +Value v1("foo"); +// Value v2(v1); // not allowed + +Value v2(v1, a); // make a copy +assert(v1.IsString()); // v1 untouched +d.SetArray().PushBack(v1, a).PushBack(v2, a); +assert(v1.IsNull() && v2.IsNull()); // both moved to d + +v2.CopyFrom(d, a); // copy whole document to v2 +assert(d.IsArray() && d.Size() == 2); // d untouched +v1.SetObject().AddMember("array", v2, a); +d.PushBack(v1, a); +~~~~~~~~~~ + +## Swap Values {#SwapValues} + +`Swap()` is also provided. + +~~~~~~~~~~cpp +Value a(123); +Value b("Hello"); +a.Swap(b); +assert(a.IsString()); +assert(b.IsInt()); +~~~~~~~~~~ + +Swapping two DOM trees is fast (constant time), despite the complexity of the trees. + +# What's next {#WhatsNext} + +This tutorial shows the basics of DOM tree query and manipulation. There are several important concepts in RapidJSON: + +1. [Streams](doc/stream.md) are channels for reading/writing JSON, which can be a in-memory string, or file stream, etc. User can also create their streams. +2. [Encoding](doc/encoding.md) defines which character encoding is used in streams and memory. RapidJSON also provide Unicode conversion/validation internally. +3. [DOM](doc/dom.md)'s basics are already covered in this tutorial. Uncover more advanced features such as *in situ* parsing, other parsing options and advanced usages. +4. [SAX](doc/sax.md) is the foundation of parsing/generating facility in RapidJSON. Learn how to use `Reader`/`Writer` to implement even faster applications. Also try `PrettyWriter` to format the JSON. +5. [Performance](doc/performance.md) shows some in-house and third-party benchmarks. +6. [Internals](doc/internals.md) describes some internal designs and techniques of RapidJSON. + +You may also refer to the [FAQ](doc/faq.md), API documentation, examples and unit tests. http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/tutorial.zh-cn.md ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/tutorial.zh-cn.md b/thirdparty/rapidjson-1.1.0/doc/tutorial.zh-cn.md new file mode 100644 index 0000000..61fb0b2 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/tutorial.zh-cn.md @@ -0,0 +1,534 @@ +# æç¨ + +æ¬æç¨ç®ä»æä»¶å¯¹è±¡æ¨¡åï¼Document Object Model, DOMï¼APIã + +å¦ [ç¨æ³ä¸è§](../readme.zh-cn.md#ç¨æ³ä¸è§) ä¸æç¤ºï¼å¯ä»¥è§£æä¸ä¸ª JSON è³ DOMï¼ç¶åå°±å¯ä»¥è½»æ¾æ¥è¯¢åä¿®æ¹ DOMï¼å¹¶æç»è½¬æ¢å JSONã + +[TOC] + +# Value å Document {#ValueDocument} + +æ¯ä¸ª JSON å¼é½å¨å为 `Value` ç±»ï¼è `Document` ç±»å表示æ´ä¸ª DOMï¼å®åå¨äºä¸ä¸ª DOM æ çæ ¹ `Value`ãRapidJSON çææå ¬å¼ç±»åå彿°é½å¨ `rapidjson` å½å空é´ä¸ã + +# æ¥è¯¢ Value {#QueryValue} + +卿¬èä¸ï¼æä»¬ä¼ä½¿ç¨å° `example/tutorial/tutorial.cpp` ä¸ç代ç çæ®µã + +å设æä»¬ç¨ C è¯è¨çå符串å¨åä¸ä¸ª JSONï¼`const char* json`ï¼ï¼ +~~~~~~~~~~js +{ + "hello": "world", + "t": true , + "f": false, + "n": null, + "i": 123, + "pi": 3.1416, + "a": [1, 2, 3, 4] +} +~~~~~~~~~~ + +æå®è§£æè³ä¸ä¸ª `Document`ï¼ +~~~~~~~~~~cpp +#include "rapidjson/document.h" + +using namespace rapidjson; + +// ... +Document document; +document.Parse(json); +~~~~~~~~~~ + +é£ä¹ç°å¨è¯¥ JSON å°±ä¼è¢«è§£æè³ `document` ä¸ï¼æä¸ºä¸æ£µ *DOM æ *: + + + +èªä» RFC 7159 ä½åºæ´æ°ï¼åæ³ JSON æä»¶çæ ¹å¯ä»¥æ¯ä»»ä½ç±»åç JSON å¼ãèå¨è¾æ©ç RFC 4627 ä¸ï¼æ ¹å¼åªå è®¸æ¯ Object æ Arrayãèå¨ä¸è¿°ä¾åä¸ï¼æ ¹æ¯ä¸ä¸ª Objectã +~~~~~~~~~~cpp +assert(document.IsObject()); +~~~~~~~~~~ + +让æä»¬æ¥è¯¢ä¸ä¸æ ¹ Object ä¸ææ²¡æ `"hello"` æåãç±äºä¸ä¸ª `Value` å¯å å«ä¸åç±»åçå¼ï¼æä»¬å¯è½éè¦éªè¯å®çç±»åï¼å¹¶ä½¿ç¨åéç API å»è·åå ¶å¼ã卿¤ä¾ä¸ï¼`"hello"` æåå ³èå°ä¸ä¸ª JSON Stringã +~~~~~~~~~~cpp +assert(document.HasMember("hello")); +assert(document["hello"].IsString()); +printf("hello = %s\n", document["hello"].GetString()); +~~~~~~~~~~ + +~~~~~~~~~~ +world +~~~~~~~~~~ + +JSON True/False 弿¯ä»¥ `bool` 表示çã +~~~~~~~~~~cpp +assert(document["t"].IsBool()); +printf("t = %s\n", document["t"].GetBool() ? "true" : "false"); +~~~~~~~~~~ + +~~~~~~~~~~ +true +~~~~~~~~~~ + +JSON Null å¼å¯ç¨ `IsNull()` æ¥è¯¢ã +~~~~~~~~~~cpp +printf("n = %s\n", document["n"].IsNull() ? "null" : "?"); +~~~~~~~~~~ + +~~~~~~~~~~ +null +~~~~~~~~~~ + +JSON Number ç±»åè¡¨ç¤ºæææ°å¼ãç¶èï¼C++ éè¦ä½¿ç¨æ´ä¸é¨çç±»åã + +~~~~~~~~~~cpp +assert(document["i"].IsNumber()); + +// 卿¤æ åµä¸ï¼IsUint()/IsInt64()/IsUInt64() ä¹ä¼è¿å true +assert(document["i"].IsInt()); +printf("i = %d\n", document["i"].GetInt()); +// å¦ä¸ç§ç¨æ³ï¼ (int)document["i"] + +assert(document["pi"].IsNumber()); +assert(document["pi"].IsDouble()); +printf("pi = %g\n", document["pi"].GetDouble()); +~~~~~~~~~~ + +~~~~~~~~~~ +i = 123 +pi = 3.1416 +~~~~~~~~~~ + +JSON Array å å«ä¸äºå ç´ ã +~~~~~~~~~~cpp +// 使ç¨å¼ç¨æ¥è¿ç»è®¿é®ï¼æ¹ä¾¿ä¹ä½è¿æ´é«æã +const Value& a = document["a"]; +assert(a.IsArray()); +for (SizeType i = 0; i < a.Size(); i++) // ä½¿ç¨ SizeType è䏿¯ size_t + printf("a[%d] = %d\n", i, a[i].GetInt()); +~~~~~~~~~~ + +~~~~~~~~~~ +a[0] = 1 +a[1] = 2 +a[2] = 3 +a[3] = 4 +~~~~~~~~~~ + +注æï¼RapidJSON å¹¶ä¸èªå¨è½¬æ¢åç§ JSON ç±»åãä¾å¦ï¼å¯¹ä¸ä¸ª String ç Value è°ç¨ `GetInt()` æ¯éæ³çãå¨è°è¯æ¨¡å¼ä¸ï¼å®ä¼è¢«æè¨å¤±è´¥ãå¨å叿¨¡å¼ä¸ï¼å ¶è¡ä¸ºæ¯æªå®ä¹çã + +以ä¸å°ä¼è®¨è®ºæå ³æ¥è¯¢åç±»åçç»èã + +## æ¥è¯¢ Array {#QueryArray} + +ç¼ºçæ åµä¸ï¼`SizeType` æ¯ `unsigned` ç typedefãå¨å¤æ°ç³»ç»ä¸ï¼Array æå¤è½åå¨ 2^32-1 个å ç´ ã + +ä½ å¯ä»¥ç¨æ´æ°åé¢é访é®å ç´ ï¼å¦ `a[0]`ã`a[1]`ã`a[2]`ã + +Array ä¸ `std::vector` ç¸ä¼¼ï¼é¤äºä½¿ç¨ç´¢å¼ï¼ä¹å¯ä½¿ç¨è¿ä»£å¨æ¥è®¿é®ææå ç´ ã +~~~~~~~~~~cpp +for (Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr) + printf("%d ", itr->GetInt()); +~~~~~~~~~~ + +è¿æä¸äºçæçæ¥è¯¢å½æ°ï¼ +* `SizeType Capacity() const` +* `bool Empty() const` + +### èå´ for å¾ªç¯ (v1.1.0 ä¸çæ°åè½) + +å½ä½¿ç¨ C++11 åè½æ¶ï¼ä½ å¯ä½¿ç¨èå´ for 循ç¯å»è®¿é® Array å çææå ç´ ã + +~~~~~~~~~~cpp +for (auto& v : a.GetArray()) + printf("%d ", v.GetInt()); +~~~~~~~~~~ + +## æ¥è¯¢ Object {#QueryObject} + +å Array ç¸ä¼¼ï¼æä»¬å¯ä»¥ç¨è¿ä»£å¨å»è®¿é®ææ Object æåï¼ + +~~~~~~~~~~cpp +static const char* kTypeNames[] = + { "Null", "False", "True", "Object", "Array", "String", "Number" }; + +for (Value::ConstMemberIterator itr = document.MemberBegin(); + itr != document.MemberEnd(); ++itr) +{ + printf("Type of member %s is %s\n", + itr->name.GetString(), kTypeNames[itr->value.GetType()]); +} +~~~~~~~~~~ + +~~~~~~~~~~ +Type of member hello is String +Type of member t is True +Type of member f is False +Type of member n is Null +Type of member i is Number +Type of member pi is Number +Type of member a is Array +~~~~~~~~~~ + +注æï¼å½ `operator[](const char*)` æ¾ä¸å°æåï¼å®ä¼æè¨å¤±è´¥ã + +è¥æä»¬ä¸ç¡®å®ä¸ä¸ªæåæ¯å¦åå¨ï¼ä¾¿éè¦å¨è°ç¨ `operator[](const char*)` åå è°ç¨ `HasMember()`ãç¶èï¼è¿ä¼å¯¼è´ä¸¤æ¬¡æ¥æ¾ãæ´å¥½çåæ³æ¯è°ç¨ `FindMember()`ï¼å®è½åæ¶æ£æ¥æåæ¯å¦åå¨å¹¶è¿åå®ç Valueï¼ + +~~~~~~~~~~cpp +Value::ConstMemberIterator itr = document.FindMember("hello"); +if (itr != document.MemberEnd()) + printf("%s\n", itr->value.GetString()); +~~~~~~~~~~ + +### èå´ for å¾ªç¯ (v1.1.0 ä¸çæ°åè½) + +å½ä½¿ç¨ C++11 åè½æ¶ï¼ä½ å¯ä½¿ç¨èå´ for 循ç¯å»è®¿é® Object å çæææåã + +~~~~~~~~~~cpp +for (auto& m : document.GetObject()) + printf("Type of member %s is %s\n", + m.name.GetString(), kTypeNames[m.value.GetType()]); +~~~~~~~~~~ + +## æ¥è¯¢ Number {#QueryNumber} + +JSON åªæä¾ä¸ç§æ°å¼ç±»åââNumberãæ°åå¯ä»¥æ¯æ´æ°æå®æ°ãRFC 4627 è§å®æ°åçèå´ç±è§£æå¨æå®ã + +ç±äº C++ æä¾å¤ç§æ´æ°åæµ®ç¹æ°ç±»åï¼DOM å°è¯å°½éæä¾æå¹¿çèå´åè¯å¥½æ§è½ã + +å½è§£æä¸ä¸ª Number æ¶, å®ä¼è¢«åå¨å¨ DOM ä¹ä¸ï¼æä¸ºä¸åå ¶ä¸ä¸ä¸ªç±»åï¼ + +ç±»å | æè¿° +-----------|--------------------------------------- +`unsigned` | 32 使 å·æ´æ° +`int` | 32 使巿´æ° +`uint64_t` | 64 使 å·æ´æ° +`int64_t` | 64 使巿´æ° +`double` | 64 ä½åç²¾åº¦æµ®ç¹æ° + +彿¥è¯¢ä¸ä¸ª Number æ¶, ä½ å¯ä»¥æ£æ¥è¯¥æ°åæ¯å¦è½ä»¥ç®æ ç±»åæ¥æåï¼ + +æ¥æ£ | æå +------------------|--------------------- +`bool IsNumber()` | ä¸éç¨ +`bool IsUint()` | `unsigned GetUint()` +`bool IsInt()` | `int GetInt()` +`bool IsUint64()` | `uint64_t GetUint64()` +`bool IsInt64()` | `int64_t GetInt64()` +`bool IsDouble()` | `double GetDouble()` + +注æï¼ä¸ä¸ªæ´æ°å¯è½ç¨å ç§ç±»åæ¥æåï¼èæ é转æ¢ãä¾å¦ï¼ä¸ä¸ªå为 `x` ç Value å å« 123ï¼é£ä¹ `x.IsInt() == x.IsUint() == x.IsInt64() == x.IsUint64() == true`ãä½å¦æä¸ä¸ªå为 `y` ç Value å å« -3000000000ï¼é£ä¹ä» ä¼ä»¤ `x.IsInt64() == true`ã + +å½è¦æå Number ç±»åï¼`GetDouble()` æ¯ä¼æå 鍿´æ°çè¡¨ç¤ºè½¬æ¢æ `double`ãæ³¨æ `int` å `unsigned` å¯ä»¥å®å ¨å°è½¬æ¢è³ `double`ï¼ä½ `int64_t` å `uint64_t` å¯è½ä¼ä¸§å¤±ç²¾åº¦ï¼å 为 `double` çå°¾æ°åªæ 52 ä½ï¼ã + +## æ¥è¯¢ String {#QueryString} + +é¤äº `GetString()`ï¼`Value` ç±»ä¹æä¸ä¸ª `GetStringLength()`ãè¿éä¼è§£é个ä¸åå ã + +æ ¹æ® RFC 4627ï¼JSON String å¯å å« Unicode å符 `U+0000`ï¼å¨ JSON ä¸ä¼è¡¨ç¤ºä¸º `"\u0000"`ãé®é¢æ¯ï¼C/C++ é常使ç¨ç©ºå符ç»å°¾å符串ï¼null-terminated stringï¼ï¼è¿ç§å符串æ ``\0'` ä½ä¸ºç»æç¬¦å·ã + +为äºç¬¦å RFC 4627ï¼RapidJSON æ¯æå å« `U+0000` ç Stringãè¥ä½ éè¦å¤çè¿äº Stringï¼ä¾¿å¯ä½¿ç¨ `GetStringLength()` å»è·å¾æ£ç¡®çå符串é¿åº¦ã + +ä¾å¦ï¼å½è§£æä»¥ä¸ç JSON è³ `Document d` ä¹åï¼ + +~~~~~~~~~~js +{ "s" : "a\u0000b" } +~~~~~~~~~~ +`"a\u0000b"` å¼çæ£ç¡®é¿åº¦åºè¯¥æ¯ 3ãä½ `strlen()` ä¼è¿å 1ã + +`GetStringLength()` ä¹å¯ä»¥æé«æ§è½ï¼å ä¸ºç¨æ·å¯è½éè¦è°ç¨ `strlen()` å»åé ç¼å²ã + +æ¤å¤ï¼`std::string` 乿¯æè¿ä¸ªæé 彿°ï¼ + +~~~~~~~~~~cpp +string(const char* s, size_t count); +~~~~~~~~~~ + +æ¤æé 彿°æ¥åå符串é¿åº¦ä½ä¸ºåæ°ã宿¯æå¨å符串ä¸åå¨ç©ºå符ï¼ä¹åºè¯¥ä¼ææ´å¥½çæ§è½ã + +## æ¯è¾ä¸¤ä¸ª Value + +ä½ å¯ä½¿ç¨ `==` å `!=` 廿¯è¾ä¸¤ä¸ª Valueãå½ä¸ä» å½ä¸¤ä¸ª Value çç±»ååå 容ç¸åï¼å®ä»¬æå½ä½ç¸çãä½ ä¹å¯ä»¥æ¯è¾ Value åå®çåçç±»åå¼ã以䏿¯ä¸ä¸ªä¾åã + +~~~~~~~~~~cpp +if (document["hello"] == document["n"]) /*...*/; // æ¯è¾ä¸¤ä¸ªå¼ +if (document["hello"] == "world") /*...*/; // ä¸å符串家é¢é使¯è¾ +if (document["i"] != 123) /*...*/; // 䏿´æ°ä½æ¯è¾ +if (document["pi"] != 3.14) /*...*/; // ä¸ double 使¯è¾ +~~~~~~~~~~ + +Arrayï¼Object 顺åºä»¥å®ä»¬çå ç´ ï¼æå使¯è¾ãå½ä¸ä» å½å®ä»¬çæ´ä¸ªåæ ç¸çï¼å®ä»¬æå½ä½ç¸çã + +注æï¼ç°æ¶è¥ä¸ä¸ª Object 嫿éå¤å½åçæåï¼å®ä¸ä»»ä½ Object 使¯è¾é½æ»ä¼è¿å `false`ã + +# å建ï¼ä¿®æ¹å¼ {#CreateModifyValues} + +æå¤ç§æ¹æ³å»å建å¼ã å½ä¸ä¸ª DOM æ 被å建æä¿®æ¹åï¼å¯ä½¿ç¨ `Writer` 忬¡åå¨ä¸º JSONã + +## æ¹å Value ç±»å {#ChangeValueType} +å½ä½¿ç¨é»è®¤æé 彿°å建ä¸ä¸ª Value æ Documentï¼å®çç±»åä¾¿ä¼æ¯ Nullãè¦æ¹åå ¶ç±»åï¼éè°ç¨ `SetXXX()` æèµå¼æä½ï¼ä¾å¦ï¼ + +~~~~~~~~~~cpp +Document d; // Null +d.SetObject(); + +Value v; // Null +v.SetInt(10); +v = 10; // ç®åï¼åä¸é¢çç¸å +~~~~~~~~~~ + +### æé 彿°çå个éè½½ +å 个类å乿éè½½æé 彿°ï¼ + +~~~~~~~~~~cpp +Value b(true); // è°ç¨ Value(bool) +Value i(-123); // è°ç¨ Value(int) +Value u(123u); // è°ç¨ Value(unsigned) +Value d(1.5); // è°ç¨ Value(double) +~~~~~~~~~~ + +è¦é建空 Object æ Arrayï¼å¯å¨é»è®¤æé 彿°åä½¿ç¨ `SetObject()`/`SetArray()`ï¼æä¸æ¬¡æ§ä½¿ç¨ `Value(Type)`ï¼ + +~~~~~~~~~~cpp +Value o(kObjectType); +Value a(kArrayType); +~~~~~~~~~~ + +## è½¬ç§»è¯æï¼Move Semanticsï¼ {#MoveSemantics} + +å¨è®¾è®¡ RapidJSON æ¶æä¸ä¸ªé常ç¹å«çå³å®ï¼å°±æ¯ Value èµå¼å¹¶ä¸æ¯ææ¥æº Value å¤å¶è³ç®ç Valueï¼èæ¯æææ¥æº Value 转移ï¼moveï¼è³ç®ç Valueãä¾å¦ï¼ + +~~~~~~~~~~cpp +Value a(123); +Value b(456); +b = a; // a åæ Nullï¼b åææ°å 123ã +~~~~~~~~~~ + + + +为ä»ä¹ï¼æ¤è¯ææä½ä¼ç¹ï¼ + +æç®åççæ¡å°±æ¯æ§è½ã对äºåºå®å¤§å°ç JSON ç±»åï¼NumberãTrueãFalseãNullï¼ï¼å¤å¶å®ä»¬æ¯ç®åå¿«æ·ãç¶èï¼å¯¹äºå¯å大å°ç JSON ç±»åï¼StringãArrayãObjectï¼ï¼å¤å¶å®ä»¬ä¼äº§ç大éå¼éï¼èä¸è¿äºå¼é常常ä¸è¢«å¯è§ãå°¤å ¶æ¯å½æä»¬éè¦åå»ºä¸´æ¶ Objectï¼æå®å¤å¶è³å¦ä¸åéï¼ç¶ååææå®ã + +ä¾å¦ï¼è¥ä½¿ç¨æ£å¸¸ * å¤å¶ * è¯æï¼ + +~~~~~~~~~~cpp +Value o(kObjectType); +{ + Value contacts(kArrayType); + // æå ç´ å è¿ contacts æ°ç»ã + // ... + o.AddMember("contacts", contacts, d.GetAllocator()); // 深度å¤å¶ contacts ï¼å¯è½æå¤§éå ååé ï¼ + // ææ contactsã +} +~~~~~~~~~~ + + + +é£ä¸ª `o` Object éè¦åé ä¸ä¸ªå contacts ç¸å大å°çç¼å²åºï¼å¯¹ conacts åæ·±åº¦å¤å¶ï¼å¹¶æç»è¦ææ contactsãè¿æ ·ä¼äº§çå¤§éæ å¿ è¦çå ååé ï¼éæ¾ï¼ä»¥åå åå¤å¶ã + +æä¸äºæ¹æ¡å¯é¿å å®è´¨å°å¤å¶è¿äºæ°æ®ï¼ä¾å¦å¼ç¨è®¡æ°ï¼reference countingï¼ãåå¾åæ¶ï¼garbage collection, GCï¼ã + +为äºä½¿ RapidJSON ç®ååå¿«éï¼æä»¬éæ©äºå¯¹èµå¼éç¨ * 转移 * è¯æãè¿æ¹æ³ä¸ `std::auto_ptr` ç¸ä¼¼ï¼é½æ¯å¨èµå¼æ¶è½¬ç§»æ¥ææã转移快å¾å¤ç®åå¾å¤ï¼åªéè¦ææåæ¥ç Valueï¼ææ¥æº `memcpy()` è³ç®æ ï¼æåææ¥æºè®¾ç½®ä¸º Null ç±»åã + +å æ¤ï¼ä½¿ç¨è½¬ç§»è¯æåï¼ä¸é¢çä¾ååæï¼ + +~~~~~~~~~~cpp +Value o(kObjectType); +{ + Value contacts(kArrayType); + // adding elements to contacts array. + o.AddMember("contacts", contacts, d.GetAllocator()); // åªé memcpy() contacts æ¬èº«è³æ°æåç Valueï¼16 åèï¼ + // contacts å¨è¿éåæ Nullãå®çæææ¯å¹³å¡çã +} +~~~~~~~~~~ + + + +å¨ C++11 ä¸è¿ç§°ä¸ºè½¬ç§»èµå¼æä½ï¼move assignment operatorï¼ãç±äº RapidJSON æ¯æ C++03ï¼å®å¨èµå¼æä½éç¨è½¬ç§»è¯æï¼å ¶å®ä¿®æ¹å½¢å½æ°å¦ `AddMember()`, `PushBack()` ä¹éç¨è½¬ç§»è¯æã + +### è½¬ç§»è¯æå临æ¶å¼ {#TemporaryValues} + +ææ¶åï¼æä»¬æ³ç´æ¥æé ä¸ä¸ª Value å¹¶ä¼ éç»ä¸ä¸ªâ转移â彿°ï¼å¦ `PushBack()`ã`AddMember()`ï¼ãç±äºä¸´æ¶å¯¹è±¡æ¯ä¸è½è½¬æ¢ä¸ºæ£å¸¸ç Value å¼ç¨ï¼æä»¬å å ¥äºä¸ä¸ªæ¹ä¾¿ç `Move()` 彿°ï¼ + +~~~~~~~~~~cpp +Value a(kArrayType); +Document::AllocatorType& allocator = document.GetAllocator(); +// a.PushBack(Value(42), allocator); // ä¸è½éè¿ç¼è¯ +a.PushBack(Value().SetInt(42), allocator); // fluent API +a.PushBack(Value(42).Move(), allocator); // åä¸ä¸è¡ç¸å +~~~~~~~~~~ + +## å建 String {#CreateString} +RapidJSON æä¾ä¸¤ä¸ª String çåå¨çç¥ã + +1. copy-string: åé ç¼å²åºï¼ç¶åææ¥æºæ°æ®å¤å¶è³å®ã +2. const-string: ç®åå°å¨åå符串çæéã + +Copy-string æ»æ¯å®å ¨çï¼å ä¸ºå®æ¥ææ°æ®çå éãConst-string å¯ç¨äºåå¨å符串åé¢éï¼ä»¥åç¨äºå¨ DOM ä¸èä¸å°ä¼æå°ç in-situ è§£æä¸ã + +为äºè®©ç¨æ·èªå®ä¹å ååé æ¹å¼ï¼å½ä¸ä¸ªæä½å¯è½éè¦å ååé æ¶ï¼RapidJSON è¦æ±ç¨æ·ä¼ éä¸ä¸ª allocator å®ä¾ä½ä¸º API åæ°ãæ¤è®¾è®¡é¿å äºå¨æ¯ä¸ª Value åå¨ allocatorï¼æ documentï¼çæéã + +å æ¤ï¼å½æä»¬æä¸ä¸ª copy-string èµå¼æ¶, è°ç¨å«æ allocator ç `SetString()` éè½½å½æ°ï¼ + +~~~~~~~~~~cpp +Document document; +Value author; +char buffer[10]; +int len = sprintf(buffer, "%s %s", "Milo", "Yip"); // 卿å建çå符串ã +author.SetString(buffer, len, document.GetAllocator()); +memset(buffer, 0, sizeof(buffer)); +// æ¸ ç©º buffer å author.GetString() ä»ç¶å å« "Milo Yip" +~~~~~~~~~~ + +卿¤ä¾åä¸ï¼æä»¬ä½¿ç¨ `Document` å®ä¾ç allocatorãè¿æ¯ä½¿ç¨ RapidJSON æ¶å¸¸ç¨çæ¯ç¨æ³ãä½ä½ ä¹å¯ä»¥ç¨å ¶ä» allocator å®ä¾ã + +å¦å¤ï¼ä¸é¢ç `SetString()` éè¦é¿åº¦åæ°ãè¿ä¸ª API è½å¤çå«æç©ºå符çå符串ãå¦ä¸ä¸ª `SetString()` éè½½å½æ°æ²¡æé¿åº¦åæ°ï¼å®å设è¾å ¥æ¯ç©ºå符ç»å°¾çï¼å¹¶ä¼è°ç¨ç±»ä¼¼ `strlen()` ç彿°å»è·åé¿åº¦ã + +æåï¼å¯¹äºå符串åé¢éææå®å ¨çå½å¨æçå符串ï¼å¯ä»¥ä½¿ç¨ const-string çæ¬ç `SetString()`ï¼å®æ²¡æ allocator åæ°ã对äºå符串家é¢éï¼æå符æ°ç»å¸¸éï¼ï¼åªéç®åå°ä¼ éåé¢éï¼åå®å ¨åé«æï¼ + +~~~~~~~~~~cpp +Value s; +s.SetString("rapidjson"); // å¯å å«ç©ºå符ï¼é¿åº¦å¨ç¼è¯èæ¨å¯¼ +s = "rapidjson"; // ä¸è¡ç缩å +~~~~~~~~~~ + +对äºå符æéï¼RapidJSON éè¦ä½ä¸ä¸ªæ è®°ï¼ä»£è¡¨å®ä¸å¤å¶ä¹æ¯å®å ¨çãå¯ä»¥ä½¿ç¨ `StringRef` 彿°ï¼ + +~~~~~~~~~cpp +const char * cstr = getenv("USER"); +size_t cstr_len = ...; // 妿æé¿åº¦ +Value s; +// s.SetString(cstr); // è¿ä¸è½éè¿ç¼è¯ +s.SetString(StringRef(cstr)); // å¯ä»¥ï¼å设å®ççå½å¨æå®å ¨ï¼å¹¶ä¸æ¯ä»¥ç©ºå符ç»å°¾ç +s = StringRef(cstr); // ä¸è¡ç缩å +s.SetString(StringRef(cstr, cstr_len));// æ´å¿«ï¼å¯å¤ç空å符 +s = StringRef(cstr, cstr_len); // ä¸è¡ç缩å + +~~~~~~~~~ + +## ä¿®æ¹ Array {#ModifyArray} +Array ç±»åç Value æä¾ä¸ `std::vector` ç¸ä¼¼ç APIã + +* `Clear()` +* `Reserve(SizeType, Allocator&)` +* `Value& PushBack(Value&, Allocator&)` +* `template <typename T> GenericValue& PushBack(T, Allocator&)` +* `Value& PopBack()` +* `ValueIterator Erase(ConstValueIterator pos)` +* `ValueIterator Erase(ConstValueIterator first, ConstValueIterator last)` + +注æï¼`Reserve(...)` å `PushBack(...)` å¯è½ä¼ä¸ºæ°ç»å ç´ åé å åï¼æä»¥éè¦ä¸ä¸ª allocatorã + +以䏿¯ `PushBack()` çä¾åï¼ + +~~~~~~~~~~cpp +Value a(kArrayType); +Document::AllocatorType& allocator = document.GetAllocator(); + +for (int i = 5; i <= 10; i++) + a.PushBack(i, allocator); // å¯è½éè¦è°ç¨ realloc() æä»¥éè¦ allocator + +// æµç æ¥å£ï¼Fluent interfaceï¼ +a.PushBack("Lua", allocator).PushBack("Mio", allocator); +~~~~~~~~~~ + +ä¸ STL ä¸ä¸æ ·çæ¯ï¼`PushBack()`/`PopBack()` è¿å Array æ¬èº«çå¼ç¨ãè¿ç§°ä¸ºæµç æ¥å£ï¼_fluent interface_ï¼ã + +å¦æä½ æ³å¨ Array ä¸å å ¥ä¸ä¸ªé常éåç¬¦ä¸²ï¼ææ¯ä¸ä¸ªæ²¡æè¶³å¤çå½å¨æçå符串ï¼è§ [Create String](#CreateString)ï¼ï¼ä½ éè¦ä½¿ç¨ copy-string API å»å建ä¸ä¸ª Stringã为äºé¿å å å ¥ä¸é´åéï¼å¯ä»¥å°±å°ä½¿ç¨ä¸ä¸ª [临æ¶å¼](#TemporaryValues)ï¼ + +~~~~~~~~~~cpp +// å°±å° Value åæ° +contact.PushBack(Value("copy", document.GetAllocator()).Move(), // copy string + document.GetAllocator()); + +// æ¾å¼ Value åæ° +Value val("key", document.GetAllocator()); // copy string +contact.PushBack(val, document.GetAllocator()); +~~~~~~~~~~ + +## ä¿®æ¹ Object {#ModifyObject} +Object æ¯é®å¼å¯¹çéåãæ¯ä¸ªé®å¿ 须为 Stringãè¦ä¿®æ¹ Objectï¼æ¹æ³æ¯å¢å æç§»é¤æåã以ä¸ç API ç¨æ¥å¢å ååï¼ + +* `Value& AddMember(Value&, Value&, Allocator& allocator)` +* `Value& AddMember(StringRefType, Value&, Allocator&)` +* `template <typename T> Value& AddMember(StringRefType, T value, Allocator&)` + +以䏿¯ä¸ä¸ªä¾åã + +~~~~~~~~~~cpp +Value contact(kObject); +contact.AddMember("name", "Milo", document.GetAllocator()); +contact.AddMember("married", true, document.GetAllocator()); +~~~~~~~~~~ + +ä½¿ç¨ `StringRefType` ä½ä¸º name åæ°çéè½½çæ¬ä¸å符串ç `SetString` çæ¥å£ç¸ä¼¼ã è¿äºéè½½æ¯ä¸ºäºé¿å å¤å¶ `name` å符串ï¼å 为 JSON object ä¸ç»å¸¸ä¼ä½¿ç¨å¸¸æ°é®åã + +å¦æä½ éè¦ä»é常æ°å符串æçå½å¨æä¸è¶³çå符串å建é®åï¼è§ [å建 String](#CreateString)ï¼ï¼ä½ éè¦ä½¿ç¨ copy-string APIã为äºé¿å ä¸é´åéï¼å¯ä»¥å°±å°ä½¿ç¨ [临æ¶å¼](#TemporaryValues)ï¼ + +~~~~~~~~~~cpp +// å°±å° Value åæ° +contact.AddMember(Value("copy", document.GetAllocator()).Move(), // copy string + Value().Move(), // null value + document.GetAllocator()); + +// æ¾å¼åæ° +Value key("key", document.GetAllocator()); // copy string name +Value val(42); // æ Value +contact.AddMember(key, val, document.GetAllocator()); +~~~~~~~~~~ + +ç§»é¤æåæå ä¸ªéæ©ï¼ + +* `bool RemoveMember(const Ch* name)`ï¼ä½¿ç¨é®åæ¥ç§»é¤æåï¼çº¿æ§æ¶é´å¤æåº¦ï¼ã +* `bool RemoveMember(const Value& name)`ï¼é¤äº `name` æ¯ä¸ä¸ª Valueï¼åä¸ä¸è¡ç¸åã +* `MemberIterator RemoveMember(MemberIterator)`ï¼ä½¿ç¨è¿ä»£å¨ç§»é¤æåï¼_ å¸¸æ° _ æ¶é´å¤æåº¦ï¼ã +* `MemberIterator EraseMember(MemberIterator)`ï¼åä¸è¡ç¸ä¼¼ä½ç»´ææå次åºï¼çº¿æ§æ¶é´å¤æåº¦ï¼ã +* `MemberIterator EraseMember(MemberIterator first, MemberIterator last)`ï¼ç§»é¤ä¸ä¸ªèå´å çæåï¼ç»´ææ¬¡åºï¼çº¿æ§æ¶é´å¤æåº¦ï¼ã + +`MemberIterator RemoveMember(MemberIterator)` 使ç¨äºâ转移æåâææ³æ¥è¾¾æå¸¸æ°æ¶é´å¤æåº¦ãåºæ¬ä¸å°±æ¯ææè¿ä»£å¨ä½ç½®çæåï¼ç¶åææåçæå转移è³è¿ä»£å¨ä½ç½®ãå æ¤ï¼æåçæ¬¡åºä¼è¢«æ¹åã + +## æ·±å¤å¶ Value {#DeepCopyValue} +è¥æä»¬ççè¦å¤å¶ä¸ä¸ª DOM æ ï¼æä»¬å¯ä½¿ç¨ä¸¤ä¸ª APIs 使·±å¤å¶ï¼å« allocator çæé 彿°å `CopyFrom()`ã + +~~~~~~~~~~cpp +Document d; +Document::AllocatorType& a = d.GetAllocator(); +Value v1("foo"); +// Value v2(v1); // ä¸å®¹è®¸ + +Value v2(v1, a); // å¶é ä¸ä¸ªå é +assert(v1.IsString()); // v1 ä¸å +d.SetArray().PushBack(v1, a).PushBack(v2, a); +assert(v1.IsNull() && v2.IsNull()); // 两个é½è½¬ç§»å¨ d + +v2.CopyFrom(d, a); // ææ´ä¸ª document å¤å¶è³ v2 +assert(d.IsArray() && d.Size() == 2); // d ä¸å +v1.SetObject().AddMember("array", v2, a); +d.PushBack(v1, a); +~~~~~~~~~~ + +## äº¤æ¢ Value {#SwapValues} + +RapidJSON ä¹æä¾ `Swap()`ã + +~~~~~~~~~~cpp +Value a(123); +Value b("Hello"); +a.Swap(b); +assert(a.IsString()); +assert(b.IsInt()); +~~~~~~~~~~ + +æ 论两棵 DOM æ æå¤å¤æï¼äº¤æ¢æ¯å¾å¿«çï¼å¸¸æ°æ¶é´ï¼ã + +# ä¸ä¸é¨å {#WhatsNext} + +æ¬æç¨å±ç¤ºäºå¦ä½è¯¢æ¥åä¿®æ¹ DOM æ ãRapidJSON è¿æä¸ä¸ªéè¦æ¦å¿µï¼ + +1. [æµ](doc/stream.zh-cn.md) æ¯è¯»å JSON çééãæµå¯ä»¥æ¯å åå符串ãæä»¶æµçãç¨æ·ä¹å¯ä»¥èªå®ä¹æµã +2. [ç¼ç ](doc/encoding.zh-cn.md) å®ä¹å¨æµæå åä¸ä½¿ç¨çå符ç¼ç ãRapidJSON ä¹å¨å é¨æä¾ Unicode 转æ¢åæ ¡éªåè½ã +3. [DOM](doc/dom.zh-cn.md) çåºæ¬åè½å·²å¨æ¬æç¨éä»ç»ãè¿ææ´é«çº§çåè½ï¼å¦åä½ï¼*in situ*ï¼è§£æãå ¶ä»è§£æé项åé«çº§ç¨æ³ã +4. [SAX](doc/sax.zh-cn.md) æ¯ RapidJSON è§£æï¼çæåè½çåºç¡ãå¦ä¹ ä½¿ç¨ `Reader`/`Writer` å»å®ç°æ´é«æ§è½çåºç¨ç¨åºãä¹å¯ä»¥ä½¿ç¨ `PrettyWriter` 廿 ¼å¼å JSONã +5. [æ§è½](doc/performance.zh-cn.md) å±ç¤ºä¸äºæä»¬åçåç¬¬ä¸æ¹çæ§è½æµè¯ã +6. [ææ¯å å¹](doc/internals.md) 讲述ä¸äº RapidJSON å é¨çè®¾è®¡åææ¯ã + +ä½ ä¹å¯ä»¥åè [常è§é®é¢](doc/faq.zh-cn.md)ãAPI ææ¡£ãä¾åååå æµè¯ã http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/docker/debian/Dockerfile ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/docker/debian/Dockerfile b/thirdparty/rapidjson-1.1.0/docker/debian/Dockerfile new file mode 100644 index 0000000..76f0235 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/docker/debian/Dockerfile @@ -0,0 +1,8 @@ +# BUILD: docker build -t rapidjson-debian . +# RUN: docker run -it -v "$PWD"/../..:/rapidjson rapidjson-debian + +FROM debian:jessie + +RUN apt-get update && apt-get install -y g++ cmake doxygen valgrind + +ENTRYPOINT ["/bin/bash"] http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/example/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/example/CMakeLists.txt b/thirdparty/rapidjson-1.1.0/example/CMakeLists.txt new file mode 100644 index 0000000..4d448cc --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/example/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 2.8) + +if(POLICY CMP0054) + cmake_policy(SET CMP0054 NEW) +endif() + +set(EXAMPLES + capitalize + condense + filterkey + filterkeydom + jsonx + messagereader + parsebyparts + pretty + prettyauto + schemavalidator + serialize + simpledom + simplereader + simplewriter + tutorial) + +include_directories("../include/") + +add_definitions(-D__STDC_FORMAT_MACROS) + +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + 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") +endif() + +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}) http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/example/capitalize/capitalize.cpp ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/example/capitalize/capitalize.cpp b/thirdparty/rapidjson-1.1.0/example/capitalize/capitalize.cpp new file mode 100644 index 0000000..7da37e9 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/example/capitalize/capitalize.cpp @@ -0,0 +1,67 @@ +// JSON condenser example + +// This example parses JSON from stdin with validation, +// and re-output the JSON content to stdout with all string capitalized, and without whitespace. + +#include "rapidjson/reader.h" +#include "rapidjson/writer.h" +#include "rapidjson/filereadstream.h" +#include "rapidjson/filewritestream.h" +#include "rapidjson/error/en.h" +#include <vector> +#include <cctype> + +using namespace rapidjson; + +template<typename OutputHandler> +struct CapitalizeFilter { + CapitalizeFilter(OutputHandler& out) : out_(out), buffer_() {} + + bool Null() { return out_.Null(); } + bool Bool(bool b) { return out_.Bool(b); } + bool Int(int i) { return out_.Int(i); } + bool Uint(unsigned u) { return out_.Uint(u); } + 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 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]))); + return out_.String(&buffer_.front(), length, true); // true = output handler need to copy the string + } + bool StartObject() { return out_.StartObject(); } + bool Key(const char* str, SizeType length, bool copy) { return String(str, length, copy); } + bool EndObject(SizeType memberCount) { return out_.EndObject(memberCount); } + bool StartArray() { return out_.StartArray(); } + bool EndArray(SizeType elementCount) { return out_.EndArray(elementCount); } + + OutputHandler& out_; + std::vector<char> buffer_; + +private: + CapitalizeFilter(const CapitalizeFilter&); + CapitalizeFilter& operator=(const CapitalizeFilter&); +}; + +int main(int, char*[]) { + // Prepare JSON reader and input stream. + Reader reader; + char readBuffer[65536]; + FileReadStream is(stdin, readBuffer, sizeof(readBuffer)); + + // Prepare JSON writer and output stream. + char writeBuffer[65536]; + FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer)); + Writer<FileWriteStream> writer(os); + + // JSON reader parse from the input stream and let writer generate the output. + CapitalizeFilter<Writer<FileWriteStream> > filter(writer); + if (!reader.Parse(is, filter)) { + fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode())); + return 1; + } + + return 0; +} http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/example/condense/condense.cpp ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/example/condense/condense.cpp b/thirdparty/rapidjson-1.1.0/example/condense/condense.cpp new file mode 100644 index 0000000..46dc350 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/example/condense/condense.cpp @@ -0,0 +1,32 @@ +// JSON condenser example + +// This example parses JSON text from stdin with validation, +// and re-output the JSON content to stdout without whitespace. + +#include "rapidjson/reader.h" +#include "rapidjson/writer.h" +#include "rapidjson/filereadstream.h" +#include "rapidjson/filewritestream.h" +#include "rapidjson/error/en.h" + +using namespace rapidjson; + +int main(int, char*[]) { + // Prepare JSON reader and input stream. + Reader reader; + char readBuffer[65536]; + FileReadStream is(stdin, readBuffer, sizeof(readBuffer)); + + // Prepare JSON writer and output stream. + char writeBuffer[65536]; + FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer)); + Writer<FileWriteStream> writer(os); + + // JSON reader parse from the input stream and let writer generate the output. + if (!reader.Parse(is, writer)) { + fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode())); + return 1; + } + + return 0; +} http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/example/filterkey/filterkey.cpp ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/example/filterkey/filterkey.cpp b/thirdparty/rapidjson-1.1.0/example/filterkey/filterkey.cpp new file mode 100644 index 0000000..c34a050 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/example/filterkey/filterkey.cpp @@ -0,0 +1,135 @@ +// JSON filterkey example with SAX-style API. + +// This example parses JSON text from stdin with validation. +// During parsing, specified key will be filtered using a SAX handler. +// It re-output the JSON content to stdout without whitespace. + +#include "rapidjson/reader.h" +#include "rapidjson/writer.h" +#include "rapidjson/filereadstream.h" +#include "rapidjson/filewritestream.h" +#include "rapidjson/error/en.h" +#include <stack> + +using namespace rapidjson; + +// This handler forwards event into an output handler, with filtering the descendent events of specified key. +template <typename OutputHandler> +class FilterKeyHandler { +public: + typedef char Ch; + + FilterKeyHandler(OutputHandler& outputHandler, const Ch* keyString, SizeType keyLength) : + outputHandler_(outputHandler), keyString_(keyString), keyLength_(keyLength), filterValueDepth_(), filteredKeyCount_() + {} + + bool Null() { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Null() && EndValue(); } + bool Bool(bool b) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Bool(b) && EndValue(); } + bool Int(int i) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int(i) && EndValue(); } + bool Uint(unsigned u) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint(u) && EndValue(); } + bool Int64(int64_t i) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int64(i) && EndValue(); } + bool Uint64(uint64_t u) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint64(u) && EndValue(); } + bool Double(double d) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Double(d) && EndValue(); } + bool RawNumber(const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.RawNumber(str, len, copy) && EndValue(); } + bool String (const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.String (str, len, copy) && EndValue(); } + + bool StartObject() { + if (filterValueDepth_ > 0) { + filterValueDepth_++; + return true; + } + else { + filteredKeyCount_.push(0); + return outputHandler_.StartObject(); + } + } + + bool Key(const Ch* str, SizeType len, bool copy) { + if (filterValueDepth_ > 0) + return true; + else if (len == keyLength_ && std::memcmp(str, keyString_, len) == 0) { + filterValueDepth_ = 1; + return true; + } + else { + ++filteredKeyCount_.top(); + return outputHandler_.Key(str, len, copy); + } + } + + bool EndObject(SizeType) { + if (filterValueDepth_ > 0) { + filterValueDepth_--; + return EndValue(); + } + else { + // Use our own filtered memberCount + SizeType memberCount = filteredKeyCount_.top(); + filteredKeyCount_.pop(); + return outputHandler_.EndObject(memberCount) && EndValue(); + } + } + + bool StartArray() { + if (filterValueDepth_ > 0) { + filterValueDepth_++; + return true; + } + else + return outputHandler_.StartArray(); + } + + bool EndArray(SizeType elementCount) { + if (filterValueDepth_ > 0) { + filterValueDepth_--; + return EndValue(); + } + else + return outputHandler_.EndArray(elementCount) && EndValue(); + } + +private: + FilterKeyHandler(const FilterKeyHandler&); + FilterKeyHandler& operator=(const FilterKeyHandler&); + + bool EndValue() { + if (filterValueDepth_ == 1) // Just at the end of value after filtered key + filterValueDepth_ = 0; + return true; + } + + OutputHandler& outputHandler_; + const char* keyString_; + const SizeType keyLength_; + unsigned filterValueDepth_; + std::stack<SizeType> filteredKeyCount_; +}; + +int main(int argc, char* argv[]) { + if (argc != 2) { + fprintf(stderr, "filterkey key < input.json > output.json\n"); + return 1; + } + + // Prepare JSON reader and input stream. + Reader reader; + char readBuffer[65536]; + FileReadStream is(stdin, readBuffer, sizeof(readBuffer)); + + // Prepare JSON writer and output stream. + char writeBuffer[65536]; + FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer)); + Writer<FileWriteStream> writer(os); + + // Prepare Filter + FilterKeyHandler<Writer<FileWriteStream> > filter(writer, argv[1], static_cast<SizeType>(strlen(argv[1]))); + + // JSON reader parse from the input stream, filter handler filters the events, and forward to writer. + // i.e. the events flow is: reader -> filter -> writer + if (!reader.Parse(is, filter)) { + fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode())); + return 1; + } + + return 0; +} http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/example/filterkeydom/filterkeydom.cpp ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/example/filterkeydom/filterkeydom.cpp b/thirdparty/rapidjson-1.1.0/example/filterkeydom/filterkeydom.cpp new file mode 100644 index 0000000..732cc81 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/example/filterkeydom/filterkeydom.cpp @@ -0,0 +1,170 @@ +// JSON filterkey example which populates filtered SAX events into a Document. + +// This example parses JSON text from stdin with validation. +// During parsing, specified key will be filtered using a SAX handler. +// And finally the filtered events are used to populate a Document. +// As an example, the document is written to standard output. + +#include "rapidjson/document.h" +#include "rapidjson/writer.h" +#include "rapidjson/filereadstream.h" +#include "rapidjson/filewritestream.h" +#include "rapidjson/error/en.h" +#include <stack> + +using namespace rapidjson; + +// This handler forwards event into an output handler, with filtering the descendent events of specified key. +template <typename OutputHandler> +class FilterKeyHandler { +public: + typedef char Ch; + + FilterKeyHandler(OutputHandler& outputHandler, const Ch* keyString, SizeType keyLength) : + outputHandler_(outputHandler), keyString_(keyString), keyLength_(keyLength), filterValueDepth_(), filteredKeyCount_() + {} + + bool Null() { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Null() && EndValue(); } + bool Bool(bool b) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Bool(b) && EndValue(); } + bool Int(int i) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int(i) && EndValue(); } + bool Uint(unsigned u) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint(u) && EndValue(); } + bool Int64(int64_t i) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int64(i) && EndValue(); } + bool Uint64(uint64_t u) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint64(u) && EndValue(); } + bool Double(double d) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Double(d) && EndValue(); } + bool RawNumber(const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.RawNumber(str, len, copy) && EndValue(); } + bool String (const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.String (str, len, copy) && EndValue(); } + + bool StartObject() { + if (filterValueDepth_ > 0) { + filterValueDepth_++; + return true; + } + else { + filteredKeyCount_.push(0); + return outputHandler_.StartObject(); + } + } + + bool Key(const Ch* str, SizeType len, bool copy) { + if (filterValueDepth_ > 0) + return true; + else if (len == keyLength_ && std::memcmp(str, keyString_, len) == 0) { + filterValueDepth_ = 1; + return true; + } + else { + ++filteredKeyCount_.top(); + return outputHandler_.Key(str, len, copy); + } + } + + bool EndObject(SizeType) { + if (filterValueDepth_ > 0) { + filterValueDepth_--; + return EndValue(); + } + else { + // Use our own filtered memberCount + SizeType memberCount = filteredKeyCount_.top(); + filteredKeyCount_.pop(); + return outputHandler_.EndObject(memberCount) && EndValue(); + } + } + + bool StartArray() { + if (filterValueDepth_ > 0) { + filterValueDepth_++; + return true; + } + else + return outputHandler_.StartArray(); + } + + bool EndArray(SizeType elementCount) { + if (filterValueDepth_ > 0) { + filterValueDepth_--; + return EndValue(); + } + else + return outputHandler_.EndArray(elementCount) && EndValue(); + } + +private: + FilterKeyHandler(const FilterKeyHandler&); + FilterKeyHandler& operator=(const FilterKeyHandler&); + + bool EndValue() { + if (filterValueDepth_ == 1) // Just at the end of value after filtered key + filterValueDepth_ = 0; + return true; + } + + OutputHandler& outputHandler_; + const char* keyString_; + const SizeType keyLength_; + unsigned filterValueDepth_; + std::stack<SizeType> filteredKeyCount_; +}; + +// Implements a generator for Document::Populate() +template <typename InputStream> +class FilterKeyReader { +public: + typedef char Ch; + + FilterKeyReader(InputStream& is, const Ch* keyString, SizeType keyLength) : + is_(is), keyString_(keyString), keyLength_(keyLength), parseResult_() + {} + + // SAX event flow: reader -> filter -> handler + template <typename Handler> + bool operator()(Handler& handler) { + FilterKeyHandler<Handler> filter(handler, keyString_, keyLength_); + Reader reader; + parseResult_ = reader.Parse(is_, filter); + return parseResult_; + } + + const ParseResult& GetParseResult() const { return parseResult_; } + +private: + FilterKeyReader(const FilterKeyReader&); + FilterKeyReader& operator=(const FilterKeyReader&); + + InputStream& is_; + const char* keyString_; + const SizeType keyLength_; + ParseResult parseResult_; +}; + +int main(int argc, char* argv[]) { + if (argc != 2) { + fprintf(stderr, "filterkeydom key < input.json > output.json\n"); + return 1; + } + + // Prepare input stream. + char readBuffer[65536]; + FileReadStream is(stdin, readBuffer, sizeof(readBuffer)); + + // Prepare Filter + FilterKeyReader<FileReadStream> reader(is, argv[1], static_cast<SizeType>(strlen(argv[1]))); + + // Populates the filtered events from reader + Document document; + document.Populate(reader); + ParseResult pr = reader.GetParseResult(); + if (!pr) { + fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(pr.Offset()), GetParseError_En(pr.Code())); + return 1; + } + + // Prepare JSON writer and output stream. + char writeBuffer[65536]; + FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer)); + Writer<FileWriteStream> writer(os); + + // Write the document to standard output + document.Accept(writer); + return 0; +} http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/example/jsonx/jsonx.cpp ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/example/jsonx/jsonx.cpp b/thirdparty/rapidjson-1.1.0/example/jsonx/jsonx.cpp new file mode 100644 index 0000000..1346b57 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/example/jsonx/jsonx.cpp @@ -0,0 +1,207 @@ +// JSON to JSONx conversion exmaple, using SAX API. +// JSONx is an IBM standard format to represent JSON as XML. +// https://www-01.ibm.com/support/knowledgecenter/SS9H2Y_7.1.0/com.ibm.dp.doc/json_jsonx.html +// This example parses JSON text from stdin with validation, +// and convert to JSONx format to stdout. +// Need compile with -D__STDC_FORMAT_MACROS for defining PRId64 and PRIu64 macros. + +#include "rapidjson/reader.h" +#include "rapidjson/stringbuffer.h" +#include "rapidjson/filereadstream.h" +#include "rapidjson/filewritestream.h" +#include "rapidjson/error/en.h" +#include <cstdio> + +using namespace rapidjson; + +// For simplicity, this example only read/write in UTF-8 encoding +template <typename OutputStream> +class JsonxWriter { +public: + JsonxWriter(OutputStream& os) : os_(os), name_(), level_(0), hasName_(false) { + } + + bool Null() { + return WriteStartElement("null", true); + } + + bool Bool(bool b) { + return + WriteStartElement("boolean") && + WriteString(b ? "true" : "false") && + WriteEndElement("boolean"); + } + + bool Int(int i) { + char buffer[12]; + return WriteNumberElement(buffer, sprintf(buffer, "%d", i)); + } + + bool Uint(unsigned i) { + char buffer[11]; + return WriteNumberElement(buffer, sprintf(buffer, "%u", i)); + } + + bool Int64(int64_t i) { + char buffer[21]; + return WriteNumberElement(buffer, sprintf(buffer, "%" PRId64, i)); + } + + bool Uint64(uint64_t i) { + char buffer[21]; + return WriteNumberElement(buffer, sprintf(buffer, "%" PRIu64, i)); + } + + bool Double(double d) { + char buffer[30]; + 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") && + WriteEscapedText(str, length) && + WriteEndElement("string"); + } + + bool StartObject() { + return WriteStartElement("object"); + } + + bool Key(const char* str, SizeType length, bool) { + // backup key to name_ + name_.Clear(); + for (SizeType i = 0; i < length; i++) + name_.Put(str[i]); + hasName_ = true; + return true; + } + + bool EndObject(SizeType) { + return WriteEndElement("object"); + } + + bool StartArray() { + return WriteStartElement("array"); + } + + bool EndArray(SizeType) { + return WriteEndElement("array"); + } + +private: + bool WriteString(const char* s) { + while (*s) + os_.Put(*s++); + return true; + } + + bool WriteEscapedAttributeValue(const char* s, size_t length) { + for (size_t i = 0; i < length; i++) { + switch (s[i]) { + case '&': WriteString("&"); break; + case '<': WriteString("<"); break; + case '"': WriteString("""); break; + default: os_.Put(s[i]); break; + } + } + return true; + } + + bool WriteEscapedText(const char* s, size_t length) { + for (size_t i = 0; i < length; i++) { + switch (s[i]) { + case '&': WriteString("&"); break; + case '<': WriteString("<"); break; + default: os_.Put(s[i]); break; + } + } + return true; + } + + bool WriteStartElement(const char* type, bool emptyElement = false) { + if (level_ == 0) + if (!WriteString("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")) + return false; + + if (!WriteString("<json:") || !WriteString(type)) + return false; + + // For root element, need to add declarations + if (level_ == 0) { + if (!WriteString( + " xsi:schemaLocation=\"http://www.datapower.com/schemas/json jsonx.xsd\"" + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + " xmlns:json=\"http://www.ibm.com/xmlns/prod/2009/jsonx\"")) + return false; + } + + if (hasName_) { + hasName_ = false; + if (!WriteString(" name=\"") || + !WriteEscapedAttributeValue(name_.GetString(), name_.GetSize()) || + !WriteString("\"")) + return false; + } + + if (emptyElement) + return WriteString("/>"); + else { + level_++; + return WriteString(">"); + } + } + + bool WriteEndElement(const char* type) { + if (!WriteString("</json:") || + !WriteString(type) || + !WriteString(">")) + return false; + + // For the last end tag, flush the output stream. + if (--level_ == 0) + os_.Flush(); + + return true; + } + + bool WriteNumberElement(const char* buffer, int length) { + if (!WriteStartElement("number")) + return false; + for (int j = 0; j < length; j++) + os_.Put(buffer[j]); + return WriteEndElement("number"); + } + + OutputStream& os_; + StringBuffer name_; + unsigned level_; + bool hasName_; +}; + +int main(int, char*[]) { + // Prepare JSON reader and input stream. + Reader reader; + char readBuffer[65536]; + FileReadStream is(stdin, readBuffer, sizeof(readBuffer)); + + // Prepare JSON writer and output stream. + char writeBuffer[65536]; + FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer)); + JsonxWriter<FileWriteStream> writer(os); + + // JSON reader parse from the input stream and let writer generate the output. + if (!reader.Parse(is, writer)) { + fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode())); + return 1; + } + + return 0; +} http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/example/messagereader/messagereader.cpp ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/example/messagereader/messagereader.cpp b/thirdparty/rapidjson-1.1.0/example/messagereader/messagereader.cpp new file mode 100644 index 0000000..3399bc9 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/example/messagereader/messagereader.cpp @@ -0,0 +1,105 @@ +// Reading a message JSON with Reader (SAX-style API). +// The JSON should be an object with key-string pairs. + +#include "rapidjson/reader.h" +#include "rapidjson/error/en.h" +#include <iostream> +#include <string> +#include <map> + +using namespace std; +using namespace rapidjson; + +typedef map<string, string> MessageMap; + +#if defined(__GNUC__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(switch-enum) +#endif + +struct MessageHandler + : public BaseReaderHandler<UTF8<>, MessageHandler> { + MessageHandler() : messages_(), state_(kExpectObjectStart), name_() {} + + bool StartObject() { + switch (state_) { + case kExpectObjectStart: + state_ = kExpectNameOrObjectEnd; + return true; + default: + return false; + } + } + + bool String(const char* str, SizeType length, bool) { + switch (state_) { + case kExpectNameOrObjectEnd: + name_ = string(str, length); + state_ = kExpectValue; + return true; + case kExpectValue: + messages_.insert(MessageMap::value_type(name_, string(str, length))); + state_ = kExpectNameOrObjectEnd; + return true; + default: + return false; + } + } + + bool EndObject(SizeType) { return state_ == kExpectNameOrObjectEnd; } + + bool Default() { return false; } // All other events are invalid. + + MessageMap messages_; + enum State { + kExpectObjectStart, + kExpectNameOrObjectEnd, + kExpectValue + }state_; + std::string name_; +}; + +#if defined(__GNUC__) +RAPIDJSON_DIAG_POP +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +static void ParseMessages(const char* json, MessageMap& messages) { + Reader reader; + MessageHandler handler; + StringStream ss(json); + if (reader.Parse(ss, handler)) + messages.swap(handler.messages_); // Only change it if success. + else { + ParseErrorCode e = reader.GetParseErrorCode(); + size_t o = reader.GetErrorOffset(); + cout << "Error: " << GetParseError_En(e) << endl;; + cout << " at offset " << o << " near '" << string(json).substr(o, 10) << "...'" << endl; + } +} + +int main() { + MessageMap messages; + + const char* json1 = "{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\" }"; + cout << json1 << endl; + ParseMessages(json1, messages); + + for (MessageMap::const_iterator itr = messages.begin(); itr != messages.end(); ++itr) + cout << itr->first << ": " << itr->second << endl; + + cout << endl << "Parse a JSON with invalid schema." << endl; + const char* json2 = "{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\", \"foo\" : {} }"; + cout << json2 << endl; + ParseMessages(json2, messages); + + return 0; +}