You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by ro...@apache.org on 2011/12/08 14:39:57 UTC

svn commit: r1211880 - in /thrift/trunk: compiler/cpp/src/generate/ lib/csharp/src/ lib/csharp/src/Collections/ lib/csharp/src/Properties/ lib/csharp/src/Protocol/ lib/csharp/src/Transport/

Author: roger
Date: Thu Dec  8 13:39:56 2011
New Revision: 1211880

URL: http://svn.apache.org/viewvc?rev=1211880&view=rev
Log:
THRIFT-1037 Proposed changes to support Silverlight, Windows Phone and AsyncCTP v3
Patch: Damian Mehers & Jens Geyer

Added:
    thrift/trunk/lib/csharp/src/Properties/AssemblyInfo.WP7.cs
    thrift/trunk/lib/csharp/src/Thrift.WP7.csproj
Modified:
    thrift/trunk/compiler/cpp/src/generate/t_csharp_generator.cc
    thrift/trunk/lib/csharp/src/Collections/THashSet.cs
    thrift/trunk/lib/csharp/src/Protocol/TBinaryProtocol.cs
    thrift/trunk/lib/csharp/src/Protocol/TJSONProtocol.cs
    thrift/trunk/lib/csharp/src/Protocol/TProtocol.cs
    thrift/trunk/lib/csharp/src/Transport/THttpClient.cs
    thrift/trunk/lib/csharp/src/Transport/TTransport.cs

Modified: thrift/trunk/compiler/cpp/src/generate/t_csharp_generator.cc
URL: http://svn.apache.org/viewvc/thrift/trunk/compiler/cpp/src/generate/t_csharp_generator.cc?rev=1211880&r1=1211879&r2=1211880&view=diff
==============================================================================
--- thrift/trunk/compiler/cpp/src/generate/t_csharp_generator.cc (original)
+++ thrift/trunk/compiler/cpp/src/generate/t_csharp_generator.cc Thu Dec  8 13:39:56 2011
@@ -44,8 +44,12 @@ class t_csharp_generator : public t_oop_
         const std::string& option_string)
       : t_oop_generator(program)
     {
-      (void) parsed_options;
       (void) option_string;
+
+      std::map<std::string, std::string>::const_iterator iter;
+      iter = parsed_options.find("async");
+      async_ctp_ = (iter != parsed_options.end());
+
       out_dir_base_ = "gen-csharp";
     }
     void init_generator();
@@ -101,6 +105,9 @@ class t_csharp_generator : public t_oop_
     std::string type_name(t_type* ttype, bool in_countainer=false, bool in_init=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 prefix="");
+    std::string function_signature_async_begin(t_function* tfunction, std::string prefix = "");
+    std::string function_signature_async_end(t_function* tfunction, std::string prefix = "");
+    std::string function_signature_async_ctp(t_function* tfunction, std::string prefix = "");
     std::string function_signature(t_function* tfunction, std::string prefix="");
     std::string argument_list(t_struct* tstruct);
     std::string type_to_enum(t_type* ttype);
@@ -121,6 +128,7 @@ class t_csharp_generator : public t_oop_
     std::string namespace_name_;
     std::ofstream f_service_;
     std::string namespace_dir_;
+	bool async_ctp_;
 };
 
 
@@ -166,6 +174,7 @@ string t_csharp_generator::csharp_type_u
     "using System.Collections.Generic;\n" +
     "using System.Text;\n" +
     "using System.IO;\n" +
+	(async_ctp_ ? "using System.Threading.Tasks;\n" : "") +
     "using Thrift;\n" +
     "using Thrift.Collections;\n";
 }
@@ -408,7 +417,9 @@ void t_csharp_generator::generate_csharp
   }
 
   out << endl;
-  indent(out) << "[Serializable]" << endl;
+  indent(out) << "#if !SILVERLIGHT" << endl;
+  indent(out) << "[Serializable]" << endl; 
+  indent(out) << "#endif" << endl;
   bool is_final = (tstruct->annotations_.find("final") != tstruct->annotations_.end());
  
   indent(out) << "public " << (is_final ? "sealed " : "") << "partial class " << tstruct->get_name() << " : ";
@@ -440,7 +451,9 @@ void t_csharp_generator::generate_csharp
     out <<
       endl <<
       indent() << "public Isset __isset;" << endl <<
