Thrift: String/Binary distinction for C#.

Reviewed By: mcslee

Test Plan: Built it after a future revision.

Revert Plan: ok

Other Notes:
Submitted by Ben Maurer.
Actually reviewed by Todd Berman.


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665463 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_csharp_generator.cc b/compiler/cpp/src/generate/t_csharp_generator.cc
index 0ec3e66..48df1b0 100644
--- a/compiler/cpp/src/generate/t_csharp_generator.cc
+++ b/compiler/cpp/src/generate/t_csharp_generator.cc
@@ -1085,7 +1085,11 @@
           throw "compiler error: cannot serialize void field in a struct: " + name;
           break;
         case t_base_type::TYPE_STRING:
-          out << "ReadString();";
+          if (((t_base_type*)type)->is_binary()) {
+             out << "ReadBinary();";
+          } else {
+            out << "ReadString();";
+          }
           break;
         case t_base_type::TYPE_BOOL:
           out << "ReadBool();";
@@ -1247,7 +1251,12 @@
           throw "compiler error: cannot serialize void field in a struct: " + name;
           break;
         case t_base_type::TYPE_STRING:
-          out << "WriteString(" << name << ");";
+          if (((t_base_type*)type)->is_binary()) {
+            out << "WriteBinary(";
+          } else {
+            out << "WriteString(";
+          }
+          out << name << ");";
           break;
         case t_base_type::TYPE_BOOL:
           out << "WriteBool(" << name << ");";
@@ -1399,12 +1408,16 @@
   return ttype->get_name();
 }
 
-string t_csharp_generator::base_type_name(t_base_type::t_base tbase, bool in_container) {
-  switch (tbase) {
+string t_csharp_generator::base_type_name(t_base_type* tbase, bool in_container) {
+  switch (tbase->get_base()) {
     case t_base_type::TYPE_VOID:
       return "void";
     case t_base_type::TYPE_STRING:
-      return "string";
+      if (tbase->is_binary()) {
+        return "byte[]";
+      } else {
+        return "string";
+      }
     case t_base_type::TYPE_BOOL:
       return "bool";
     case t_base_type::TYPE_BYTE:
@@ -1418,7 +1431,7 @@
     case t_base_type::TYPE_DOUBLE:
       return "double";
     default:
-      throw "compiler error: no C# name for base type " + tbase;
+      throw "compiler error: no C# name for base type " + tbase->get_base();
   }
 }
 
diff --git a/compiler/cpp/src/generate/t_csharp_generator.h b/compiler/cpp/src/generate/t_csharp_generator.h
index 33d1491..63ec447 100644
--- a/compiler/cpp/src/generate/t_csharp_generator.h
+++ b/compiler/cpp/src/generate/t_csharp_generator.h
@@ -68,7 +68,7 @@
     std::string csharp_thrift_usings();
 
     std::string type_name(t_type* ttype, bool in_countainer=false, bool in_init=false);
-    std::string base_type_name(t_base_type::t_base tbase, bool in_container=false);
+    std::string base_type_name(t_base_type* tbase, bool in_container=false);
     std::string declare_field(t_field* tfield, bool init=false);
     std::string function_signature(t_function* tfunction, std::string prefix="");
     std::string argument_list(t_struct* tstruct);
diff --git a/lib/csharp/src/Protocol/TBinaryProtocol.cs b/lib/csharp/src/Protocol/TBinaryProtocol.cs
index 36f03d0..c2eb81f 100644
--- a/lib/csharp/src/Protocol/TBinaryProtocol.cs
+++ b/lib/csharp/src/Protocol/TBinaryProtocol.cs
@@ -195,9 +195,8 @@
 			WriteI64(BitConverter.DoubleToInt64Bits(d));
 		}
 
-		public override void WriteString(string s)
+		public override void WriteBinary(byte[] b)
 		{
-			byte[] b = Encoding.UTF8.GetBytes(s);
 			WriteI32(b.Length);
 			trans.Write(b, 0, b.Length);
 		}
@@ -361,13 +360,15 @@
 			}
 		}
 
-		public override string ReadString()
+		public override byte[] ReadBinary()
 		{
 			int size = ReadI32();
-			return ReadStringBody(size);
+			CheckReadLength(size);
+			byte[] buf = new byte[size];
+			trans.ReadAll(buf, 0, size);
+			return buf;
 		}
-
-		public string ReadStringBody(int size)
+		private  string ReadStringBody(int size)
 		{
 			CheckReadLength(size);
 			byte[] buf = new byte[size];
diff --git a/lib/csharp/src/Protocol/TProtocol.cs b/lib/csharp/src/Protocol/TProtocol.cs
index f46b6d1..d4b0829 100644
--- a/lib/csharp/src/Protocol/TProtocol.cs
+++ b/lib/csharp/src/Protocol/TProtocol.cs
@@ -50,7 +50,10 @@
 		public abstract void WriteI32(int i32);
 		public abstract void WriteI64(long i64);
 		public abstract void WriteDouble(double d);
-		public abstract void WriteString(string s);
+		public void WriteString(string s) {
+			WriteBinary(Encoding.UTF8.GetBytes(s));
+		}
+		public abstract void WriteBinary(byte[] b);
 
 		public abstract TMessage ReadMessageBegin();
 		public abstract void ReadMessageEnd();
@@ -70,6 +73,9 @@
 		public abstract int ReadI32();
 		public abstract long ReadI64();
 		public abstract double ReadDouble();
-		public abstract string ReadString();
+		public string ReadString() {
+		       return Encoding.UTF8.GetString(ReadBinary());
+		}
+		public abstract byte[] ReadBinary();
 	}
 }
diff --git a/lib/csharp/src/Protocol/TProtocolUtil.cs b/lib/csharp/src/Protocol/TProtocolUtil.cs
index 67f0ce6..ae5a107 100644
--- a/lib/csharp/src/Protocol/TProtocolUtil.cs
+++ b/lib/csharp/src/Protocol/TProtocolUtil.cs
@@ -41,7 +41,8 @@
 					prot.ReadDouble();
 					break;
 				case TType.String:
-					prot.ReadString();
+					// Don't try to decode the string, just skip it.
+					prot.ReadBinary();
 					break;
 				case TType.Struct:
 					prot.ReadStructBegin();