Thrift: Add a full-featured JSON protocol for C++.

Summary:
This change adds a new and exciting protocol to Thrift.  It uses
RFC-compliant JSON as the wire protocol and is fully human readable.
(once a little whitespace has been inserted.)  Unlike the existing
JSON protocol for Java, which is intended to allow Thrift data to be
transferred to scripting languages, this protocol is lossless and fully
read-write.  It was written by Chad Walters of Powerset and reviewed
by David Reiss.

Tested by running make check.


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665482 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/test/JSONProtoTest.cpp b/test/JSONProtoTest.cpp
new file mode 100644
index 0000000..077d2c4
--- /dev/null
+++ b/test/JSONProtoTest.cpp
@@ -0,0 +1,119 @@
+#include <iostream>
+#include <cmath>
+#include <transport/TTransportUtils.h>
+#include <protocol/TJSONProtocol.h>
+#include "gen-cpp/DebugProtoTest_types.h"
+
+int main() {
+  using std::cout;
+  using std::endl;
+  using namespace thrift::test;
+  using facebook::thrift::transport::TMemoryBuffer;
+  using facebook::thrift::protocol::TJSONProtocol;
+
+  OneOfEach ooe;
+  ooe.im_true   = true;
+  ooe.im_false  = false;
+  ooe.a_bite    = 0xd6;
+  ooe.integer16 = 27000;
+  ooe.integer32 = 1<<24;
+  ooe.integer64 = (uint64_t)6000 * 1000 * 1000;
+  ooe.double_precision = M_PI;
+  ooe.some_characters  = "JSON THIS! \"\1";
+  ooe.zomg_unicode     = "\xd7\n\a\t";
+  ooe.base64 = "\1\2\3\255";
+  cout << facebook::thrift::ThriftJSONString(ooe) << endl << endl;
+
+
+  Nesting n;
+  n.my_ooe = ooe;
+  n.my_ooe.integer16 = 16;
+  n.my_ooe.integer32 = 32;
+  n.my_ooe.integer64 = 64;
+  n.my_ooe.double_precision = (std::sqrt(5)+1)/2;
+  n.my_ooe.some_characters  = ":R (me going \"rrrr\")";
+  n.my_ooe.zomg_unicode     = "\xd3\x80\xe2\x85\xae\xce\x9d\x20"
+                              "\xd0\x9d\xce\xbf\xe2\x85\xbf\xd0\xbe\xc9\xa1\xd0\xb3\xd0\xb0\xcf\x81\xe2\x84\x8e"
+                              "\x20\xce\x91\x74\x74\xce\xb1\xe2\x85\xbd\xce\xba\xc7\x83\xe2\x80\xbc";
+  n.my_bonk.type    = 31337;
+  n.my_bonk.message = "I am a bonk... xor!";
+
+  cout << facebook::thrift::ThriftJSONString(n) << endl << endl;
+
+
+  HolyMoley hm;
+
+  hm.big.push_back(ooe);
+  hm.big.push_back(n.my_ooe);
+  hm.big[0].a_bite = 0x22;
+  hm.big[1].a_bite = 0x33;
+
+  std::vector<std::string> stage1;
+  stage1.push_back("and a one");
+  stage1.push_back("and a two");
+  hm.contain.insert(stage1);
+  stage1.clear();
+  stage1.push_back("then a one, two");
+  stage1.push_back("three!");
+  stage1.push_back("FOUR!!");
+  hm.contain.insert(stage1);
+  stage1.clear();
+  hm.contain.insert(stage1);
+
+  std::vector<Bonk> stage2;
+  hm.bonks["nothing"] = stage2;
+  stage2.resize(stage2.size()+1);
+  stage2.back().type = 1;
+  stage2.back().message = "Wait.";
+  stage2.resize(stage2.size()+1);
+  stage2.back().type = 2;
+  stage2.back().message = "What?";
+  hm.bonks["something"] = stage2;
+  stage2.clear();
+  stage2.resize(stage2.size()+1);
+  stage2.back().type = 3;
+  stage2.back().message = "quoth";
+  stage2.resize(stage2.size()+1);
+  stage2.back().type = 4;
+  stage2.back().message = "the raven";
+  stage2.resize(stage2.size()+1);
+  stage2.back().type = 5;
+  stage2.back().message = "nevermore";
+  hm.bonks["poe"] = stage2;
+
+  cout << facebook::thrift::ThriftJSONString(hm) << endl << endl;
+
+  boost::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
+  boost::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
+
+
+  cout << "Testing ooe" << endl;
+
+  ooe.write(proto.get());
+  OneOfEach ooe2;
+  ooe2.read(proto.get());
+
+  assert(ooe == ooe2);
+
+
+  cout << "Testing hm" << endl;
+
+  hm.write(proto.get());
+  HolyMoley hm2;
+  hm2.read(proto.get());
+
+  assert(hm == hm2);
+
+  Doubles dub;
+  dub.nan = HUGE_VAL/HUGE_VAL;
+  dub.inf = HUGE_VAL;
+  dub.neginf = -HUGE_VAL;
+  dub.repeating = 10.0/3.0;
+  dub.big = 1E+305;
+  dub.small = 1E-305;
+  dub.zero = 0.0;
+  dub.negzero = -0.0;
+  cout << facebook::thrift::ThriftJSONString(dub) << endl << endl;
+
+  return 0;
+}