+      indent() << "#if !SILVERLIGHT" << endl <<
       indent() << "[Serializable]" << endl <<
+      indent() << "#endif" << endl <<
       indent() << "public struct Isset {" << endl;
     indent_up();
     for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
@@ -778,6 +791,15 @@ void t_csharp_generator::generate_servic
   {
     indent(f_service_) <<
       function_signature(*f_iter) << ";" << endl;
+    indent(f_service_) << "#if SILVERLIGHT" << endl;
+    indent(f_service_) <<
+      function_signature_async_begin(*f_iter, "Begin_") << ";" << endl;
+    indent(f_service_) <<
+      function_signature_async_end(*f_iter, "End_") << ";" << endl;  
+    if( async_ctp_)
+      indent(f_service_) <<
+        function_signature_async_ctp(*f_iter) << ";" << endl;  
+    indent(f_service_) << "#endif" << endl;
   }
   indent_down();
   f_service_ <<
@@ -852,17 +874,104 @@ void t_csharp_generator::generate_servic
   for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
     string funname = (*f_iter)->get_name();
 
+    indent(f_service_) << endl;
+    indent(f_service_) << "#if SILVERLIGHT" << endl;
+	// Begin_
     indent(f_service_) <<
-      "public " << function_signature(*f_iter) << endl;
+      "public " << function_signature_async_begin(*f_iter, "Begin_") << endl;
     scope_up(f_service_);
     indent(f_service_) <<
-      "send_" << funname << "(";
+      "return " << "send_" << funname << "(callback, state";
 
     t_struct* arg_struct = (*f_iter)->get_arglist();
 
     const vector<t_field*>& fields = arg_struct->get_members();
     vector<t_field*>::const_iterator fld_iter;
-    bool first = true;
+    for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
+	    f_service_ << ", ";
+        f_service_ << (*fld_iter)->get_name();
+    }
+    f_service_ << ");" << endl;
+    scope_down(f_service_);
+    f_service_ << endl;
+	
+    // End
+    indent(f_service_) <<
+      "public " << function_signature_async_end(*f_iter, "End_") << endl;
+    scope_up(f_service_);
+    indent(f_service_) <<
+      "oprot_.Transport.EndFlush(asyncResult);" << endl;
+    if (!(*f_iter)->is_oneway()) {
+      f_service_ << indent();
+      if (!(*f_iter)->get_returntype()->is_void()) {
+        f_service_ << "return ";
+      }
+      f_service_ <<
+        "recv_" << funname << "();" << endl;
+    }
+    scope_down(f_service_);
+    f_service_ << endl;
+
+    // async CTP
+	bool first;
+    if( async_ctp_)
+	{
+      indent(f_service_) <<
+        "public async " << function_signature_async_ctp(*f_iter, "") << endl;
+      scope_up(f_service_);
+	
+      if (!(*f_iter)->get_returntype()->is_void()) {
+        indent(f_service_) <<
+          type_name( (*f_iter)->get_returntype()) << " retval;" << endl;
+        indent(f_service_) <<
+          "retval = ";
+      }
+	  else
+	  {
+        indent(f_service_);
+	  }
+      f_service_ <<
+        "await TaskEx.Run(() =>" << endl;
+      scope_up(f_service_);
+      indent(f_service_);
+      if (!(*f_iter)->get_returntype()->is_void()) {
+        f_service_ <<
+          "return ";
+      }
+      f_service_ << 
+        funname << "(";
+	  first = true;
+      for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
+        if (first) {
+          first = false;
+        } else {
+          f_service_ << ", ";
+        }
+        f_service_ << (*fld_iter)->get_name();
+      }
+      f_service_ << ");" << endl;
+      indent_down();
+      indent(f_service_) << 
+        "});" << endl;
+      if (!(*f_iter)->get_returntype()->is_void()) {
+        indent(f_service_) << 
+          "return retval;"  << endl;
+      }
+	  scope_down(f_service_);
+      f_service_ << endl;
+    }
+	
+    indent(f_service_) << "#endif" << endl << endl;
+
+    // "Normal" Synchronous invoke
+    indent(f_service_) <<
+      "public " << function_signature(*f_iter) << endl;
+    scope_up(f_service_);
+    indent(f_service_) << "#if !SILVERLIGHT" << endl;
+    indent(f_service_) <<
+      "send_" << funname << "(";
+
+    first = true;
     for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
       if (first) {
         first = false;
@@ -881,17 +990,49 @@ void t_csharp_generator::generate_servic
       f_service_ <<
         "recv_" << funname << "();" << endl;
     }
