http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/architecture.dot ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/architecture.dot b/thirdparty/rapidjson-1.1.0/doc/diagram/architecture.dot new file mode 100644 index 0000000..c816c87 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/diagram/architecture.dot @@ -0,0 +1,50 @@ +digraph { + compound=true + fontname="Inconsolata, Consolas" + fontsize=10 + margin="0,0" + ranksep=0.2 + nodesep=0.5 + penwidth=0.5 + colorscheme=spectral7 + + node [shape=box, fontname="Inconsolata, Consolas", fontsize=10, penwidth=0.5, style=filled, fillcolor=white] + edge [fontname="Inconsolata, Consolas", fontsize=10, penwidth=0.5] + + subgraph cluster1 { + margin="10,10" + labeljust="left" + label = "SAX" + style=filled + fillcolor=6 + + Reader -> Writer [style=invis] + } + + subgraph cluster2 { + margin="10,10" + labeljust="left" + label = "DOM" + style=filled + fillcolor=7 + + Value + Document + } + + Handler [label="<<concept>>\nHandler"] + + { + edge [arrowtail=onormal, dir=back] + Value -> Document + Handler -> Document + Handler -> Writer + } + + { + edge [arrowhead=vee, style=dashed, constraint=false] + Reader -> Handler [label="calls"] + Value -> Handler [label="calls"] + Document -> Reader [label="uses"] + } +} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/architecture.png ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/architecture.png b/thirdparty/rapidjson-1.1.0/doc/diagram/architecture.png new file mode 100644 index 0000000..556c7e7 Binary files /dev/null and b/thirdparty/rapidjson-1.1.0/doc/diagram/architecture.png differ http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/insituparsing.dot ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/insituparsing.dot b/thirdparty/rapidjson-1.1.0/doc/diagram/insituparsing.dot new file mode 100644 index 0000000..eca0e38 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/diagram/insituparsing.dot @@ -0,0 +1,65 @@ +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] + oldjson [label="\{|\"|m|s|g|\"|:|\"|H|e|l|l|o|\\|n|W|o|r|l|d|!|\"|,|\"|\\|u|0|0|7|3|t|a|r|s|\"|:|1|0|\}", xlabel="Before Parsing"] + //newjson [label="\{|\"|<a>m|s|g|\\0|:|\"|<b>H|e|l|l|o|\\n|W|o|r|l|d|!|\\0|\"|,|\"|<c>s|t|a|r|s|\\0|t|a|r|s|:|1|0|\}", xlabel="After Parsing"] + newjson [shape=plaintext, label=< +<table BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="2"><tr> +<td>{</td> +<td>"</td><td port="a">m</td><td>s</td><td>g</td><td bgcolor="yellow">\\0</td> +<td>:</td> +<td>"</td><td port="b">H</td><td>e</td><td>l</td><td>l</td><td>o</td><td bgcolor="yellow">\\n</td><td bgcolor="yellow">W</td><td bgcolor="yellow">o</td><td bgcolor="yellow">r</td><td bgcolor="yellow">l</td><td bgcolor="yellow">d</td><td bgcolor="yellow">!</td><td bgcolor="yellow">\\0</td><td>"</td> +<td>,</td> +<td>"</td><td port="c" bgcolor="yellow">s</td><td bgcolor="yellow">t</td><td bgcolor="yellow">a</td><td bgcolor="yellow">r</td><td bgcolor="yellow">s</td><td bgcolor="yellow">\\0</td><td>t</td><td>a</td><td>r</td><td>s</td> +<td>:</td> +<td>1</td><td>0</td> +<td>}</td> +</tr></table> +>, xlabel="After Parsing"] + } + + subgraph cluster1 { + margin="10,10" + labeljust="left" + label = "Document by In situ Parsing" + style=filled + fillcolor=gray95 + node [shape=Mrecord, style=filled, colorscheme=spectral7] + + root [label="{object|}", fillcolor=3] + + { + msg [label="{string|<a>}", fillcolor=5] + helloworld [label="{string|<a>}", fillcolor=5] + stars [label="{string|<a>}", fillcolor=5] + ten [label="{number|10}", fillcolor=6] + } + } + + oldjson -> root [label=" ParseInsitu()" lhead="cluster1"] + edge [arrowhead=vee] + root -> { msg; stars } + + edge [arrowhead="none"] + msg -> helloworld + stars -> ten + + { + edge [arrowhead=vee, arrowtail=dot, arrowsize=0.5, dir=both, tailclip=false] + msg:a:c -> newjson:a + helloworld:a:c -> newjson:b + stars:a:c -> newjson:c + } + + //oldjson -> newjson [style=invis] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/insituparsing.png ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/insituparsing.png b/thirdparty/rapidjson-1.1.0/doc/diagram/insituparsing.png new file mode 100644 index 0000000..4400c88 Binary files /dev/null and b/thirdparty/rapidjson-1.1.0/doc/diagram/insituparsing.png differ http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/iterative-parser-states-diagram.dot ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/iterative-parser-states-diagram.dot b/thirdparty/rapidjson-1.1.0/doc/diagram/iterative-parser-states-diagram.dot new file mode 100644 index 0000000..82ebfe1 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/diagram/iterative-parser-states-diagram.dot @@ -0,0 +1,62 @@ +digraph { + fontname="Inconsolata, Consolas" + fontsize=10 + margin="0,0" + penwidth=0.0 + + node [fontname="Inconsolata, Consolas", fontsize=10, penwidth=0.5] + edge [fontname="Inconsolata, Consolas", fontsize=10, penwidth=0.5] + + node [shape = doublecircle]; Start; Finish; + node [shape = box; style = "rounded, filled"; fillcolor=white ]; + + Start -> ArrayInitial [label=" ["]; + Start -> ObjectInitial [label=" {"]; + + subgraph clusterArray { + margin="10,10" + style=filled + fillcolor=gray95 + label = "Array" + + ArrayInitial; Element; ElementDelimiter; ArrayFinish; + } + + subgraph clusterObject { + margin="10,10" + style=filled + fillcolor=gray95 + label = "Object" + + ObjectInitial; MemberKey; KeyValueDelimiter; MemberValue; MemberDelimiter; ObjectFinish; + } + + ArrayInitial -> ArrayInitial [label="["]; + ArrayInitial -> ArrayFinish [label=" ]"]; + ArrayInitial -> ObjectInitial [label="{", constraint=false]; + ArrayInitial -> Element [label="string\nfalse\ntrue\nnull\nnumber"]; + + Element -> ArrayFinish [label="]"]; + Element -> ElementDelimiter [label=","]; + + ElementDelimiter -> ArrayInitial [label=" ["]; + ElementDelimiter -> ObjectInitial [label="{"]; + ElementDelimiter -> Element [label="string\nfalse\ntrue\nnull\nnumber"]; + + ObjectInitial -> ObjectFinish [label=" }"]; + ObjectInitial -> MemberKey [label=" string "]; + + MemberKey -> KeyValueDelimiter [label=":"]; + + KeyValueDelimiter -> ArrayInitial [label="["]; + KeyValueDelimiter -> ObjectInitial [label=" {"]; + KeyValueDelimiter -> MemberValue [label=" string\n false\n true\n null\n number"]; + + MemberValue -> ObjectFinish [label="}"]; + MemberValue -> MemberDelimiter [label=","]; + + MemberDelimiter -> MemberKey [label=" string "]; + + ArrayFinish -> Finish; + ObjectFinish -> Finish; +} http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/iterative-parser-states-diagram.png ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/iterative-parser-states-diagram.png b/thirdparty/rapidjson-1.1.0/doc/diagram/iterative-parser-states-diagram.png new file mode 100644 index 0000000..f315494 Binary files /dev/null and b/thirdparty/rapidjson-1.1.0/doc/diagram/iterative-parser-states-diagram.png differ http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/makefile ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/makefile b/thirdparty/rapidjson-1.1.0/doc/diagram/makefile new file mode 100644 index 0000000..3483977 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/diagram/makefile @@ -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)) http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/move1.dot ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/move1.dot b/thirdparty/rapidjson-1.1.0/doc/diagram/move1.dot new file mode 100644 index 0000000..a7c1464 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/diagram/move1.dot @@ -0,0 +1,47 @@ +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] + + subgraph cluster1 { + margin="10,10" + labeljust="left" + label = "Before" + style=filled + fillcolor=gray95 + + node [shape=Mrecord, style=filled, colorscheme=spectral7] + + { + rank = same + b1 [label="{b:number|456}", fillcolor=6] + a1 [label="{a:number|123}", fillcolor=6] + } + + a1 -> b1 [style="dashed", label="Move", dir=back] + } + + subgraph cluster2 { + margin="10,10" + labeljust="left" + label = "After" + style=filled + fillcolor=gray95 + + node [shape=Mrecord, style=filled, colorscheme=spectral7] + + { + rank = same + b2 [label="{b:null|}", fillcolor=1] + a2 [label="{a:number|456}", fillcolor=6] + } + a2 -> b2 [style=invis, dir=back] + } + b1 -> b2 [style=invis] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/move1.png ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/move1.png b/thirdparty/rapidjson-1.1.0/doc/diagram/move1.png new file mode 100644 index 0000000..ab322d0 Binary files /dev/null and b/thirdparty/rapidjson-1.1.0/doc/diagram/move1.png differ http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/move2.dot ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/move2.dot b/thirdparty/rapidjson-1.1.0/doc/diagram/move2.dot new file mode 100644 index 0000000..7037ea6 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/diagram/move2.dot @@ -0,0 +1,62 @@ +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] + + subgraph cluster1 { + margin="10,10" + labeljust="left" + label = "Before Copying (Hypothetic)" + style=filled + fillcolor=gray95 + + node [shape=Mrecord, style=filled, colorscheme=spectral7] + + c1 [label="{contact:array|}", fillcolor=4] + c11 [label="{|}"] + c12 [label="{|}"] + c13 [shape="none", label="...", style="solid"] + o1 [label="{o:object|}", fillcolor=3] + ghost [label="{o:object|}", style=invis] + + c1 -> o1 [style="dashed", label="AddMember", constraint=false] + + edge [arrowhead=vee] + c1 -> { c11; c12; c13 } + o1 -> ghost [style=invis] + } + + subgraph cluster2 { + margin="10,10" + labeljust="left" + label = "After Copying (Hypothetic)" + style=filled + fillcolor=gray95 + + node [shape=Mrecord, style=filled, colorscheme=spectral7] + + c2 [label="{contact:array|}", fillcolor=4] + c3 [label="{array|}", fillcolor=4] + c21 [label="{|}"] + c22 [label="{|}"] + c23 [shape=none, label="...", style="solid"] + o2 [label="{o:object|}", fillcolor=3] + cs [label="{string|\"contact\"}", fillcolor=5] + c31 [label="{|}"] + c32 [label="{|}"] + c33 [shape="none", label="...", style="solid"] + + edge [arrowhead=vee] + c2 -> { c21; c22; c23 } + o2 -> cs + cs -> c3 [arrowhead=none] + c3 -> { c31; c32; c33 } + } + ghost -> o2 [style=invis] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/move2.png ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/move2.png b/thirdparty/rapidjson-1.1.0/doc/diagram/move2.png new file mode 100644 index 0000000..8d4fc5b Binary files /dev/null and b/thirdparty/rapidjson-1.1.0/doc/diagram/move2.png differ http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/move3.dot ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/move3.dot b/thirdparty/rapidjson-1.1.0/doc/diagram/move3.dot new file mode 100644 index 0000000..c197b99 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/diagram/move3.dot @@ -0,0 +1,60 @@ +digraph { + compound=true + fontname="Inconsolata, Consolas" + fontsize=10 + margin="0,0" + ranksep=0.2 + penwidth=0.5 + forcelabels=true + + node [fontname="Inconsolata, Consolas", fontsize=10, penwidth=0.5] + edge [fontname="Inconsolata, Consolas", fontsize=10, arrowhead=normal] + + subgraph cluster1 { + margin="10,10" + labeljust="left" + label = "Before Moving" + style=filled + fillcolor=gray95 + + node [shape=Mrecord, style=filled, colorscheme=spectral7] + + c1 [label="{contact:array|}", fillcolor=4] + c11 [label="{|}"] + c12 [label="{|}"] + c13 [shape=none, label="...", style="solid"] + o1 [label="{o:object|}", fillcolor=3] + ghost [label="{o:object|}", style=invis] + + c1 -> o1 [style="dashed", constraint=false, label="AddMember"] + + edge [arrowhead=vee] + c1 -> { c11; c12; c13 } + o1 -> ghost [style=invis] + } + + subgraph cluster2 { + margin="10,10" + labeljust="left" + label = "After Moving" + style=filled + fillcolor=gray95 + + node [shape=Mrecord, style=filled, colorscheme=spectral7] + + c2 [label="{contact:null|}", fillcolor=1] + c3 [label="{array|}", fillcolor=4] + c21 [label="{|}"] + c22 [label="{|}"] + c23 [shape="none", label="...", style="solid"] + o2 [label="{o:object|}", fillcolor=3] + cs [label="{string|\"contact\"}", fillcolor=5] + c2 -> o2 [style="dashed", constraint=false, label="AddMember", style=invis] + + edge [arrowhead=vee] + c3 -> { c21; c22; c23 } + o2 -> cs + cs -> c3 [arrowhead=none] + } + ghost -> o2 [style=invis] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/move3.png ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/move3.png b/thirdparty/rapidjson-1.1.0/doc/diagram/move3.png new file mode 100644 index 0000000..558470f Binary files /dev/null and b/thirdparty/rapidjson-1.1.0/doc/diagram/move3.png differ http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/normalparsing.dot ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/normalparsing.dot b/thirdparty/rapidjson-1.1.0/doc/diagram/normalparsing.dot new file mode 100644 index 0000000..b15941b --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/diagram/normalparsing.dot @@ -0,0 +1,56 @@ +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] + normaljson [label="\{|\"|m|s|g|\"|:|\"|H|e|l|l|o|\\|n|W|o|r|l|d|!|\"|,|\"|\\|u|0|0|7|3|t|a|r|s\"|:|1|0|\}"] + + { + rank = same + msgstring [label="m|s|g|\\0"] + helloworldstring [label="H|e|l|l|o|\\n|W|o|r|l|d|!|\\0"] + starsstring [label="s|t|a|r|s\\0"] + } + } + + subgraph cluster1 { + margin="10,10" + labeljust="left" + label = "Document by Normal Parsing" + style=filled + fillcolor=gray95 + node [shape=Mrecord, style=filled, colorscheme=spectral7] + + root [label="{object|}", fillcolor=3] + + { + msg [label="{string|<a>}", fillcolor=5] + helloworld [label="{string|<a>}", fillcolor=5] + stars [label="{string|<a>}", fillcolor=5] + ten [label="{number|10}", fillcolor=6] + } + } + + normaljson -> root [label=" Parse()" lhead="cluster1"] + edge [arrowhead=vee] + root -> { msg; stars } + + edge [arrowhead="none"] + msg -> helloworld + stars -> ten + + edge [arrowhead=vee, arrowtail=dot, arrowsize=0.5, dir=both, tailclip=false] + msg:a:c -> msgstring:w + helloworld:a:c -> helloworldstring:w + stars:a:c -> starsstring:w + + msgstring -> helloworldstring -> starsstring [style=invis] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/normalparsing.png ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/normalparsing.png b/thirdparty/rapidjson-1.1.0/doc/diagram/normalparsing.png new file mode 100644 index 0000000..702512c Binary files /dev/null and b/thirdparty/rapidjson-1.1.0/doc/diagram/normalparsing.png differ http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/simpledom.dot ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/simpledom.dot b/thirdparty/rapidjson-1.1.0/doc/diagram/simpledom.dot new file mode 100644 index 0000000..959cdbb --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/diagram/simpledom.dot @@ -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"] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/simpledom.png ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/simpledom.png b/thirdparty/rapidjson-1.1.0/doc/diagram/simpledom.png new file mode 100644 index 0000000..38d9c5d Binary files /dev/null and b/thirdparty/rapidjson-1.1.0/doc/diagram/simpledom.png differ http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/tutorial.dot ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/tutorial.dot b/thirdparty/rapidjson-1.1.0/doc/diagram/tutorial.dot new file mode 100644 index 0000000..138ddc3 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/diagram/tutorial.dot @@ -0,0 +1,58 @@ +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] + + 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] + + { + hello [label="{string|\"hello\"}", fillcolor=5] + t [label="{string|\"t\"}", fillcolor=5] + f [label="{string|\"f\"}", fillcolor=5] + n [label="{string|\"n\"}", fillcolor=5] + i [label="{string|\"i\"}", fillcolor=5] + pi [label="{string|\"pi\"}", fillcolor=5] + a [label="{string|\"a\"}", fillcolor=5] + + world [label="{string|\"world\"}", fillcolor=5] + true [label="{true|}", fillcolor=7] + false [label="{false|}", fillcolor=2] + null [label="{null|}", fillcolor=1] + i1 [label="{number|123}", fillcolor=6] + pi1 [label="{number|3.1416}", fillcolor=6] + array [label="{array|size=4}", fillcolor=4] + + a1 [label="{number|1}", fillcolor=6] + a2 [label="{number|2}", fillcolor=6] + a3 [label="{number|3}", fillcolor=6] + a4 [label="{number|4}", fillcolor=6] + } + + edge [arrowhead=vee] + root -> { hello; t; f; n; i; pi; a } + array -> { a1; a2; a3; a4 } + + edge [arrowhead=none] + hello -> world + t -> true + f -> false + n -> null + i -> i1 + pi -> pi1 + a -> array + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/tutorial.png ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/tutorial.png b/thirdparty/rapidjson-1.1.0/doc/diagram/tutorial.png new file mode 100644 index 0000000..8a12924 Binary files /dev/null and b/thirdparty/rapidjson-1.1.0/doc/diagram/tutorial.png differ http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/utilityclass.dot ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/utilityclass.dot b/thirdparty/rapidjson-1.1.0/doc/diagram/utilityclass.dot new file mode 100644 index 0000000..1492a8a --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/diagram/utilityclass.dot @@ -0,0 +1,73 @@ +digraph { + rankdir=LR + compound=true + fontname="Inconsolata, Consolas" + fontsize=10 + margin="0,0" + ranksep=0.3 + nodesep=0.15 + penwidth=0.5 + colorscheme=spectral7 + + node [shape=box, fontname="Inconsolata, Consolas", fontsize=10, penwidth=0.5, style=filled, fillcolor=white] + edge [fontname="Inconsolata, Consolas", fontsize=10, penwidth=0.5] + + subgraph cluster0 { + style=filled + fillcolor=4 + + Encoding [label="<<concept>>\nEncoding"] + + edge [arrowtail=onormal, dir=back] + Encoding -> { UTF8; UTF16; UTF32; ASCII; AutoUTF } + UTF16 -> { UTF16LE; UTF16BE } + UTF32 -> { UTF32LE; UTF32BE } + } + + subgraph cluster1 { + style=filled + fillcolor=5 + + Stream [label="<<concept>>\nStream"] + InputByteStream [label="<<concept>>\nInputByteStream"] + OutputByteStream [label="<<concept>>\nOutputByteStream"] + + edge [arrowtail=onormal, dir=back] + Stream -> { + StringStream; InsituStringStream; StringBuffer; + EncodedInputStream; EncodedOutputStream; + AutoUTFInputStream; AutoUTFOutputStream + InputByteStream; OutputByteStream + } + + InputByteStream -> { MemoryStream; FlieReadStream } + OutputByteStream -> { MemoryBuffer; FileWriteStream } + } + + subgraph cluster2 { + style=filled + fillcolor=3 + + Allocator [label="<<concept>>\nAllocator"] + + edge [arrowtail=onormal, dir=back] + Allocator -> { CrtAllocator; MemoryPoolAllocator } + } + + { + edge [arrowtail=odiamond, arrowhead=vee, dir=both] + EncodedInputStream -> InputByteStream + EncodedOutputStream -> OutputByteStream + AutoUTFInputStream -> InputByteStream + AutoUTFOutputStream -> OutputByteStream + MemoryPoolAllocator -> Allocator [label="base", tailport=s] + } + + { + edge [arrowhead=vee, style=dashed] + AutoUTFInputStream -> AutoUTF + AutoUTFOutputStream -> AutoUTF + } + + //UTF32LE -> Stream [style=invis] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/diagram/utilityclass.png ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/diagram/utilityclass.png b/thirdparty/rapidjson-1.1.0/doc/diagram/utilityclass.png new file mode 100644 index 0000000..ce029a4 Binary files /dev/null and b/thirdparty/rapidjson-1.1.0/doc/diagram/utilityclass.png differ http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/dom.md ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/dom.md b/thirdparty/rapidjson-1.1.0/doc/dom.md new file mode 100644 index 0000000..6c541fe --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/dom.md @@ -0,0 +1,280 @@ +# DOM + +Document Object Model(DOM) is an in-memory representation of JSON for query and manipulation. The basic usage of DOM is described in [Tutorial](doc/tutorial.md). This section will describe some details and more advanced usages. + +[TOC] + +# Template {#Template} + +In the tutorial, `Value` and `Document` was used. Similarly to `std::string`, these are actually `typedef` of template classes: + +~~~~~~~~~~cpp +namespace rapidjson { + +template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > +class GenericValue { + // ... +}; + +template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > +class GenericDocument : public GenericValue<Encoding, Allocator> { + // ... +}; + +typedef GenericValue<UTF8<> > Value; +typedef GenericDocument<UTF8<> > Document; + +} // namespace rapidjson +~~~~~~~~~~ + +User can customize these template parameters. + +## Encoding {#Encoding} + +The `Encoding` parameter specifies the encoding of JSON String value in memory. Possible options are `UTF8`, `UTF16`, `UTF32`. Note that, these 3 types are also template class. `UTF8<>` is `UTF8<char>`, which means using char to store the characters. You may refer to [Encoding](doc/encoding.md) for details. + +Suppose a Windows application would query localization strings stored in JSON files. Unicode-enabled functions in Windows use UTF-16 (wide character) encoding. No matter what encoding was used in JSON files, we can store the strings in UTF-16 in memory. + +~~~~~~~~~~cpp +using namespace rapidjson; + +typedef GenericDocument<UTF16<> > WDocument; +typedef GenericValue<UTF16<> > WValue; + +FILE* fp = fopen("localization.json", "rb"); // non-Windows use "r" + +char readBuffer[256]; +FileReadStream bis(fp, readBuffer, sizeof(readBuffer)); + +AutoUTFInputStream<unsigned, FileReadStream> eis(bis); // wraps bis into eis + +WDocument d; +d.ParseStream<0, AutoUTF<unsigned> >(eis); + +const WValue locale(L"ja"); // Japanese + +MessageBoxW(hWnd, d[locale].GetString(), L"Test", MB_OK); +~~~~~~~~~~ + +## Allocator {#Allocator} + +The `Allocator` defines which allocator class is used when allocating/deallocating memory for `Document`/`Value`. `Document` owns, or references to an `Allocator` instance. On the other hand, `Value` does not do so, in order to reduce memory consumption. + +The default allocator used in `GenericDocument` is `MemoryPoolAllocator`. This allocator actually allocate memory sequentially, and cannot deallocate one by one. This is very suitable when parsing a JSON into a DOM tree. + +Another allocator is `CrtAllocator`, of which CRT is short for C RunTime library. This allocator simply calls the standard `malloc()`/`realloc()`/`free()`. When there is a lot of add and remove operations, this allocator may be preferred. But this allocator is far less efficient than `MemoryPoolAllocator`. + +# Parsing {#Parsing} + +`Document` provides several functions for parsing. In below, (1) is the fundamental function, while the others are helpers which call (1). + +~~~~~~~~~~cpp +using namespace rapidjson; + +// (1) Fundamental +template <unsigned parseFlags, typename SourceEncoding, typename InputStream> +GenericDocument& GenericDocument::ParseStream(InputStream& is); + +// (2) Using the same Encoding for stream +template <unsigned parseFlags, typename InputStream> +GenericDocument& GenericDocument::ParseStream(InputStream& is); + +// (3) Using default parse flags +template <typename InputStream> +GenericDocument& GenericDocument::ParseStream(InputStream& is); + +// (4) In situ parsing +template <unsigned parseFlags> +GenericDocument& GenericDocument::ParseInsitu(Ch* str); + +// (5) In situ parsing, using default parse flags +GenericDocument& GenericDocument::ParseInsitu(Ch* str); + +// (6) Normal parsing of a string +template <unsigned parseFlags, typename SourceEncoding> +GenericDocument& GenericDocument::Parse(const Ch* str); + +// (7) Normal parsing of a string, using same Encoding of Document +template <unsigned parseFlags> +GenericDocument& GenericDocument::Parse(const Ch* str); + +// (8) Normal parsing of a string, using default parse flags +GenericDocument& GenericDocument::Parse(const Ch* str); +~~~~~~~~~~ + +The examples of [tutorial](doc/tutorial.md) uses (8) for normal parsing of string. The examples of [stream](doc/stream.md) uses the first three. *In situ* parsing will be described soon. + +The `parseFlags` are combination of the following bit-flags: + +Parse flags | Meaning +------------------------------|----------------------------------- +`kParseNoFlags` | No flag is set. +`kParseDefaultFlags` | Default parse flags. It is equal to macro `RAPIDJSON_PARSE_DEFAULT_FLAGS`, which is defined as `kParseNoFlags`. +`kParseInsituFlag` | In-situ(destructive) parsing. +`kParseValidateEncodingFlag` | Validate encoding of JSON strings. +`kParseIterativeFlag` | Iterative(constant complexity in terms of function call stack size) parsing. +`kParseStopWhenDoneFlag` | After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate `kParseErrorDocumentRootNotSingular` error. Using this flag for parsing multiple JSONs in the same stream. +`kParseFullPrecisionFlag` | Parse number in full precision (slower). If this flag is not set, the normal precision (faster) is used. Normal precision has maximum 3 [ULP](http://en.wikipedia.org/wiki/Unit_in_the_last_place) error. +`kParseCommentsFlag` | Allow one-line `// ...` and multi-line `/* ... */` comments (relaxed JSON syntax). +`kParseNumbersAsStringsFlag` | Parse numerical type values as strings. +`kParseTrailingCommasFlag` | Allow trailing commas at the end of objects and arrays (relaxed JSON syntax). +`kParseNanAndInfFlag` | Allow parsing `NaN`, `Inf`, `Infinity`, `-Inf` and `-Infinity` as `double` values (relaxed JSON syntax). + +By using a non-type template parameter, instead of a function parameter, C++ compiler can generate code which is optimized for specified combinations, improving speed, and reducing code size (if only using a single specialization). The downside is the flags needed to be determined in compile-time. + +The `SourceEncoding` parameter defines what encoding is in the stream. This can be differed to the `Encoding` of the `Document`. See [Transcoding and Validation](#TranscodingAndValidation) section for details. + +And the `InputStream` is type of input stream. + +## Parse Error {#ParseError} + +When the parse processing succeeded, the `Document` contains the parse results. When there is an error, the original DOM is *unchanged*. And the error state of parsing can be obtained by `bool HasParseError()`, `ParseErrorCode GetParseError()` and `size_t GetParseOffset()`. + +Parse Error Code | Description +--------------------------------------------|--------------------------------------------------- +`kParseErrorNone` | No error. +`kParseErrorDocumentEmpty` | The document is empty. +`kParseErrorDocumentRootNotSingular` | The document root must not follow by other values. +`kParseErrorValueInvalid` | Invalid value. +`kParseErrorObjectMissName` | Missing a name for object member. +`kParseErrorObjectMissColon` | Missing a colon after a name of object member. +`kParseErrorObjectMissCommaOrCurlyBracket` | Missing a comma or `}` after an object member. +`kParseErrorArrayMissCommaOrSquareBracket` | Missing a comma or `]` after an array element. +`kParseErrorStringUnicodeEscapeInvalidHex` | Incorrect hex digit after `\\u` escape in string. +`kParseErrorStringUnicodeSurrogateInvalid` | The surrogate pair in string is invalid. +`kParseErrorStringEscapeInvalid` | Invalid escape character in string. +`kParseErrorStringMissQuotationMark` | Missing a closing quotation mark in string. +`kParseErrorStringInvalidEncoding` | Invalid encoding in string. +`kParseErrorNumberTooBig` | Number too big to be stored in `double`. +`kParseErrorNumberMissFraction` | Miss fraction part in number. +`kParseErrorNumberMissExponent` | Miss exponent in number. + +The offset of error is defined as the character number from beginning of stream. Currently RapidJSON does not keep track of line number. + +To get an error message, RapidJSON provided a English messages in `rapidjson/error/en.h`. User can customize it for other locales, or use a custom localization system. + +Here shows an example of parse error handling. + +~~~~~~~~~~cpp +#include "rapidjson/document.h" +#include "rapidjson/error/en.h" + +// ... +Document d; +if (d.Parse(json).HasParseError()) { + fprintf(stderr, "\nError(offset %u): %s\n", + (unsigned)d.GetErrorOffset(), + GetParseError_En(d.GetParseError())); + // ... +} +~~~~~~~~~~ + +## In Situ Parsing {#InSituParsing} + +From [Wikipedia](http://en.wikipedia.org/wiki/In_situ): + +> *In situ* ... is a Latin phrase that translates literally to "on site" or "in position". It means "locally", "on site", "on the premises" or "in place" to describe an event where it takes place, and is used in many different contexts. +> ... +> (In computer science) An algorithm is said to be an in situ algorithm, or in-place algorithm, if the extra amount of memory required to execute the algorithm is O(1), that is, does not exceed a constant no matter how large the input. For example, heapsort is an in situ sorting algorithm. + +In normal parsing process, a large overhead is to decode JSON strings and copy them to other buffers. *In situ* parsing decodes those JSON string at the place where it is stored. It is possible in JSON because the length of decoded string is always shorter than or equal to the one in JSON. In this context, decoding a JSON string means to process the escapes, such as `"\n"`, `"\u1234"`, etc., and add a null terminator (`'\0'`)at the end of string. + +The following diagrams compare normal and *in situ* parsing. The JSON string values contain pointers to the decoded string. + + + +In normal parsing, the decoded string are copied to freshly allocated buffers. `"\\n"` (2 characters) is decoded as `"\n"` (1 character). `"\\u0073"` (6 characters) is decoded as `"s"` (1 character). + + + +*In situ* parsing just modified the original JSON. Updated characters are highlighted in the diagram. If the JSON string does not contain escape character, such as `"msg"`, the parsing process merely replace the closing double quotation mark with a null character. + +Since *in situ* parsing modify the input, the parsing API needs `char*` instead of `const char*`. + +~~~~~~~~~~cpp +// Read whole file into a buffer +FILE* fp = fopen("test.json", "r"); +fseek(fp, 0, SEEK_END); +size_t filesize = (size_t)ftell(fp); +fseek(fp, 0, SEEK_SET); +char* buffer = (char*)malloc(filesize + 1); +size_t readLength = fread(buffer, 1, filesize, fp); +buffer[readLength] = '\0'; +fclose(fp); + +// In situ parsing the buffer into d, buffer will also be modified +Document d; +d.ParseInsitu(buffer); + +// Query/manipulate the DOM here... + +free(buffer); +// Note: At this point, d may have dangling pointers pointed to the deallocated buffer. +~~~~~~~~~~ + +The JSON strings are marked as const-string. But they may not be really "constant". The life cycle of it depends on the JSON buffer. + +In situ parsing minimizes allocation overheads and memory copying. Generally this improves cache coherence, which is an important factor of performance in modern computer. + +There are some limitations of *in situ* parsing: + +1. The whole JSON is in memory. +2. The source encoding in stream and target encoding in document must be the same. +3. The buffer need to be retained until the document is no longer used. +4. If the DOM need to be used for long period after parsing, and there are few JSON strings in the DOM, retaining the buffer may be a memory waste. + +*In situ* parsing is mostly suitable for short-term JSON that only need to be processed once, and then be released from memory. In practice, these situation is very common, for example, deserializing JSON to C++ objects, processing web requests represented in JSON, etc. + +## Transcoding and Validation {#TranscodingAndValidation} + +RapidJSON supports conversion between Unicode formats (officially termed UCS Transformation Format) internally. During DOM parsing, the source encoding of the stream can be different from the encoding of the DOM. For example, the source stream contains a UTF-8 JSON, while the DOM is using UTF-16 encoding. There is an example code in [EncodedInputStream](doc/stream.md). + +When writing a JSON from DOM to output stream, transcoding can also be used. An example is in [EncodedOutputStream](doc/stream.md). + +During transcoding, the source string is decoded to into Unicode code points, and then the code points are encoded in the target format. During decoding, it will validate the byte sequence in the source string. If it is not a valid sequence, the parser will be stopped with `kParseErrorStringInvalidEncoding` error. + +When the source encoding of stream is the same as encoding of DOM, by default, the parser will *not* validate the sequence. User may use `kParseValidateEncodingFlag` to force validation. + +# Techniques {#Techniques} + +Some techniques about using DOM API is discussed here. + +## DOM as SAX Event Publisher + +In RapidJSON, stringifying a DOM with `Writer` may be look a little bit weired. + +~~~~~~~~~~cpp +// ... +Writer<StringBuffer> writer(buffer); +d.Accept(writer); +~~~~~~~~~~ + +Actually, `Value::Accept()` is responsible for publishing SAX events about the value to the handler. With this design, `Value` and `Writer` are decoupled. `Value` can generate SAX events, and `Writer` can handle those events. + +User may create custom handlers for transforming the DOM into other formats. For example, a handler which converts the DOM into XML. + +For more about SAX events and handler, please refer to [SAX](doc/sax.md). + +## User Buffer {#UserBuffer} + +Some applications may try to avoid memory allocations whenever possible. + +`MemoryPoolAllocator` can support this by letting user to provide a buffer. The buffer can be on the program stack, or a "scratch buffer" which is statically allocated (a static/global array) for storing temporary data. + +`MemoryPoolAllocator` will use the user buffer to satisfy allocations. When the user buffer is used up, it will allocate a chunk of memory from the base allocator (by default the `CrtAllocator`). + +Here is an example of using stack memory. The first allocator is for storing values, while the second allocator is for storing temporary data during parsing. + +~~~~~~~~~~cpp +typedef GenericDocument<UTF8<>, MemoryPoolAllocator<>, MemoryPoolAllocator<>> DocumentType; +char valueBuffer[4096]; +char parseBuffer[1024]; +MemoryPoolAllocator<> valueAllocator(valueBuffer, sizeof(valueBuffer)); +MemoryPoolAllocator<> parseAllocator(parseBuffer, sizeof(parseBuffer)); +DocumentType d(&valueAllocator, sizeof(parseBuffer), &parseAllocator); +d.Parse(json); +~~~~~~~~~~ + +If the total size of allocation is less than 4096+1024 bytes during parsing, this code does not invoke any heap allocation (via `new` or `malloc()`) at all. + +User can query the current memory consumption in bytes via `MemoryPoolAllocator::Size()`. And then user can determine a suitable size of user buffer. http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/dom.zh-cn.md ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/dom.zh-cn.md b/thirdparty/rapidjson-1.1.0/doc/dom.zh-cn.md new file mode 100644 index 0000000..d93f603 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/dom.zh-cn.md @@ -0,0 +1,284 @@ +# DOM + +ææ¡£å¯¹è±¡æ¨¡åï¼Document Object Model, DOMï¼æ¯ä¸ç§ç½äºå åä¸ç JSON 表示æ¹å¼ï¼ä»¥ä¾æ¥è¯¢åæä½ãæä»¬å·±äº [æç¨](doc/tutorial.zh-cn.md) ä¸ä»ç»äº DOM çåºæ¬ç¨æ³ï¼æ¬èå°è®²è¿°ä¸äºç»èåé«çº§ç¨æ³ã + +[TOC] + +# æ¨¡æ¿ {#Template} + +æç¨ä¸ä½¿ç¨äº `Value` å `Document` ç±»åãä¸ `std::string` ç¸ä¼¼ï¼è¿äºç±»åå ¶å®æ¯ä¸¤ä¸ªæ¨¡æ¿ç±»ç `typedef`ï¼ + +~~~~~~~~~~cpp +namespace rapidjson { + +template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > +class GenericValue { + // ... +}; + +template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > +class GenericDocument : public GenericValue<Encoding, Allocator> { + // ... +}; + +typedef GenericValue<UTF8<> > Value; +typedef GenericDocument<UTF8<> > Document; + +} // namespace rapidjson +~~~~~~~~~~ + +使ç¨è å¯ä»¥èªå®ä¹è¿äºæ¨¡æ¿åæ°ã + +## ç¼ç {#Encoding} + +`Encoding` åæ°ææå¨å åä¸ç JSON String 使ç¨åªç§ç¼ç ãå¯è¡çé项æ `UTF8`ã`UTF16`ã`UTF32`ãè¦æ³¨æè¿ 3 个类åå ¶å®ä¹æ¯æ¨¡æ¿ç±»ã`UTF8<>` çå `UTF8<char>`ï¼è¿ä»£è¡¨å®ä½¿ç¨ `char` æ¥åå¨åç¬¦ä¸²ãæ´å¤ç»èå¯ä»¥åè [ç¼ç ](doc/encoding.zh-cn.md)ã + +è¿éæ¯ä¸ä¸ªä¾åãå设ä¸ä¸ª Windows åºç¨è½¯ä»¶å¸ææ¥è¯¢åå¨äº JSON ä¸çæ¬å°åå符串ãWindows ä¸å« Unicode ç彿°ä½¿ç¨ UTF-16ï¼å®½å符ï¼ç¼ç ãæ è®º JSON æä»¶ä½¿ç¨åªç§ç¼ç ï¼æä»¬é½å¯ä»¥æå符串以 UTF-16 å½¢å¼åå¨å¨å åã + +~~~~~~~~~~cpp +using namespace rapidjson; + +typedef GenericDocument<UTF16<> > WDocument; +typedef GenericValue<UTF16<> > WValue; + +FILE* fp = fopen("localization.json", "rb"); // é Windows å¹³å°ä½¿ç¨ "r" + +char readBuffer[256]; +FileReadStream bis(fp, readBuffer, sizeof(readBuffer)); + +AutoUTFInputStream<unsigned, FileReadStream> eis(bis); // å è£ bis æ eis + +WDocument d; +d.ParseStream<0, AutoUTF<unsigned> >(eis); + +const WValue locale(L"ja"); // Japanese + +MessageBoxW(hWnd, d[locale].GetString(), L"Test", MB_OK); +~~~~~~~~~~ + +## åé å¨ {#Allocator} + +`Allocator` å®ä¹å½ `Document`/`Value` åé æéæ¾å åæ¶ä½¿ç¨é£ä¸ªåé ç±»ã`Document` æ¥ææå¼ç¨å°ä¸ä¸ª `Allocator` å®ä¾ãè为äºèçå åï¼`Value` 没æè¿ä¹åã + +`GenericDocument` ç缺çåé 卿¯ `MemoryPoolAllocator`ãæ¤åé å¨å®é ä¸ä¼é¡ºåºå°åé å åï¼å¹¶ä¸ä¸è½éä¸éæ¾ãå½è¦è§£æä¸ä¸ª JSON å¹¶çæ DOMï¼è¿ç§åé 卿¯é常åéçã + +RapidJSON è¿æä¾å¦ä¸ä¸ªåé å¨ `CrtAllocator`ï¼å½ä¸ CRT æ¯ C è¿è¡åºï¼C RunTime libraryï¼ç缩åãæ¤åé å¨ç®åå°è¯»ç¨æ åç `malloc()`/`realloc()`/`free()`ã彿们éè¦è®¸å¤å¢åæä½ï¼è¿ç§åé å¨ä¼æ´ä¸ºéåãç¶èè¿ç§åé å¨è¿è¿æ¯ `MemoryPoolAllocator` 使ã + +# è§£æ {#Parsing} + +`Document` æä¾å 个解æå½æ°ã以ä¸ç (1) æ¯æ ¹æ¬ç彿°ï¼å ¶ä»é½æ¯è°ç¨ (1) çåå©å½æ°ã + +~~~~~~~~~~cpp +using namespace rapidjson; + +// (1) æ ¹æ¬ +template <unsigned parseFlags, typename SourceEncoding, typename InputStream> +GenericDocument& GenericDocument::ParseStream(InputStream& is); + +// (2) ä½¿ç¨æµçç¼ç +template <unsigned parseFlags, typename InputStream> +GenericDocument& GenericDocument::ParseStream(InputStream& is); + +// (3) 使ç¨ç¼ºçæ å¿ +template <typename InputStream> +GenericDocument& GenericDocument::ParseStream(InputStream& is); + +// (4) åä½è§£æ +template <unsigned parseFlags> +GenericDocument& GenericDocument::ParseInsitu(Ch* str); + +// (5) åä½è§£æï¼ä½¿ç¨ç¼ºçæ å¿ +GenericDocument& GenericDocument::ParseInsitu(Ch* str); + +// (6) æ£å¸¸è§£æä¸ä¸ªå符串 +template <unsigned parseFlags, typename SourceEncoding> +GenericDocument& GenericDocument::Parse(const Ch* str); + +// (7) æ£å¸¸è§£æä¸ä¸ªå符串ï¼ä½¿ç¨ Document çç¼ç +template <unsigned parseFlags> +GenericDocument& GenericDocument::Parse(const Ch* str); + +// (8) æ£å¸¸è§£æä¸ä¸ªå符串ï¼ä½¿ç¨ç¼ºçæ å¿ +GenericDocument& GenericDocument::Parse(const Ch* str); +~~~~~~~~~~ + +[æç¨](doc/tutorial.zh-cn.md) ä¸çä¾ä½¿ç¨ (8) 廿£å¸¸è§£æå符串ãè [æµ](doc/stream.zh-cn.md) çä¾å使ç¨å 3 ä¸ªå½æ°ãæä»¬å°ç¨åä»ç»åä½ï¼*In situ*ï¼ è§£æã + +`parseFlags` æ¯ä»¥ä¸ä½æ ç½®çç»åï¼ + +è§£æä½æ å¿ | æä¹ +------------------------------|----------------------------------- +`kParseNoFlags` | 没æä»»ä½æ å¿ã +`kParseDefaultFlags` | 缺ççè§£æé项ãå®çäº `RAPIDJSON_PARSE_DEFAULT_FLAGS` å®ï¼æ¤å®å®ä¹ä¸º `kParseNoFlags`ã +`kParseInsituFlag` | åä½ï¼ç ´åæ§ï¼è§£æã +`kParseValidateEncodingFlag` | æ ¡éª JSON å符串çç¼ç ã +`kParseIterativeFlag` | è¿ä»£å¼ï¼è°ç¨å æ 大å°ä¸ºå¸¸æ°å¤æåº¦ï¼è§£æã +`kParseStopWhenDoneFlag` | å½ä»æµè§£æäºä¸ä¸ªå®æ´ç JSON æ ¹èç¹ä¹åï¼åæ¢ç»§ç»å¤çä½ä¸çæµãå½ä½¿ç¨äºæ¤æ å¿ï¼è§£æå¨ä¾¿ä¸ä¼äº§ç `kParseErrorDocumentRootNotSingular` é误ãå¯ä½¿ç¨æ¬æ å¿å»è§£æåä¸ä¸ªæµéçå¤ä¸ª JSONã +`kParseFullPrecisionFlag` | 使ç¨å®æ´ç精确度å»è§£ææ°åï¼è¾æ ¢ï¼ãå¦ä¸è®¾ç½®æ¤æ èï¼åä¼ä½¿ç¨æ£å¸¸ç精确度ï¼è¾å¿«ï¼ãæ£å¸¸ç²¾ç¡®åº¦ä¼ææå¤ 3 个 [ULP](http://en.wikipedia.org/wiki/Unit_in_the_last_place) ç误差ã +`kParseCommentsFlag` | 容许åè¡ `// ...` åå¤è¡ `/* ... */` 注éï¼æ¾å®½ç JSON è¯æ³ï¼ã +`kParseNumbersAsStringsFlag` | ææ°åç±»åè§£ææå符串ã +`kParseTrailingCommasFlag` | 容许å¨å¯¹è±¡åæ°ç»ç»æå嫿éå·ï¼æ¾å®½ç JSON è¯æ³ï¼ã +`kParseNanAndInfFlag` | 容许 `NaN`ã`Inf`ã`Infinity`ã`-Inf` å `-Infinity` ä½ä¸º `double` å¼ï¼æ¾å®½ç JSON è¯æ³ï¼ã + +ç±äºä½¿ç¨äºéç±»åæ¨¡æ¿åæ°ï¼è䏿¯å½æ°åæ°ï¼C++ ç¼è¯å¨è½ä¸ºä¸ªå«ç»åçæä»£ç ï¼ä»¥æ¹åæ§è½ååå°ä»£ç 尺寸ï¼å½åªç¨åç§ç¹åï¼ãç¼ºç¹æ¯éè¦å¨ç¼è¯æå³å®æ å¿ã + +`SourceEncoding` åæ°å®ä¹æµä½¿ç¨äºä»ä¹ç¼ç ãè¿ä¸ `Document` ç `Encoding` ä¸ç¸åãç»èå¯åè [转ç åæ ¡éª](#TranscodingAndValidation) ä¸èã + +æ¤å¤ `InputStream` æ¯è¾å ¥æµçç±»åã + +## è§£æé误 {#ParseError} + +å½è§£æè¿ç¨é¡ºå©å®æï¼`Document` 便ä¼å«æè§£æç»æãå½è¿ç¨åºç°é误ï¼åæ¥ç DOM ä¼ * ç»´æä¸ä¾¿ *ãå¯ä½¿ç¨ `bool HasParseError()`ã`ParseErrorCode GetParseError()` å `size_t GetParseOffset()` è·åè§£æçéè¯¯ç¶æã + +è§£æéè¯¯ä»£å· | æè¿° +--------------------------------------------|--------------------------------------------------- +`kParseErrorNone` | æ é误ã +`kParseErrorDocumentEmpty` | ææ¡£æ¯ç©ºçã +`kParseErrorDocumentRootNotSingular` | ææ¡£çæ ¹åé¢ä¸è½æå ¶å®å¼ã +`kParseErrorValueInvalid` | ä¸åæ³çå¼ã +`kParseErrorObjectMissName` | Object æå缺å°ååã +`kParseErrorObjectMissColon` | Object æåååå缺å°åå·ã +`kParseErrorObjectMissCommaOrCurlyBracket` | Object æåå缺å°éå·æ `}`ã +`kParseErrorArrayMissCommaOrSquareBracket` | Array å ç´ å缺å°éå·æ `]` ã +`kParseErrorStringUnicodeEscapeInvalidHex` | String ä¸ç `\\u` 转ä¹ç¬¦åå«éåå è¿ä½æ°åã +`kParseErrorStringUnicodeSurrogateInvalid` | String ä¸ç代ç对ï¼surrogate pairï¼ä¸åæ³ã +`kParseErrorStringEscapeInvalid` | String å«éæ³è½¬ä¹å符ã +`kParseErrorStringMissQuotationMark` | String 缺å°å ³éå¼å·ã +`kParseErrorStringInvalidEncoding` | String å«éæ³ç¼ç ã +`kParseErrorNumberTooBig` | Number çå¼å¤ªå¤§ï¼ä¸è½åå¨äº `double`ã +`kParseErrorNumberMissFraction` | Number 缺å°äºå°æ°é¨åã +`kParseErrorNumberMissExponent` | Number 缺å°äºææ°ã + +é误çåç§»éå®ä¹ä¸ºä»æµå¼å§è³é误å¤çå符æ°éãç®å RapidJSON ä¸è®°å½é误è¡å·ã + +è¦åå¾é误讯æ¯ï¼RapidJSON å¨ `rapidjson/error/en.h` 䏿ä¾äºè±æé误讯æ¯ã使ç¨è å¯ä»¥ä¿®æ¹å®ç¨äºå ¶ä»è¯è¨ç¯å¢ï¼æä½¿ç¨ä¸ä¸ªèªå®ä¹çæ¬å°åç³»ç»ã + +以䏿¯ä¸ä¸ªå¤çé误çä¾åã + +~~~~~~~~~~cpp +#include "rapidjson/document.h" +#include "rapidjson/error/en.h" + +// ... +Document d; +if (d.Parse(json).HasParseError()) { + fprintf(stderr, "\nError(offset %u): %s\n", + (unsigned)d.GetErrorOffset(), + GetParseError_En(d.GetParseErrorCode())); + // ... +} +~~~~~~~~~~ + +## åä½è§£æ {#InSituParsing} + +æ ¹æ® [ç»´åºç¾ç§](http://en.wikipedia.org/wiki/In_situ): + +> *In situ* ... is a Latin phrase that translates literally to "on site" or "in position". It means "locally", "on site", "on the premises" or "in place" to describe an event where it takes place, and is used in many different contexts. +> ... +> (In computer science) An algorithm is said to be an in situ algorithm, or in-place algorithm, if the extra amount of memory required to execute the algorithm is O(1), that is, does not exceed a constant no matter how large the input. For example, heapsort is an in situ sorting algorithm. + +> ç¿»è¯ï¼*In situ*â¦â¦æ¯ä¸ä¸ªæä¸æçè¯ï¼åé¢ä¸çæææ¯æãç°åºãããå¨ä½ç½®ããå¨è®¸å¤ä¸åè¯å¢ä¸ï¼å®æè¿°ä¸ä¸ªäºä»¶åççä½ç½®ï¼ææãæ¬å°ãããç°åºãããå¨å¤æãããå°±ä½ãã +> â¦â¦ +> ï¼å¨è®¡ç®æºç§å¦ä¸ï¼ä¸ä¸ªç®æ³è¥ç§°ä¸ºåä½ç®æ³ï¼æå¨ä½ç®æ³ï¼æ¯ææ§è¡è¯¥ç®æ³æéçé¢å¤å åç©ºé´æ¯ O(1) çï¼æ¢å¥è¯è¯´ï¼æ 论è¾å ¥å¤§å°é½åªéè¦å¸¸æ°ç©ºé´ãä¾å¦ï¼å æåºæ¯ä¸ä¸ªå使åºç®æ³ã + +卿£å¸¸çè§£æè¿ç¨ä¸ï¼å¯¹ JSON string è§£ç å¹¶å¤å¶è³å ¶ä»ç¼å²åºæ¯ä¸ä¸ªå¾å¤§çå¼éãåä½è§£æï¼*in situ* parsingï¼æè¿äº JSON string ç´æ¥è§£ç äºå®åæ¥åå¨çå°æ¹ãç±äºè§£ç åç string é¿åº¦æ»æ¯çäºæçäºåæ¥å¨åäº JSON ç stringï¼æä»¥è¿æ¯å¯è¡çãå¨è¿ä¸ªè¯å¢ä¸ï¼å¯¹ JSON string è¿è¡è§£ç æ¯æå¤ç转ä¹ç¬¦ï¼å¦ `"\n"`ã`"\u1234"` çï¼ä»¥åå¨ string æ«ç«¯å å ¥ç©ºç»æ¢ç¬¦å· (`'\0'`)ã + +以ä¸ç徿¯è¾æ£å¸¸ååä½è§£æãJSON string å¼å 嫿åè§£ç åçå符串ã + + + +卿£å¸¸è§£æä¸ï¼è§£ç åçå符串被å¤å¶è³å ¨æ°åé çç¼å²åºä¸ã`"\\n"`ï¼2 个å符ï¼è¢«è§£ç æ `"\n"`ï¼1 个å符ï¼ã`"\\u0073"`ï¼6 个å符ï¼è¢«è§£ç æ `"s"`ï¼1 个å符ï¼ã + + + +åä½è§£æç´æ¥ä¿®æ¹äºåæ¥ç JSONãå¾ä¸é«äº®äºè¢«æ´æ°çå符ãè¥ JSON string ä¸å«è½¬ä¹ç¬¦ï¼ä¾å¦ `"msg"`ï¼é£ä¹è§£æè¿ç¨ä» ä» æ¯ä»¥ç©ºå符代æ¿ç»æåå¼å·ã + +ç±äºåä½è§£æä¿®æ¹äºè¾å ¥ï¼å ¶è§£æ API éè¦ `char*` èé `const char*`ã + +~~~~~~~~~~cpp +// ææ´ä¸ªæä»¶è¯»å ¥ buffer +FILE* fp = fopen("test.json", "r"); +fseek(fp, 0, SEEK_END); +size_t filesize = (size_t)ftell(fp); +fseek(fp, 0, SEEK_SET); +char* buffer = (char*)malloc(filesize + 1); +size_t readLength = fread(buffer, 1, filesize, fp); +buffer[readLength] = '\0'; +fclose(fp); + +// åä½è§£æ buffer è³ dï¼buffer å 容ä¼è¢«ä¿®æ¹ã +Document d; +d.ParseInsitu(buffer); + +// 卿¤æ¥è¯¢ãä¿®æ¹ DOMâ¦â¦ + +free(buffer); +// 注æï¼å¨è¿ä¸ªä½ç½®ï¼d å¯è½å«ææåå·²è¢«éæ¾ç buffer çæ¬ç©ºæé +~~~~~~~~~~ + +JSON string ä¼è¢«æä¸ const-string çæ å¿ãä½å®ä»¬å¯è½å¹¶éçæ£çã常æ°ããå®ççå½å¨æåå³äºåå¨ JSON çç¼å²åºã + +åä½è§£ææåé å¼éåå åå¤å¶åè³æå°ãéå¸¸è¿æ ·åè½æ¹åç¼åä¸è´æ§ï¼èè¿å¯¹ç°ä»£è®¡ç®æºæ¥è¯´æ¯ä¸ä¸ªéè¦çæ§è½å ç´ ã + +åä½è§£ææä»¥ä¸éå¶ï¼ + +1. æ´ä¸ª JSON é¡»åå¨å¨å åä¹ä¸ã +2. æµçæ¥æºç¼ç ä¸ææ¡£çç®æ ç¼ç å¿ é¡»ç¸åã +3. éè¦ä¿çç¼å²åºï¼ç´è³ææ¡£ä¸å被使ç¨ã +4. è¥ DOM éè¦å¨è§£æåè¢«é¿æä½¿ç¨ï¼è DOM å åªæå¾å° JSON stringï¼ä¿çç¼å²åºå¯è½é æå åæµªè´¹ã + +åä½è§£ææéåç¨äºçæçãç¨å®å³å¼ç JSONãå®é åºç¨ä¸ï¼è¿äºåºåæ¯é常æ®éçï¼ä¾å¦ååºåå JSON è³ C++ 对象ãå¤ç以 JSON 表示ç web 请æ±çã + +## 转ç 䏿 ¡éª {#TranscodingAndValidation} + +RapidJSON å 鍿¯æä¸å Unicode æ ¼å¼ï¼æ£å¼çæ¯è¯æ¯ UCS åæ¢æ ¼å¼ï¼é´ç转æ¢ãå¨ DOM è§£ææ¶ï¼æµçæ¥æºç¼ç ä¸ DOM çç¼ç å¯ä»¥ä¸åãä¾å¦ï¼æ¥æºæµå¯è½å«æ UTF-8 ç JSONï¼è DOM åä½¿ç¨ UTF-16 ç¼ç ãå¨ [EncodedInputStream](doc/stream.zh-cn.md) ä¸èéæä¸ä¸ªä¾åã + +å½ä» DOM è¾åºä¸ä¸ª JSON è³è¾åºæµä¹æ¶ï¼ä¹å¯ä»¥ä½¿ç¨è½¬ç åè½ãå¨ [EncodedOutputStream](doc/stream.zh-cn.md) ä¸èéæä¸ä¸ªä¾åã + +å¨è½¬ç è¿ç¨ä¸ï¼ä¼ææ¥æº string è§£ç æ Unicode ç ç¹ï¼ç¶åæç ç¹ç¼ç æç®æ æ ¼å¼ãå¨è§£ç æ¶ï¼å®ä¼æ ¡éªæ¥æº string çåèåºåæ¯å¦åæ³ãè¥éä¸éåæ³åºåï¼è§£æå¨ä¼åæ¢å¹¶è¿å `kParseErrorStringInvalidEncoding` é误ã + +彿¥æºç¼ç ä¸ DOM çç¼ç ç¸åï¼è§£æå¨ç¼ºçå° * ä¸ä¼ * æ ¡éªåºåã使ç¨è å¯å¼å¯ `kParseValidateEncodingFlag` å»å¼ºå¶æ ¡éªã + +# æå·§ {#Techniques} + +è¿é讨论ä¸äº DOM API çä½¿ç¨æå·§ã + +## æ DOM ä½ä¸º SAX äºä»¶å表è + +å¨ RapidJSON ä¸ï¼å©ç¨ `Writer` æ DOM çæ JSON çåæ³ï¼çæ¥æç¹å¥æªã + +~~~~~~~~~~cpp +// ... +Writer<StringBuffer> writer(buffer); +d.Accept(writer); +~~~~~~~~~~ + +å®é ä¸ï¼`Value::Accept()` æ¯è´è´£åå¸è¯¥å¼ç¸å ³ç SAX äºä»¶è³å¤çå¨çãéè¿è¿ä¸ªè®¾è®¡ï¼`Value` å `Writer` è§£é¤äºå¶åã`Value` å¯çæ SAX äºä»¶ï¼è `Writer` åå¯ä»¥å¤çè¿äºäºä»¶ã + +使ç¨è å¯ä»¥å建èªå®ä¹çå¤çå¨ï¼å»æ DOM è½¬æ¢æå ¶å®æ ¼å¼ãä¾å¦ï¼ä¸ä¸ªæ DOM è½¬æ¢æ XML çå¤çå¨ã + +è¦ç¥éæ´å¤å ³äº SAX äºä»¶ä¸å¤çå¨ï¼å¯åé [SAX](doc/sax.zh-cn.md)ã + +## 使ç¨è ç¼å²åº {#UserBuffer} + +许å¤åºç¨è½¯ä»¶å¯è½éè¦å°½éåå°å ååé ã + +`MemoryPoolAllocator` å¯ä»¥å¸®å©è¿æ¹é¢ï¼å®å®¹è®¸ä½¿ç¨è æä¾ä¸ä¸ªç¼å²åºã该ç¼å²åºå¯è½ç½®äºç¨åºå æ ï¼ææ¯ä¸ä¸ªéæåé çãè稿ç¼å²åºï¼scratch bufferï¼ãï¼ä¸ä¸ªéæï¼å ¨å±çæ°ç»ï¼ï¼ç¨äºå¨åä¸´æ¶æ°æ®ã + +`MemoryPoolAllocator` ä¼å ç¨ä½¿ç¨è ç¼å²åºå»è§£å³åé 请æ±ãå½ä½¿ç¨è ç¼å²åºç¨å®ï¼å°±ä¼ä»åºç¡åé å¨ï¼ç¼ºç为 `CrtAllocator`ï¼åé ä¸åå åã + +以䏿¯ä½¿ç¨å æ å åçä¾åï¼ç¬¬ä¸ä¸ªåé å¨ç¨äºåå¨å¼ï¼ç¬¬äºä¸ªç¨äºè§£ææ¶ç临æ¶ç¼å²ã + +~~~~~~~~~~cpp +typedef GenericDocument<UTF8<>, MemoryPoolAllocator<>, MemoryPoolAllocator<>> DocumentType; +char valueBuffer[4096]; +char parseBuffer[1024]; +MemoryPoolAllocator<> valueAllocator(valueBuffer, sizeof(valueBuffer)); +MemoryPoolAllocator<> parseAllocator(parseBuffer, sizeof(parseBuffer)); +DocumentType d(&valueAllocator, sizeof(parseBuffer), &parseAllocator); +d.Parse(json); +~~~~~~~~~~ + +è¥è§£ææ¶åé æ»éå°äº 4096+1024 åèæ¶ï¼è¿æ®µä»£ç ä¸ä¼é æä»»ä½å å ååé ï¼ç» `new` æ `malloc()`ï¼ã + +使ç¨è å¯ä»¥éè¿ `MemoryPoolAllocator::Size()` æ¥è¯¢å½åå·²åçå å大å°ãé£ä¹ä½¿ç¨è å¯ä»¥æå®ä½¿ç¨è ç¼å²åºçåé大å°ã http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/encoding.md ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/encoding.md b/thirdparty/rapidjson-1.1.0/doc/encoding.md new file mode 100644 index 0000000..8f8ff7f --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/encoding.md @@ -0,0 +1,146 @@ +# Encoding + +According to [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf), + +> (in Introduction) JSON text is a sequence of Unicode code points. + +The earlier [RFC4627](http://www.ietf.org/rfc/rfc4627.txt) stated that, + +> (in §3) JSON text SHALL be encoded in Unicode. The default encoding is UTF-8. + +> (in §6) JSON may be represented using UTF-8, UTF-16, or UTF-32. When JSON is written in UTF-8, JSON is 8bit compatible. When JSON is written in UTF-16 or UTF-32, the binary content-transfer-encoding must be used. + +RapidJSON supports various encodings. It can also validate the encodings of JSON, and transconding JSON among encodings. All these features are implemented internally, without the need for external libraries (e.g. [ICU](http://site.icu-project.org/)). + +[TOC] + +# Unicode {#Unicode} +From [Unicode's official website](http://www.unicode.org/standard/WhatIsUnicode.html): +> Unicode provides a unique number for every character, +> no matter what the platform, +> no matter what the program, +> no matter what the language. + +Those unique numbers are called code points, which is in the range `0x0` to `0x10FFFF`. + +## Unicode Transformation Format {#UTF} + +There are various encodings for storing Unicode code points. These are called Unicode Transformation Format (UTF). RapidJSON supports the most commonly used UTFs, including + +* UTF-8: 8-bit variable-width encoding. It maps a code point to 1â4 bytes. +* UTF-16: 16-bit variable-width encoding. It maps a code point to 1â2 16-bit code units (i.e., 2â4 bytes). +* UTF-32: 32-bit fixed-width encoding. It directly maps a code point to a single 32-bit code unit (i.e. 4 bytes). + +For UTF-16 and UTF-32, the byte order (endianness) does matter. Within computer memory, they are often stored in the computer's endianness. However, when it is stored in file or transferred over network, we need to state the byte order of the byte sequence, either little-endian (LE) or big-endian (BE). + +RapidJSON provide these encodings via the structs in `rapidjson/encodings.h`: + +~~~~~~~~~~cpp +namespace rapidjson { + +template<typename CharType = char> +struct UTF8; + +template<typename CharType = wchar_t> +struct UTF16; + +template<typename CharType = wchar_t> +struct UTF16LE; + +template<typename CharType = wchar_t> +struct UTF16BE; + +template<typename CharType = unsigned> +struct UTF32; + +template<typename CharType = unsigned> +struct UTF32LE; + +template<typename CharType = unsigned> +struct UTF32BE; + +} // namespace rapidjson +~~~~~~~~~~ + +For processing text in memory, we normally use `UTF8`, `UTF16` or `UTF32`. For processing text via I/O, we may use `UTF8`, `UTF16LE`, `UTF16BE`, `UTF32LE` or `UTF32BE`. + +When using the DOM-style API, the `Encoding` template parameter in `GenericValue<Encoding>` and `GenericDocument<Encoding>` indicates the encoding to be used to represent JSON string in memory. So normally we will use `UTF8`, `UTF16` or `UTF32` for this template parameter. The choice depends on operating systems and other libraries that the application is using. For example, Windows API represents Unicode characters in UTF-16, while most Linux distributions and applications prefer UTF-8. + +Example of UTF-16 DOM declaration: + +~~~~~~~~~~cpp +typedef GenericDocument<UTF16<> > WDocument; +typedef GenericValue<UTF16<> > WValue; +~~~~~~~~~~ + +For a detail example, please check the example in [DOM's Encoding](doc/stream.md) section. + +## Character Type {#CharacterType} + +As shown in the declaration, each encoding has a `CharType` template parameter. Actually, it may be a little bit confusing, but each `CharType` stores a code unit, not a character (code point). As mentioned in previous section, a code point may be encoded to 1â4 code units for UTF-8. + +For `UTF16(LE|BE)`, `UTF32(LE|BE)`, the `CharType` must be integer type of at least 2 and 4 bytes respectively. + +Note that C++11 introduces `char16_t` and `char32_t`, which can be used for `UTF16` and `UTF32` respectively. + +## AutoUTF {#AutoUTF} + +Previous encodings are statically bound in compile-time. In other words, user must know exactly which encodings will be used in the memory or streams. However, sometimes we may need to read/write files of different encodings. The encoding needed to be decided in runtime. + +`AutoUTF` is an encoding designed for this purpose. It chooses which encoding to be used according to the input or output stream. Currently, it should be used with `EncodedInputStream` and `EncodedOutputStream`. + +## ASCII {#ASCII} + +Although the JSON standards did not mention about [ASCII](http://en.wikipedia.org/wiki/ASCII), sometimes we would like to write 7-bit ASCII JSON for applications that cannot handle UTF-8. Since any JSON can represent unicode characters in escaped sequence `\uXXXX`, JSON can always be encoded in ASCII. + +Here is an example for writing a UTF-8 DOM into ASCII: + +~~~~~~~~~~cpp +using namespace rapidjson; +Document d; // UTF8<> +// ... +StringBuffer buffer; +Writer<StringBuffer, Document::EncodingType, ASCII<> > writer(buffer); +d.Accept(writer); +std::cout << buffer.GetString(); +~~~~~~~~~~ + +ASCII can be used in input stream. If the input stream contains bytes with values above 127, it will cause `kParseErrorStringInvalidEncoding` error. + +ASCII *cannot* be used in memory (encoding of `Document` or target encoding of `Reader`), as it cannot represent Unicode code points. + +# Validation & Transcoding {#ValidationTranscoding} + +When RapidJSON parses a JSON, it can validate the input JSON, whether it is a valid sequence of a specified encoding. This option can be turned on by adding `kParseValidateEncodingFlag` in `parseFlags` template parameter. + +If the input encoding and output encoding is different, `Reader` and `Writer` will automatically transcode (convert) the text. In this case, `kParseValidateEncodingFlag` is not necessary, as it must decode the input sequence. And if the sequence was unable to be decoded, it must be invalid. + +## Transcoder {#Transcoder} + +Although the encoding functions in RapidJSON are designed for JSON parsing/generation, user may abuse them for transcoding of non-JSON strings. + +Here is an example for transcoding a string from UTF-8 to UTF-16: + +~~~~~~~~~~cpp +#include "rapidjson/encodings.h" + +using namespace rapidjson; + +const char* s = "..."; // UTF-8 string +StringStream source(s); +GenericStringBuffer<UTF16<> > target; + +bool hasError = false; +while (source.Peek() != '\0') + if (!Transcoder<UTF8<>, UTF16<> >::Transcode(source, target)) { + hasError = true; + break; + } + +if (!hasError) { + const wchar_t* t = target.GetString(); + // ... +} +~~~~~~~~~~ + +You may also use `AutoUTF` and the associated streams for setting source/target encoding in runtime. http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/encoding.zh-cn.md ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/encoding.zh-cn.md b/thirdparty/rapidjson-1.1.0/doc/encoding.zh-cn.md new file mode 100644 index 0000000..6816923 --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/encoding.zh-cn.md @@ -0,0 +1,152 @@ +# ç¼ç + +æ ¹æ® [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf)ï¼ + +> (in Introduction) JSON text is a sequence of Unicode code points. +> +> ç¿»è¯ï¼JSON ææ¬æ¯ Unicode ç ç¹çåºåã + +è¾æ©ç [RFC4627](http://www.ietf.org/rfc/rfc4627.txt) ç³æï¼ + +> (in §3) JSON text SHALL be encoded in Unicode. The default encoding is UTF-8. +> +> ç¿»è¯ï¼JSON ææ¬åºè¯¥ä»¥ Unicode ç¼ç ã缺ççç¼ç 为 UTF-8ã + +> (in §6) JSON may be represented using UTF-8, UTF-16, or UTF-32. When JSON is written in UTF-8, JSON is 8bit compatible. When JSON is written in UTF-16 or UTF-32, the binary content-transfer-encoding must be used. +> +> ç¿»è¯ï¼JSON å¯ä½¿ç¨ UTF-8ãUTF-16 æ UTF-18 表示ãå½ JSON 以 UTF-8 åå ¥ï¼è¯¥ JSON æ¯ 8 ä½å ¼å®¹çãå½ JSON 以 UTF-16 æ UTF-32 åå ¥ï¼å°±å¿ 须使ç¨äºè¿å¶çå å®¹ä¼ éç¼ç ã + +RapidJSON æ¯æå¤ç§ç¼ç ãå®ä¹è½æ£æ¥ JSON çç¼ç ï¼ä»¥åå¨ä¸åç¼ç ä¸è¿è¡è½¬ç ãææè¿äºåè½é½æ¯å¨å é¨å®ç°ï¼æ é使ç¨å¤é¨çç¨åºåºï¼å¦ [ICU](http://site.icu-project.org/)ï¼ã + +[TOC] + +# Unicode {#Unicode} +æ ¹æ® [Unicode ç宿¹ç½ç«](http://www.unicode.org/standard/translations/t-chinese.html)ï¼ +>Unicode ç»æ¯ä¸ªå符æä¾äºä¸ä¸ªå¯ä¸çæ°åï¼ +ä¸è®ºæ¯ä»ä¹å¹³å°ã +ä¸è®ºæ¯ä»ä¹ç¨åºã +ä¸è®ºæ¯ä»ä¹è¯è¨ã + +è¿äºå¯ä¸æ°å称为ç ç¹ï¼code pointï¼ï¼å ¶èå´ä»ä¹ `0x0` è³ `0x10FFFF` ä¹é´ã + +## Unicode è½¬æ¢æ ¼å¼ {#UTF} + +åå¨ Unicode ç ç¹æå¤ç§ç¼ç æ¹å¼ãè¿äºç§°ä¸º Unicode è½¬æ¢æ ¼å¼ï¼Unicode Transformation Format, UTFï¼ãRapidJSON æ¯ææå¸¸ç¨ç UTFï¼å æ¬ï¼ + +* UTF-8ï¼8 ä½å¯åé¿åº¦ç¼ç ã宿ä¸ä¸ªç ç¹æ å°è³ 1 è³ 4 个åèã +* UTF-16ï¼16 ä½å¯åé¿åº¦ç¼ç ã宿ä¸ä¸ªç ç¹æ å°è³ 1 è³ 2 个 16 ä½ç¼ç åå ï¼å³ 2 è³ 4 个åèï¼ã +* UTF-32ï¼32 ä½åºå®é¿åº¦ç¼ç ãå®ç´æ¥æç ç¹æ å°è³å个 32 ä½ç¼ç åå ï¼å³ 4 åèï¼ã + +å¯¹äº UTF-16 å UTF-32 æ¥è¯´ï¼åèåºï¼endiannessï¼æ¯æå½±åçãå¨å åä¸ï¼å®ä»¬é叏齿¯ä»¥è¯¥è®¡ç®æºçåèåºæ¥åå¨ãç¶èï¼å½è¦å¨å卿件䏿å¨ç½ä¸ä¼ è¾ï¼æä»¬éè¦ææåèåºåçåèåºï¼æ¯å°ç«¯ï¼little endian, LEï¼è¿æ¯å¤§ç«¯ï¼big-endian, BEï¼ã + +RapidJSON éè¿ `rapidjson/encodings.h` ä¸ç struct 廿ä¾åç§ç¼ç ï¼ + +~~~~~~~~~~cpp +namespace rapidjson { + +template<typename CharType = char> +struct UTF8; + +template<typename CharType = wchar_t> +struct UTF16; + +template<typename CharType = wchar_t> +struct UTF16LE; + +template<typename CharType = wchar_t> +struct UTF16BE; + +template<typename CharType = unsigned> +struct UTF32; + +template<typename CharType = unsigned> +struct UTF32LE; + +template<typename CharType = unsigned> +struct UTF32BE; + +} // namespace rapidjson +~~~~~~~~~~ + +对äºå¨å åä¸çææ¬ï¼æä»¬æ£å¸¸ä¼ä½¿ç¨ `UTF8`ã`UTF16` æ `UTF32`ã对äºå¤çç»è¿ I/O çææ¬ï¼æä»¬å¯ä½¿ç¨ `UTF8`ã`UTF16LE`ã`UTF16BE`ã`UTF32LE` æ `UTF32BE`ã + +å½ä½¿ç¨ DOM 飿 ¼ç APIï¼`GenericValue<Encoding>` å `GenericDocument<Encoding>` éç `Encoding` 模æ¿åæ°æ¯ç¨äºææå åä¸åå¨ç JSON å符串使ç¨åªç§ç¼ç ãå æ¤é常æä»¬ä¼å¨æ¤åæ°ä¸ä½¿ç¨ `UTF8`ã`UTF16` æ `UTF32`ãå¦ä½éæ©ï¼è§ä¹åºç¨è½¯ä»¶æä½¿ç¨çæä½ç³»ç»åå ¶ä»ç¨åºåºãä¾å¦ï¼Windows API ä½¿ç¨ UTF-16 表示 Unicode å符ï¼è夿°ç Linux åè¡çæ¬ååºç¨è½¯ä»¶åæ´å欢 UTF-8ã + +ä½¿ç¨ UTF-16 ç DOM 声æä¾åï¼ + +~~~~~~~~~~cpp +typedef GenericDocument<UTF16<> > WDocument; +typedef GenericValue<UTF16<> > WValue; +~~~~~~~~~~ + +å¯ä»¥å¨ [DOM's Encoding](doc/stream.zh-cn.md) ä¸èçå°æ´è¯¦ç»ç使ç¨ä¾åã + +## å符类å {#CharacterType} + +ä»ä¹åç声æä¸å¯ä»¥çå°ï¼æ¯ä¸ªç¼ç 齿ä¸ä¸ª `CharType` 模æ¿åæ°ãè¿å¯è½æ¯è¾å®¹ææ··æ·ï¼å®é ä¸ï¼æ¯ä¸ª `CharType` åå¨ä¸ä¸ªç¼ç åå ï¼è䏿¯ä¸ä¸ªå符ï¼ç ç¹ï¼ãå¦ä¹åæè°åï¼å¨ UTF-8 ä¸ä¸ä¸ªç ç¹å¯è½ä¼ç¼ç æ 1 è³ 4 个ç¼ç åå ã + +å¯¹äº `UTF16(LE|BE)` å `UTF32(LE|BE)` æ¥è¯´ï¼`CharType` å¿ é¡»å嫿¯ä¸ä¸ªè³å° 2 å 4 åèçæ´æ°ç±»åã + +注æ C++11 æ°æ·»äº `char16_t` å `char32_t` ç±»åï¼ä¹å¯åå«ç¨äº `UTF16` å `UTF32`ã + +## AutoUTF {#AutoUTF} + +ä¸è¿°æä»ç»çç¼ç 齿¯å¨ç¼è¯æéææ·å®çãæ¢å¥è¯è¯´ï¼ä½¿ç¨è å¿ é¡»ç¥éå åææµä¹ä¸ä½¿ç¨äºåªç§ç¼ç ãç¶èï¼ææ¶åæä»¬å¯è½éè¦è¯»åä¸åç¼ç çæä»¶ï¼èä¸è¿äºç¼ç éè¦å¨è¿è¡æ¶æè½å³å®ã + +`AutoUTF` æ¯ä¸ºæ¤è设计çç¼ç ã宿 ¹æ®è¾å ¥æè¾åºæµæ¥éæ©ä½¿ç¨åªç§ç¼ç ãç®åå®åºè¯¥ä¸ `EncodedInputStream` å `EncodedOutputStream` ç»å使ç¨ã + +## ASCII {#ASCII} + +è½ç¶ JSON æ åå¹¶æªæå [ASCII](http://en.wikipedia.org/wiki/ASCII)ï¼ææ¶åæä»¬å¸æåå ¥ 7 ä½ç ASCII JSONï¼ä»¥ä¾æªè½å¤ç UTF-8 çåºç¨ç¨åºä½¿ç¨ãç±äºä»» JSON é½å¯ä»¥æ Unicode å符表示为 `\uXXXX` 转ä¹åºåï¼JSON æ»æ¯å¯ç¨ ASCII æ¥ç¼ç ã + +以ä¸çä¾åæ UTF-8 ç DOM åæ ASCII ç JSONï¼ + +~~~~~~~~~~cpp +using namespace rapidjson; +Document d; // UTF8<> +// ... +StringBuffer buffer; +Writer<StringBuffer, Document::EncodingType, ASCII<> > writer(buffer); +d.Accept(writer); +std::cout << buffer.GetString(); +~~~~~~~~~~ + +ASCII å¯ç¨äºè¾å ¥æµãå½è¾å ¥æµå å«å¤§äº 127 çåèï¼å°±ä¼å¯¼è´ `kParseErrorStringInvalidEncoding` é误ã + +ASCII * ä¸è½ * ç¨äºå åï¼`Document` çç¼ç ï¼æ `Reader` çç®æ ç¼ç )ï¼å 为å®ä¸è½è¡¨ç¤º Unicode ç ç¹ã + +# æ ¡éªå转ç {#ValidationTranscoding} + +å½ RapidJSON è§£æä¸ä¸ª JSON æ¶ï¼å®è½æ ¡éªè¾å ¥ JSONï¼å¤æå®æ¯å¦ææ æç¼ç çåæ³åºåãè¦å¼å¯æ¤é项ï¼è¯·æ `kParseValidateEncodingFlag` å å ¥ `parseFlags` 模æ¿åæ°ã + +è¥è¾å ¥ç¼ç åè¾åºç¼ç å¹¶ä¸ç¸åï¼`Reader` å `Writer` ä¼ç®æææ¬è½¬ç ãå¨è¿ç§æ åµä¸ï¼å¹¶ä¸éè¦ `kParseValidateEncodingFlag`ï¼å 为å®å¿ 须解ç è¾å ¥åºåãè¥åºåä¸è½è¢«è§£ç ï¼å®å¿ ç¶æ¯ä¸åæ³çã + +## 转ç å¨ {#Transcoder} + +è½ç¶ RapidJSON çç¼ç åè½æ¯ä¸º JSON è§£æï¼çæè设计ï¼ä½¿ç¨è ä¹å¯ä»¥â滥ç¨âå®ä»¬æ¥ä¸ºé JSON å符串转ç ã + +以ä¸çä¾åæ UTF-8 åç¬¦ä¸²è½¬ç æ UTF-16ï¼ + +~~~~~~~~~~cpp +#include "rapidjson/encodings.h" + +using namespace rapidjson; + +const char* s = "..."; // UTF-8 string +StringStream source(s); +GenericStringBuffer<UTF16<> > target; + +bool hasError = false; +while (source.Peek() != '\0') + if (!Transcoder<UTF8<>, UTF16<> >::Transcode(source, target)) { + hasError = true; + break; + } + +if (!hasError) { + const wchar_t* t = target.GetString(); + // ... +} +~~~~~~~~~~ + +ä½ ä¹å¯ä»¥ç¨ `AutoUTF` å对åºçæµæ¥å¨è¿è¡æ¶è®¾ç½®å æºï¼ç®çä¹ç¼ç ã http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/fd280b5c/thirdparty/rapidjson-1.1.0/doc/faq.md ---------------------------------------------------------------------- diff --git a/thirdparty/rapidjson-1.1.0/doc/faq.md b/thirdparty/rapidjson-1.1.0/doc/faq.md new file mode 100644 index 0000000..1b0541c --- /dev/null +++ b/thirdparty/rapidjson-1.1.0/doc/faq.md @@ -0,0 +1,289 @@ +# FAQ + +[TOC] + +## General + +1. What is RapidJSON? + + RapidJSON is a C++ library for parsing and generating JSON. You may check all [features](doc/features.md) of it. + +2. Why is RapidJSON named so? + + It is inspired by [RapidXML](http://rapidxml.sourceforge.net/), which is a fast XML DOM parser. + +3. Is RapidJSON similar to RapidXML? + + RapidJSON borrowed some designs of RapidXML, including *in situ* parsing, header-only library. But the two APIs are completely different. Also RapidJSON provide many features that are not in RapidXML. + +4. Is RapidJSON free? + + Yes, it is free under MIT license. It can be used in commercial applications. Please check the details in [license.txt](https://github.com/miloyip/rapidjson/blob/master/license.txt). + +5. Is RapidJSON small? What are its dependencies? + + Yes. A simple executable which parses a JSON and prints its statistics is less than 30KB on Windows. + + RapidJSON depends on C++ standard library only. + +6. How to install RapidJSON? + + Check [Installation section](https://miloyip.github.io/rapidjson/). + +7. Can RapidJSON run on my platform? + + RapidJSON has been tested in many combinations of operating systems, compilers and CPU architecture by the community. But we cannot ensure that it can be run on your particular platform. Building and running the unit test suite will give you the answer. + +8. Does RapidJSON support C++03? C++11? + + RapidJSON was firstly implemented for C++03. Later it added optional support of some C++11 features (e.g., move constructor, `noexcept`). RapidJSON shall be compatible with C++03 or C++11 compliant compilers. + +9. Does RapidJSON really work in real applications? + + Yes. It is deployed in both client and server real applications. A community member reported that RapidJSON in their system parses 50 million JSONs daily. + +10. How RapidJSON is tested? + + RapidJSON contains a unit test suite for automatic testing. [Travis](https://travis-ci.org/miloyip/rapidjson/)(for Linux) and [AppVeyor](https://ci.appveyor.com/project/miloyip/rapidjson/)(for Windows) will compile and run the unit test suite for all modifications. The test process also uses Valgrind (in Linux) to detect memory leaks. + +11. Is RapidJSON well documented? + + RapidJSON provides user guide and API documentationn. + +12. Are there alternatives? + + Yes, there are a lot alternatives. For example, [nativejson-benchmark](https://github.com/miloyip/nativejson-benchmark) has a listing of open-source C/C++ JSON libraries. [json.org](http://www.json.org/) also has a list. + +## JSON + +1. What is JSON? + + JSON (JavaScript Object Notation) is a lightweight data-interchange format. It uses human readable text format. More details of JSON can be referred to [RFC7159](http://www.ietf.org/rfc/rfc7159.txt) and [ECMA-404](http://www.ecma-international.org/publications/standards/Ecma-404.htm). + +2. What are applications of JSON? + + JSON are commonly used in web applications for transferring structured data. It is also used as a file format for data persistence. + +2. Does RapidJSON conform to the JSON standard? + + Yes. RapidJSON is fully compliance with [RFC7159](http://www.ietf.org/rfc/rfc7159.txt) and [ECMA-404](http://www.ecma-international.org/publications/standards/Ecma-404.htm). It can handle corner cases, such as supporting null character and surrogate pairs in JSON strings. + +3. Does RapidJSON support relaxed syntax? + + Currently no. RapidJSON only support the strict standardized format. Support on related syntax is under discussion in this [issue](https://github.com/miloyip/rapidjson/issues/36). + +## DOM and SAX + +1. What is DOM style API? + + Document Object Model (DOM) is an in-memory representation of JSON for query and manipulation. + +2. What is SAX style API? + + SAX is an event-driven API for parsing and generation. + +3. Should I choose DOM or SAX? + + DOM is easy for query and manipulation. SAX is very fast and memory-saving but often more difficult to be applied. + +4. What is *in situ* parsing? + + *in situ* parsing decodes the JSON strings directly into the input JSON. This is an optimization which can reduce memory consumption and improve performance, but the input JSON will be modified. Check [in-situ parsing](doc/dom.md) for details. + +5. When does parsing generate an error? + + The parser generates an error when the input JSON contains invalid syntax, or a value can not be represented (a number is too big), or the handler of parsers terminate the parsing. Check [parse error](doc/dom.md) for details. + +6. What error information is provided? + + The error is stored in `ParseResult`, which includes the error code and offset (number of characters from the beginning of JSON). The error code can be translated into human-readable error message. + +7. Why not just using `double` to represent JSON number? + + Some applications use 64-bit unsigned/signed integers. And these integers cannot be converted into `double` without loss of precision. So the parsers detects whether a JSON number is convertible to different types of integers and/or `double`. + +8. How to clear-and-minimize a document or value? + + Call one of the `SetXXX()` methods - they call destructor which deallocates DOM data: + + ~~~~~~~~~~cpp + Document d; + ... + d.SetObject(); // clear and minimize + ~~~~~~~~~~ + + Alternatively, use equivalent of the [C++ swap with temporary idiom](https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Clear-and-minimize): + ~~~~~~~~~~cpp + Value(kObjectType).Swap(d); + ~~~~~~~~~~ + or equivalent, but sightly longer to type: + ~~~~~~~~~~cpp + d.Swap(Value(kObjectType).Move()); + ~~~~~~~~~~ + +9. How to insert a document node into another document? + + Let's take the following two DOM trees represented as JSON documents: + ~~~~~~~~~~cpp + Document person; + person.Parse("{\"person\":{\"name\":{\"first\":\"Adam\",\"last\":\"Thomas\"}}}"); + + Document address; + address.Parse("{\"address\":{\"city\":\"Moscow\",\"street\":\"Quiet\"}}"); + ~~~~~~~~~~ + Let's assume we want to merge them in such way that the whole `address` document becomes a node of the `person`: + ~~~~~~~~~~js + { "person": { + "name": { "first": "Adam", "last": "Thomas" }, + "address": { "city": "Moscow", "street": "Quiet" } + } + } + ~~~~~~~~~~ + + The most important requirement to take care of document and value life-cycle as well as consistent memory managent using the right allocator during the value transfer. + + Simple yet most efficient way to achieve that is to modify the `address` definition above to initialize it with allocator of the `person` document, then we just add the root member of the value: + ~~~~~~~~~~cpp + Documnet address(person.GetAllocator()); + ... + person["person"].AddMember("address", address["address"], person.GetAllocator()); + ~~~~~~~~~~ +Alternatively, if we don't want to explicitly refer to the root value of `address` by name, we can refer to it via iterator: + ~~~~~~~~~~cpp + auto addressRoot = address.MemberBegin(); + person["person"].AddMember(addressRoot->name, addressRoot->value, person.GetAllocator()); + ~~~~~~~~~~ + + Second way is to deep-clone the value from the address document: + ~~~~~~~~~~cpp + Value addressValue = Value(address["address"], person.GetAllocator()); + person["person"].AddMember("address", addressValue, person.GetAllocator()); + ~~~~~~~~~~ + +## Document/Value (DOM) + +1. What is move semantics? Why? + + Instead of copy semantics, move semantics is used in `Value`. That means, when assigning a source value to a target value, the ownership of source value is moved to the target value. + + Since moving is faster than copying, this design decision forces user to aware of the copying overhead. + +2. How to copy a value? + + There are two APIs: constructor with allocator, and `CopyFrom()`. See [Deep Copy Value](doc/tutorial.md) for an example. + +3. Why do I need to provide the length of string? + + Since C string is null-terminated, the length of string needs to be computed via `strlen()`, with linear runtime complexity. This incurs an unncessary overhead of many operations, if the user already knows the length of string. + + Also, RapidJSON can handle `\u0000` (null character) within a string. If a string contains null characters, `strlen()` cannot return the true length of it. In such case user must provide the length of string explicitly. + +4. Why do I need to provide allocator parameter in many DOM manipulation API? + + Since the APIs are member functions of `Value`, we do not want to save an allocator pointer in every `Value`. + +5. Does it convert between numerical types? + + When using `GetInt()`, `GetUint()`, ... conversion may occur. For integer-to-integer conversion, it only convert when it is safe (otherwise it will assert). However, when converting a 64-bit signed/unsigned integer to double, it will convert but be aware that it may lose precision. A number with fraction, or an integer larger than 64-bit, can only be obtained by `GetDouble()`. + +## Reader/Writer (SAX) + +1. Why don't we just `printf` a JSON? Why do we need a `Writer`? + + Most importantly, `Writer` will ensure the output JSON is well-formed. Calling SAX events incorrectly (e.g. `StartObject()` pairing with `EndArray()`) will assert. Besides, `Writer` will escapes strings (e.g., `\n`). Finally, the numeric output of `printf()` may not be a valid JSON number, especially in some locale with digit delimiters. And the number-to-string conversion in `Writer` is implemented with very fast algorithms, which outperforms than `printf()` or `iostream`. + +2. Can I pause the parsing process and resume it later? + + This is not directly supported in the current version due to performance consideration. However, if the execution environment supports multi-threading, user can parse a JSON in a separate thread, and pause it by blocking in the input stream. + +## Unicode + +1. Does it support UTF-8, UTF-16 and other format? + + Yes. It fully support UTF-8, UTF-16 (LE/BE), UTF-32 (LE/BE) and ASCII. + +2. Can it validate the encoding? + + Yes, just pass `kParseValidateEncodingFlag` to `Parse()`. If there is invalid encoding in the stream, it wil generate `kParseErrorStringInvalidEncoding` error. + +3. What is surrogate pair? Does RapidJSON support it? + + JSON uses UTF-16 encoding when escaping unicode character, e.g. `\u5927` representing Chinese character "big". To handle characters other than those in basic multilingual plane (BMP), UTF-16 encodes those characters with two 16-bit values, which is called UTF-16 surrogate pair. For example, the Emoji character U+1F602 can be encoded as `\uD83D\uDE02` in JSON. + + RapidJSON fully support parsing/generating UTF-16 surrogates. + +4. Can it handle `\u0000` (null character) in JSON string? + + Yes. RapidJSON fully support null character in JSON string. However, user need to be aware of it and using `GetStringLength()` and related APIs to obtain the true length of string. + +5. Can I output `\uxxxx` for all non-ASCII character? + + Yes, use `ASCII<>` as output encoding template parameter in `Writer` can enforce escaping those characters. + +## Stream + +1. I have a big JSON file. Should I load the whole file to memory? + + User can use `FileReadStream` to read the file chunk-by-chunk. But for *in situ* parsing, the whole file must be loaded. + +2. Can I parse JSON while it is streamed from network? + + Yes. User can implement a custom stream for this. Please refer to the implementation of `FileReadStream`. + +3. I don't know what encoding will the JSON be. How to handle them? + + You may use `AutoUTFInputStream` which detects the encoding of input stream automatically. However, it will incur some performance overhead. + +4. What is BOM? How RapidJSON handle it? + + [Byte order mark (BOM)](http://en.wikipedia.org/wiki/Byte_order_mark) sometimes reside at the beginning of file/stream to indiciate the UTF encoding type of it. + + RapidJSON's `EncodedInputStream` can detect/consume BOM. `EncodedOutputStream` can optionally write a BOM. See [Encoded Streams](doc/stream.md) for example. + +5. Why little/big endian is related? + + little/big endian of stream is an issue for UTF-16 and UTF-32 streams, but not UTF-8 stream. + +## Performance + +1. Is RapidJSON really fast? + + Yes. It may be the fastest open source JSON library. There is a [benchmark](https://github.com/miloyip/nativejson-benchmark) for evaluating performance of C/C++ JSON libaries. + +2. Why is it fast? + + Many design decisions of RapidJSON is aimed at time/space performance. These may reduce user-friendliness of APIs. Besides, it also employs low-level optimizations (intrinsics, SIMD) and special algorithms (custom double-to-string, string-to-double conversions). + +3. What is SIMD? How it is applied in RapidJSON? + + [SIMD](http://en.wikipedia.org/wiki/SIMD) instructions can perform parallel computation in modern CPUs. RapidJSON support Intel's SSE2/SSE4.2 to accelerate whitespace skipping. This improves performance of parsing indent formatted JSON. Define `RAPIDJSON_SSE2` or `RAPIDJSON_SSE42` macro to enable this feature. However, running the executable on a machine without such instruction set support will make it crash. + +4. Does it consume a lot of memory? + + The design of RapidJSON aims at reducing memory footprint. + + In the SAX API, `Reader` consumes memory portional to maximum depth of JSON tree, plus maximum length of JSON string. + + In the DOM API, each `Value` consumes exactly 16/24 bytes for 32/64-bit architecture respectively. RapidJSON also uses a special memory allocator to minimize overhead of allocations. + +5. What is the purpose of being high performance? + + Some applications need to process very large JSON files. Some server-side applications need to process huge amount of JSONs. Being high performance can improve both latency and throuput. In a broad sense, it will also save energy. + +## Gossip + +1. Who are the developers of RapidJSON? + + Milo Yip ([miloyip](https://github.com/miloyip)) is the original author of RapidJSON. Many contributors from the world have improved RapidJSON. Philipp A. Hartmann ([pah](https://github.com/pah)) has implemented a lot of improvements, setting up automatic testing and also involves in a lot of discussions for the community. Don Ding ([thebusytypist](https://github.com/thebusytypist)) implemented the iterative parser. Andrii Senkovych ([jollyroger](https://github.com/jollyroger)) completed the CMake migration. Kosta ([Kosta-Github](https://github.com/Kosta-Github)) provided a very neat short-string optimization. Thank you for all other contributors and community members as well. + +2. Why do you develop RapidJSON? + + It was just a hobby project initially in 2011. Milo Yip is a game programmer and he just knew about JSON at that time and would like to apply JSON in future projects. As JSON seems very simple he would like to write a header-only and fast library. + +3. Why there is a long empty period of development? + + It is basically due to personal issues, such as getting new family members. Also, Milo Yip has spent a lot of spare time on translating "Game Engine Architecture" by Jason Gregory into Chinese. + +4. Why did the repository move from Google Code to GitHub? + + This is the trend. And GitHub is much more powerful and convenient.
