Thrift: OCaml library and generator

Summary: Added (minimal) library and code generator for OCaml.
Reviewed by: mcslee
Test plan: Test client and server (included).
Revert plan: yes


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665163 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/test/ocaml/Makefile b/test/ocaml/Makefile
new file mode 100644
index 0000000..c6ce7c3
--- /dev/null
+++ b/test/ocaml/Makefile
@@ -0,0 +1,5 @@
+all:
+	cd client; make; cd ..; cd server; make
+clean:
+	cd client; make clean; cd ..; cd server; make clean
+
diff --git a/test/ocaml/client/Makefile b/test/ocaml/client/Makefile
new file mode 100644
index 0000000..67757b9
--- /dev/null
+++ b/test/ocaml/client/Makefile
@@ -0,0 +1,7 @@
+SOURCES = ../gen-ocaml/ThriftTest_types.ml ../gen-ocaml/ThriftTest_consts.ml ../gen-ocaml/SecondService.ml ../gen-ocaml/ThriftTest.ml TestClient.ml
+RESULT = tc
+INCDIRS = "/home/iproctor/code/projects/thrift/trunk/lib/ocaml/src/" "../gen-ocaml/"
+LIBS = unix thrift
+all: nc
+OCAMLMAKEFILE = ../../../lib/ocaml/OCamlMakefile
+include $(OCAMLMAKEFILE)
diff --git a/test/ocaml/client/TestClient.ml b/test/ocaml/client/TestClient.ml
new file mode 100644
index 0000000..c60f1fb
--- /dev/null
+++ b/test/ocaml/client/TestClient.ml
@@ -0,0 +1,63 @@
+open Thrift;;
+open ThriftTest_types;;
+
+let s = new TSocket.t "127.0.0.1" 9090;;
+let p = new TBinaryProtocol.t s;;
+let c = new ThriftTest.client p p;;
+let sod = function
+    Some v -> v
+  | None -> raise Thrift_error;;
+
+s#opn;
+print_string (c#testString "bya");
+print_char '\n';
+print_int (c#testByte 8);
+print_char '\n';
+print_int (c#testByte (-8));
+print_char '\n';
+print_int (c#testI32 32);
+print_char '\n';
+print_string (Int64.to_string (c#testI64 64L));
+print_char '\n';
+print_float (c#testDouble 3.14);
+print_char '\n';
+
+let l = [1;2;3;4] in
+  if l = (c#testList l) then print_string "list ok\n" else print_string "list fail\n";;
+let h = Hashtbl.create 5 in
+let a = Hashtbl.add h in
+  for i=1 to 10 do
+    a i (10*i)
+  done;
+  let r = c#testMap h in
+    for i=1 to 10 do
+      try
+        let g = Hashtbl.find r i in
+          print_int i;
+          print_char ' ';
+          print_int g;
+          print_char '\n'
+      with Not_found -> print_string ("Can't find "^(string_of_int i)^"\n")
+    done;;
+
+let s = Hashtbl.create 5 in
+let a = Hashtbl.add s in
+  for i = 1 to 10 do
+    a i true
+  done;
+  let r = c#testSet s in
+    for i = 1 to 10 do
+      try
+        let g = Hashtbl.find r i in
+          print_int i;
+          print_char '\n'
+      with Not_found -> print_string ("Can't find "^(string_of_int i)^"\n")
+    done;;
+try
+  c#testException "Xception"
+with Xception _ -> print_string "testException ok\n";;
+try
+  ignore(c#testMultiException "Xception" "bya")
+with Xception e -> Printf.printf "%d %s\n" (sod e#get_errorCode) (sod e#get_message);;
+
+
diff --git a/test/ocaml/server/Makefile b/test/ocaml/server/Makefile
new file mode 100644
index 0000000..839292d
--- /dev/null
+++ b/test/ocaml/server/Makefile
@@ -0,0 +1,7 @@
+SOURCES = ../gen-ocaml/ThriftTest_types.ml ../gen-ocaml/ThriftTest_consts.ml ../gen-ocaml/SecondService.ml ../gen-ocaml/ThriftTest.ml TestServer.ml
+RESULT = ts
+INCDIRS = "/home/iproctor/code/projects/thrift/trunk/lib/ocaml/src/" "../gen-ocaml/"
+LIBS = unix thrift
+all: nc
+OCAMLMAKEFILE = ../../../lib/ocaml/OCamlMakefile
+include $(OCAMLMAKEFILE)
diff --git a/test/ocaml/server/TestServer.ml b/test/ocaml/server/TestServer.ml
new file mode 100644
index 0000000..3789035
--- /dev/null
+++ b/test/ocaml/server/TestServer.ml
@@ -0,0 +1,107 @@
+open Thrift
+open ThriftTest_types
+
+let p = Printf.printf;;
+exception Die;;
+let sod = function
+    Some v -> v
+  | None -> raise Die;;
+
+
+class test_handler =
+object (self)
+  inherit ThriftTest.iface
+  method testVoid = p "testVoid()\n"
+  method testString x = p "testString(%s)\n" (sod x); (sod x)
+  method testByte x = p "testByte(%d)\n" (sod x); (sod x)
+  method testI32 x = p "testI32(%d)\n" (sod x); (sod x)
+  method testI64 x = p "testI64(%s)\n" (Int64.to_string (sod x)); (sod x)
+  method testDouble x = p "testDouble(%f)\n" (sod x); (sod x)
+  method testStruct x = p "testStruct(---)\n"; (sod x)
+  method testNest x = p "testNest(---)\n"; (sod x)
+  method testMap x = p "testMap(---)\n"; (sod x)
+  method testSet x = p "testSet(---)\n"; (sod x)
+  method testList x = p "testList(---)\n"; (sod x)
+  method testEnum x = p "testEnum(---)\n"; (sod x)
+  method testTypedef x = p "testTypedef(---)\n"; (sod x)
+  method testMapMap x = p "testMapMap(%d)\n" (sod x); 
+    let mm = Hashtbl.create 3 in
+    let pos = Hashtbl.create 7 in
+    let neg = Hashtbl.create 7 in
+      for i=1 to 4 do
+        Hashtbl.add pos i i;
+        Hashtbl.add neg (-i) (-i);
+      done;
+      Hashtbl.add mm 4 pos;
+      Hashtbl.add mm (-4) neg;
+      mm
+  method testInsanity x = p "testInsanity()\n";
+    p "testinsanity()\n";
+    let hello = new xtruct in
+    let goodbye = new xtruct in
+    let crazy = new insanity in
+    let looney = new insanity in
+    let cumap = Hashtbl.create 7 in
+    let insane = Hashtbl.create 7 in
+    let firstmap = Hashtbl.create 7 in
+    let secondmap = Hashtbl.create 7 in
+      hello#set_string_thing "Hello2";
+      hello#set_byte_thing 2;
+      hello#set_i32_thing 2;
+      hello#set_i64_thing 2L;
+      goodbye#set_string_thing "Goodbye4";
+      goodbye#set_byte_thing 4;
+      goodbye#set_i32_thing 4;
+      goodbye#set_i64_thing 4L;
+      Hashtbl.add cumap Numberz.EIGHT 8L;
+      Hashtbl.add cumap Numberz.FIVE 5L;
+      crazy#set_userMap cumap;
+      crazy#set_xtructs [goodbye; hello];
+      Hashtbl.add firstmap Numberz.TWO crazy;
+      Hashtbl.add firstmap Numberz.THREE crazy;
+      Hashtbl.add secondmap Numberz.SIX looney;
+      Hashtbl.add insane 1L firstmap;
+      Hashtbl.add insane 2L secondmap;
+      insane
+  method testMulti a0 a1 a2 a3 a4 a5 = 
+    p "testMulti()\n";
+    let hello = new xtruct in
+      hello#set_string_thing "Hello2";
+      hello#set_byte_thing (sod a0);
+      hello#set_i32_thing (sod a1);
+      hello#set_i64_thing (sod a2);
+      hello
+  method testException s =
+    p "testException(%S)\n" (sod s);
+    if (sod s) = "Xception" then
+      let x = new xception in
+        x#set_errorCode 1001;
+        x#set_message "This is an Xception";
+        raise (Xception x)
+    else ()
+  method testMultiException a0 a1 =
+    p "testMultiException(%S, %S)\n" (sod a0) (sod a1);
+    if (sod a0) = "Xception" then
+      let x = new xception in
+        x#set_errorCode 1001;
+        x#set_message "This is an Xception";
+        raise (Xception x)
+    else (if (sod a0) = "Xception2" then
+              let x = new xception2 in
+              let s = new xtruct in
+                x#set_errorCode 2002;
+                s#set_string_thing "This as an Xception2";
+                x#set_struct_thing s;
+                raise (Xception2 x)
+          else ());
+    let res = new xtruct in
+      res#set_string_thing (sod a1);
+      res
+end;;
+
+let h = new test_handler in
+let proc = new ThriftTest.processor h in
+let port = 9090 in
+  TServer.run_basic_server proc port;;
+                                             
+