-    scope_down(f_service_);
     f_service_ << endl;
 
+    indent(f_service_) << "#else" << endl;
+
+    // Silverlight synchronous invoke
+    indent(f_service_) << "var asyncResult = Begin_" << funname << "(null, null, ";
+    first = true;
+    for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
+      if (first) {
+        first = false;
+      } else {
+        f_service_ << ", ";
+      }
+      f_service_ << (*fld_iter)->get_name();
+    }
+    f_service_ << ");" << endl;
+
+    if (!(*f_iter)->is_oneway()) {
+      f_service_ << indent();
+      if (!(*f_iter)->get_returntype()->is_void()) {
+        f_service_ << "return ";
+      }
+      f_service_ <<
+        "End_" << funname << "(asyncResult);" << endl;
+    }
+    f_service_ << endl;
+
+
+    indent(f_service_) << "#endif" << endl;
+    scope_down(f_service_);
+
+    // Send
     t_function send_function(g_type_void,
         string("send_") + (*f_iter)->get_name(),
         (*f_iter)->get_arglist());
 
     string argsname = (*f_iter)->get_name() + "_args";
 
-    indent(f_service_) <<
-      "public " << function_signature(&send_function) << endl;
+    indent(f_service_) << "#if SILVERLIGHT" << endl;
+    indent(f_service_) << "public " << function_signature_async_begin(&send_function) << endl;
+    indent(f_service_) << "#else" << endl;
+    indent(f_service_) << "public " << function_signature(&send_function) << endl;
+    indent(f_service_) << "#endif" << endl;
     scope_up(f_service_);
 
     f_service_ <<
@@ -905,8 +1046,13 @@ void t_csharp_generator::generate_servic
 
     f_service_ <<
       indent() << "args.Write(oprot_);" << endl <<
-      indent() << "oprot_.WriteMessageEnd();" << endl <<
-      indent() << "oprot_.Transport.Flush();" << endl;
+      indent() << "oprot_.WriteMessageEnd();" << endl;;
+
+    indent(f_service_) << "#if SILVERLIGHT" << endl;
+    indent(f_service_) << "return oprot_.Transport.BeginFlush(callback, state);" << endl;
+    indent(f_service_) << "#else" << endl;
+    indent(f_service_) << "oprot_.Transport.Flush();" << endl;
+    indent(f_service_) << "#endif" << endl;
 
     scope_down(f_service_);
     f_service_ << endl;
@@ -1650,6 +1796,24 @@ string t_csharp_generator::function_sign
   return type_name(ttype) + " " + prefix + tfunction->get_name() + "(" + argument_list(tfunction->get_arglist()) + ")";
 }
 
+string t_csharp_generator::function_signature_async_begin(t_function* tfunction, string prefix) {
+  return "IAsyncResult " + prefix + tfunction->get_name() + "(AsyncCallback callback, object state, " + argument_list(tfunction->get_arglist()) + ")";
+}
+
+string t_csharp_generator::function_signature_async_end(t_function* tfunction, string prefix) {
+  t_type* ttype = tfunction->get_returntype();
+  return type_name(ttype) + " " + prefix + tfunction->get_name() + "(IAsyncResult asyncResult)";
+}
+
+string t_csharp_generator::function_signature_async_ctp(t_function* tfunction, string prefix) {
+  t_type* ttype = tfunction->get_returntype();
+  string task = "Task";
+  if( ! ttype->is_void())
+    task += "<" + type_name(ttype) + ">";
+  return task + " " + prefix + tfunction->get_name() + "Async(" + argument_list(tfunction->get_arglist()) + ")";
+}
+
+
 string t_csharp_generator::argument_list(t_struct* tstruct) {
   string result = "";
   const vector<t_field*>& fields = tstruct->get_members();
@@ -1707,5 +1871,6 @@ string t_csharp_generator::type_to_enum(
 }
 
 
-THRIFT_REGISTER_GENERATOR(csharp, "C#", "")
+THRIFT_REGISTER_GENERATOR(csharp, "C#",
+"    async:  add AsyncCTP support.\n")
 

Modified: thrift/trunk/lib/csharp/src/Collections/THashSet.cs
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/csharp/src/Collections/THashSet.cs?rev=1211880&r1=1211879&r2=1211880&view=diff
==============================================================================
--- thrift/trunk/lib/csharp/src/Collections/THashSet.cs (original)
+++ thrift/trunk/lib/csharp/src/Collections/THashSet.cs Thu Dec  8 13:39:56 2011
@@ -23,11 +23,13 @@ using System.Collections.Generic;
 
 namespace Thrift.Collections
 {
+#if !SILVERLIGHT
      [Serializable]
+#endif
 	public class THashSet<T> : ICollection<T>
 	{
-#if NET_2_0
-		TDictSet<T> set = new TDictSet<T>();
+#if NET_2_0 || SILVERLIGHT
+        TDictSet<T> set = new TDictSet<T>();
 #else
 		HashSet<T> set = new HashSet<T>();
 #endif
@@ -76,8 +78,8 @@ namespace Thrift.Collections
 			return set.Remove(item);
 		}
 
-#if NET_2_0
-		private class TDictSet<V> : ICollection<V>
+#if NET_2_0 || SILVERLIGHT
+        private class TDictSet<V> : ICollection<V>
 		{
 			Dictionary<V, TDictSet<V>> dict = new Dictionary<V, TDictSet<V>>();
 

Added: thrift/trunk/lib/csharp/src/Properties/AssemblyInfo.WP7.cs
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/csharp/src/Properties/AssemblyInfo.WP7.cs?rev=1211880&view=auto
==============================================================================
--- thrift/trunk/lib/csharp/src/Properties/AssemblyInfo.WP7.cs (added)
+++ thrift/trunk/lib/csharp/src/Properties/AssemblyInfo.WP7.cs Thu Dec  8 13:39:56 2011
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Thrift.WP7")]
+[assembly: AssemblyDescription("C# bindings for the Apache Thrift RPC system")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+//@TODO where to put License information?
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("a343f89c-57dd-4fa8-a9c6-35391cd5f655")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("0.9.0.0")]
+[assembly: AssemblyFileVersion("0.9.0.0")]

Modified: thrift/trunk/lib/csharp/src/Protocol/TBinaryProtocol.cs
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/csharp/src/Protocol/TBinaryProtocol.cs?rev=1211880&r1=1211879&r2=1211880&view=diff
==============================================================================
--- thrift/trunk/lib/csharp/src/Protocol/TBinaryProtocol.cs (original)
+++ thrift/trunk/lib/csharp/src/Protocol/TBinaryProtocol.cs Thu Dec  8 13:39:56 2011
@@ -201,7 +201,12 @@ namespace Thrift.Protocol
 
 		public override void WriteDouble(double d)
 		{
+#if !SILVERLIGHT
 			WriteI64(BitConverter.DoubleToInt64Bits(d));
+#else
+            var bytes = BitConverter.GetBytes(d);
+            WriteI64(BitConverter.ToInt64(bytes, 0));
+#endif
 		}
 
 		public override void WriteBinary(byte[] b)
@@ -348,7 +353,13 @@ namespace Thrift.Protocol
 
 		public override double ReadDouble()
 		{
+#if !SILVERLIGHT
 			return BitConverter.Int64BitsToDouble(ReadI64());
+#else
+            var value = ReadI64();
+            var bytes = BitConverter.GetBytes(value);
+            return BitConverter.ToDouble(bytes, 0);
+#endif
 		}
 
 		public void SetReadLength(int readLength)
@@ -382,7 +393,7 @@ namespace Thrift.Protocol
 			CheckReadLength(size);
 			byte[] buf = new byte[size];
 			trans.ReadAll(buf, 0, size);
-			return Encoding.UTF8.GetString(buf);
+			return Encoding.UTF8.GetString(buf, 0, buf.Length);
 		}
 
 		private int ReadAll(byte[] buf, int off, int len)

Modified: thrift/trunk/lib/csharp/src/Protocol/TJSONProtocol.cs
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/csharp/src/Protocol/TJSONProtocol.cs?rev=1211880&r1=1211879&r2=1211880&view=diff
==============================================================================
--- thrift/trunk/lib/csharp/src/Protocol/TJSONProtocol.cs (original)
+++ thrift/trunk/lib/csharp/src/Protocol/TJSONProtocol.cs Thu Dec  8 13:39:56 2011
@@ -841,7 +841,7 @@ namespace Thrift.Protocol
 			if (reader.Peek() == QUOTE[0])
 			{
 				byte[] arr = ReadJSONString(true);
-				double dub = Double.Parse(utf8Encoding.GetString(arr), CultureInfo.InvariantCulture);
+				double dub = Double.Parse(utf8Encoding.GetString(arr,0,arr.Length), CultureInfo.InvariantCulture);
 
 				if (!context.EscapeNumbers() && !Double.IsNaN(dub) &&
 					!Double.IsInfinity(dub))
@@ -938,7 +938,8 @@ namespace Thrift.Protocol
 											 "Message contained bad version.");
 			}
 
-			message.Name = utf8Encoding.GetString(ReadJSONString(false));
+            var buf = ReadJSONString(false);
+			message.Name = utf8Encoding.GetString(buf,0,buf.Length);
 			message.Type = (TMessageType)ReadJSONInteger();
 			message.SeqID = (int)ReadJSONInteger();
 			return message;
@@ -1059,7 +1060,8 @@ namespace Thrift.Protocol
 
 		public override String ReadString()
 		{
-			return utf8Encoding.GetString(ReadJSONString(false));
+            var buf = ReadJSONString(false);
+			return utf8Encoding.GetString(buf,0,buf.Length);
 		}
 
 		public override byte[] ReadBinary()

Modified: thrift/trunk/lib/csharp/src/Protocol/TProtocol.cs
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/csharp/src/Protocol/TProtocol.cs?rev=1211880&r1=1211879&r2=1211880&view=diff
==============================================================================
--- thrift/trunk/lib/csharp/src/Protocol/TProtocol.cs (original)
+++ thrift/trunk/lib/csharp/src/Protocol/TProtocol.cs Thu Dec  8 13:39:56 2011
@@ -84,8 +84,9 @@ namespace Thrift.Protocol
 		public abstract long ReadI64();
 		public abstract double ReadDouble();
 		public virtual string ReadString() {
-		       return Encoding.UTF8.GetString(ReadBinary());
-		}
+            var buf = ReadBinary();
+            return Encoding.UTF8.GetString(buf, 0, buf.Length);
+        }
 		public abstract byte[] ReadBinary();
 	}
 }

Added: thrift/trunk/lib/csharp/src/Thrift.WP7.csproj
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/csharp/src/Thrift.WP7.csproj?rev=1211880&view=auto
==============================================================================
--- thrift/trunk/lib/csharp/src/Thrift.WP7.csproj (added)
+++ thrift/trunk/lib/csharp/src/Thrift.WP7.csproj Thu Dec  8 13:39:56 2011
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>10.0.20506</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{DF58BDB0-2457-4A52-9981-65A0E8B50833}</ProjectGuid>
+    <ProjectTypeGuids>{C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Thrift.WP7</RootNamespace>
+    <AssemblyName>Thrift.WP7</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
+    <TargetFrameworkProfile>WindowsPhone</TargetFrameworkProfile>
+    <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
+    <SilverlightApplication>false</SilverlightApplication>
+    <ValidateXaml>true</ValidateXaml>
+    <ThrowErrorsInValidation>true</ThrowErrorsInValidation>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>Bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>Bin\Release</OutputPath>
+    <DefineConstants>TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Phone" />
+    <Reference Include="Microsoft.Phone.Interop" />
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.Servicemodel.Web" />
+    <Reference Include="System.Windows" />
+    <Reference Include="system" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Net" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Collections\THashSet.cs" />
+    <Compile Include="Properties\AssemblyInfo.WP7.cs" />
+    <Compile Include="Protocol\TBase.cs" />
+    <Compile Include="Protocol\TBase64Utils.cs" />
+    <Compile Include="Protocol\TBinaryProtocol.cs" />
+    <Compile Include="Protocol\TField.cs" />
+    <Compile Include="Protocol\TJSONProtocol.cs" />
+    <Compile Include="Protocol\TList.cs" />
+    <Compile Include="Protocol\TMap.cs" />
+    <Compile Include="Protocol\TMessage.cs" />
+    <Compile Include="Protocol\TMessageType.cs" />
+    <Compile Include="Protocol\TProtocol.cs" />
+    <Compile Include="Protocol\TProtocolException.cs" />
+    <Compile Include="Protocol\TProtocolFactory.cs" />
+    <Compile Include="Protocol\TProtocolUtil.cs" />
+    <Compile Include="Protocol\TSet.cs" />
+    <Compile Include="Protocol\TStruct.cs" />
+    <Compile Include="Protocol\TType.cs" />
+    <Compile Include="TApplicationException.cs" />
+    <Compile Include="TProcessor.cs" />
+    <Compile Include="Transport\TFramedTransport.cs" />
+    <Compile Include="Transport\THttpClient.cs" />
+    <Compile Include="Transport\TStreamTransport.cs" />
+    <Compile Include="Transport\TTransport.cs" />
+    <Compile Include="Transport\TTransportException.cs" />
+    <Compile Include="Transport\TTransportFactory.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
+  <ProjectExtensions />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file

Modified: thrift/trunk/lib/csharp/src/Transport/THttpClient.cs
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/csharp/src/Transport/THttpClient.cs?rev=1211880&r1=1211879&r2=1211880&view=diff
==============================================================================
--- thrift/trunk/lib/csharp/src/Transport/THttpClient.cs (original)
+++ thrift/trunk/lib/csharp/src/Transport/THttpClient.cs Thu Dec  8 13:39:56 2011
@@ -23,6 +23,7 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Net;
+using System.Threading;
 
 namespace Thrift.Transport
 {
@@ -119,6 +120,7 @@ namespace Thrift.Transport
 			outputStream.Write(buf, off, len);
 		}
 
+#if !SILVERLIGHT
 		public override void Flush()
 		{
 			try 
@@ -153,11 +155,12 @@ namespace Thrift.Transport
 				throw new TTransportException(TTransportException.ExceptionType.Unknown, "Couldn't connect to server: " + wx);
 			}
 		}
-
-		private HttpWebRequest CreateRequest()
+#endif
+        private HttpWebRequest CreateRequest()
 		{
 			HttpWebRequest connection = (HttpWebRequest)WebRequest.Create(uri);
 
+#if !SILVERLIGHT
 			if (connectTimeout > 0)
 			{
 				connection.Timeout = connectTimeout;
@@ -166,23 +169,190 @@ namespace Thrift.Transport
 			{
 				connection.ReadWriteTimeout = readTimeout;
 			}
-
+#endif
 			// Make the request
 			connection.ContentType = "application/x-thrift";
 			connection.Accept = "application/x-thrift";
 			connection.UserAgent = "C#/THttpClient";
 			connection.Method = "POST";
+#if !SILVERLIGHT
 			connection.ProtocolVersion = HttpVersion.Version10;
+#endif
 
-			//add custom headers here
+            //add custom headers here
 			foreach (KeyValuePair<string, string> item in customHeaders)
 			{
+#if !SILVERLIGHT
 				connection.Headers.Add(item.Key, item.Value);
+#else
+                connection.Headers[item.Key] = item.Value;
+#endif
 			}
 
 			connection.Proxy = null;
 
-			return connection;
+            return connection;
 		}
-	}
+
+#if SILVERLIGHT
+        public override IAsyncResult BeginFlush(AsyncCallback callback, object state)
+        {
+            // Extract request and reset buffer
+            var data = outputStream.ToArray();
+
+            //requestBuffer_ = new MemoryStream();
+
+            try
+            {
+                // Create connection object
+                var flushAsyncResult = new FlushAsyncResult(callback, state);
+                flushAsyncResult.Connection = CreateRequest();
+
+                flushAsyncResult.Data = data;
+
+
+                flushAsyncResult.Connection.BeginGetRequestStream(GetRequestStreamCallback, flushAsyncResult);
+                return flushAsyncResult;
+
+            }
+            catch (IOException iox)
+            {
+                throw new TTransportException(iox.ToString());
+            }
+        }
+
+        public override void EndFlush(IAsyncResult asyncResult)
+        {
+            try
+            {
+                var flushAsyncResult = (FlushAsyncResult) asyncResult;
+
+                if (!flushAsyncResult.IsCompleted)
+                {
+                    var waitHandle = flushAsyncResult.AsyncWaitHandle;
+                    waitHandle.WaitOne();  // blocking INFINITEly
+                    waitHandle.Close();
+                }
+
+                if (flushAsyncResult.AsyncException != null)
+                {
+                    throw flushAsyncResult.AsyncException;
+                }
+            } finally
+            {
+                outputStream = new MemoryStream();
+            }
+
+        }
+
+
+        private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
+        {
+            var flushAsyncResult = (FlushAsyncResult)asynchronousResult.AsyncState;
+            try
+            {
+                var reqStream = flushAsyncResult.Connection.EndGetRequestStream(asynchronousResult);
+                reqStream.Write(flushAsyncResult.Data, 0, flushAsyncResult.Data.Length);
+                reqStream.Flush();
+                reqStream.Close();
+
+                // Start the asynchronous operation to get the response
+                flushAsyncResult.Connection.BeginGetResponse(GetResponseCallback, flushAsyncResult);
+            }
+            catch (Exception exception)
+            {
+                flushAsyncResult.AsyncException = new TTransportException(exception.ToString());
+                flushAsyncResult.UpdateStatusToComplete();
+                flushAsyncResult.NotifyCallbackWhenAvailable();
+            }
+        }
+
+        private void GetResponseCallback(IAsyncResult asynchronousResult)
+        {
+            var flushAsyncResult = (FlushAsyncResult)asynchronousResult.AsyncState;
+            try
+            {
+                inputStream = flushAsyncResult.Connection.EndGetResponse(asynchronousResult).GetResponseStream();
+            }
+            catch (Exception exception)
+            {
+                flushAsyncResult.AsyncException = new TTransportException(exception.ToString());
+            }
+            flushAsyncResult.UpdateStatusToComplete();
+            flushAsyncResult.NotifyCallbackWhenAvailable();
+        }
+
+        // Based on http://msmvps.com/blogs/luisabreu/archive/2009/06/15/multithreading-implementing-the-iasyncresult-interface.aspx
+        class FlushAsyncResult : IAsyncResult
+        {
+            private volatile Boolean _isCompleted;
+            private ManualResetEvent _evt;
+            private readonly AsyncCallback _cbMethod;
+            private readonly Object _state;
+
+            public FlushAsyncResult(AsyncCallback cbMethod, Object state)
+            {
+                _cbMethod = cbMethod;
+                _state = state;
+            }
+
+            internal byte[] Data { get; set; }
+            internal HttpWebRequest Connection { get; set; }
+            internal TTransportException AsyncException { get; set; }
+
+            public object AsyncState
+            {
+                get { return _state; }
+            }
+            public WaitHandle AsyncWaitHandle
+            {
+                get { return GetEvtHandle(); }
+            }
+            public bool CompletedSynchronously
+            {
+                get { return false; }
+            }
+            public bool IsCompleted
+            {
+                get { return _isCompleted; }
+            }
+            private readonly Object _locker = new Object();
+            private ManualResetEvent GetEvtHandle()
+            {
+                lock (_locker)
+                {
+                    if (_evt == null)
+                    {
+                        _evt = new ManualResetEvent(false);
+                    }
+                    if (_isCompleted)
+                    {
+                        _evt.Set();
+                    }
+                }
+                return _evt;
+            }
+            internal void UpdateStatusToComplete()
+            {
+                _isCompleted = true; //1. set _iscompleted to true 
+                lock (_locker)
+                {
+                    if (_evt != null)
+                    {
+                        _evt.Set(); //2. set the event, when it exists 
+                    }
+                }
+            }
+
+            internal void NotifyCallbackWhenAvailable()
+            {
+                if (_cbMethod != null)
+                {
+                    _cbMethod(this);
+                }
+            }
+        }
+
+#endif
+    }
 }

Modified: thrift/trunk/lib/csharp/src/Transport/TTransport.cs
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/csharp/src/Transport/TTransport.cs?rev=1211880&r1=1211879&r2=1211880&view=diff
==============================================================================
--- thrift/trunk/lib/csharp/src/Transport/TTransport.cs (original)
+++ thrift/trunk/lib/csharp/src/Transport/TTransport.cs Thu Dec  8 13:39:56 2011
@@ -71,5 +71,14 @@ namespace Thrift.Transport
 		public virtual void Flush()
 		{
 		}
-	}
+        
+        public virtual IAsyncResult BeginFlush(AsyncCallback callback, object state)
+        {
+            return null;
+        }
+
+        public virtual void EndFlush(IAsyncResult asyncResult)
+        {
+        }
+    }
 }