You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by je...@apache.org on 2013/04/29 22:12:41 UTC

[1/2] git commit: THRIFT-1742 Optionally implement hashcode and equals in c#

Updated Branches:
  refs/heads/master 9a3a5642b -> 1077ed678


THRIFT-1742 Optionally implement hashcode and equals in c#

Patch: Carl Yeksigian


Project: http://git-wip-us.apache.org/repos/asf/thrift/repo
Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/b706b1a9
Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/b706b1a9
Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/b706b1a9

Branch: refs/heads/master
Commit: b706b1a905ce5eb8b195300c585caf53a8272c11
Parents: 1b4c9b9
Author: Jens Geyer <je...@apache.org>
Authored: Mon Apr 29 22:10:10 2013 +0200
Committer: Jens Geyer <je...@apache.org>
Committed: Mon Apr 29 22:10:10 2013 +0200

----------------------------------------------------------------------
 compiler/cpp/src/generate/t_csharp_generator.cc |  100 ++++++++++++++++++
 lib/csharp/Makefile.am                          |    1 +
 lib/csharp/src/Collections/TCollections.cs      |   94 ++++++++++++++++
 lib/csharp/src/Thrift.WP7.csproj                |    1 +
 lib/csharp/src/Thrift.csproj                    |    5 +-
 5 files changed, 199 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/thrift/blob/b706b1a9/compiler/cpp/src/generate/t_csharp_generator.cc
----------------------------------------------------------------------
diff --git a/compiler/cpp/src/generate/t_csharp_generator.cc b/compiler/cpp/src/generate/t_csharp_generator.cc
index b9e0b75..f0972cf 100644
--- a/compiler/cpp/src/generate/t_csharp_generator.cc
+++ b/compiler/cpp/src/generate/t_csharp_generator.cc
@@ -66,6 +66,9 @@ class t_csharp_generator : public t_oop_generator
       iter = parsed_options.find("nullable");
       nullable_ = (iter != parsed_options.end());
 
+      iter = parsed_options.find("hashcode");
+      hashcode_ = (iter != parsed_options.end());
+
       iter = parsed_options.find("union");
       union_ = (iter != parsed_options.end());
 
@@ -111,6 +114,8 @@ class t_csharp_generator : public t_oop_generator
     void generate_csharp_struct_result_writer(std::ofstream& out, t_struct* tstruct);
     void generate_csharp_struct_writer(std::ofstream& out, t_struct* tstruct);
     void generate_csharp_struct_tostring(std::ofstream& out, t_struct* tstruct);
+    void generate_csharp_struct_equals(std::ofstream& out, t_struct* tstruct);
+    void generate_csharp_struct_hashcode(std::ofstream& out, t_struct* tstruct);
     void generate_csharp_union_reader(std::ofstream& out, t_struct* tunion);
 
     void generate_function_helpers(t_function* tfunction);
@@ -183,6 +188,7 @@ class t_csharp_generator : public t_oop_generator
     bool async_ctp_;
     bool nullable_;
     bool union_;
+    bool hashcode_;
     bool serialize_;
     bool wcf_;
     std::string wcf_namespace_;
@@ -576,6 +582,7 @@ void t_csharp_generator::generate_csharp_struct_definition(ofstream &out, t_stru
   // We always want a default, no argument constructor for Reading
   indent(out) << "public " << tstruct->get_name() << "() {" << endl;
   indent_up();
+
   for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
     t_type* t = (*m_iter)->get_type();
     while (t->is_typedef()) {
@@ -626,6 +633,10 @@ void t_csharp_generator::generate_csharp_struct_definition(ofstream &out, t_stru
   } else {
     generate_csharp_struct_writer(out, tstruct);
   }
+  if (hashcode_) {
+    generate_csharp_struct_equals(out, tstruct);
+    generate_csharp_struct_hashcode(out, tstruct);
+  }
   generate_csharp_struct_tostring(out, tstruct);
   scope_down(out);
   out << endl;
@@ -1034,6 +1045,94 @@ void t_csharp_generator::generate_csharp_union_class(std::ofstream& out, t_struc
   indent(out) << "}" << endl << endl;
 }
 
+
+void t_csharp_generator::generate_csharp_struct_equals(ofstream& out, t_struct* tstruct) {
+  indent(out) << "public override bool Equals(object that) {" << endl;
+  indent_up();
+  
+  indent(out) << "var other = that as " << type_name(tstruct) << ";" << endl;
+  indent(out) << "if (other == null) return false;" << endl;
+  indent(out) << "if (ReferenceEquals(this, other)) return true;" << endl;
+  
+  const vector<t_field*>& fields = tstruct->get_members();
+  vector<t_field*>::const_iterator f_iter;
+  
+  bool first = true;
+  
+  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+    if (first) {
+      first = false;
+      indent(out) << "return ";
+      indent_up();
+    } else {
+      out << endl;
+      indent(out) << "&& ";
+    }
+    if (!field_is_required((*f_iter)) && !(nullable_ && !field_has_default((*f_iter)))) {
+      out << "((__isset." << (*f_iter)->get_name() << " == other.__isset." << (*f_iter)->get_name() << ") && ((!__isset." << (*f_iter)->get_name() << ") || (";
+    }
+    t_type* ttype = (*f_iter)->get_type();
+    if (ttype->is_container()) {
+      out << "TCollections.Equals(" << prop_name((*f_iter)) << ", other." << prop_name((*f_iter)) << ")";
+    } else {
+      out << prop_name((*f_iter)) << ".Equals(other." << prop_name((*f_iter)) << ")";
+    }
+    if (!field_is_required((*f_iter)) && !(nullable_ && !field_has_default((*f_iter)))) {
+      out << ")))";
+    }
+  }
+  if (first) {
+    indent(out) << "return true;" << endl;
+  } else {
+    out << ";" << endl;
+    indent_down();
+  }
+  
+  indent_down();
+  indent(out) << "}" << endl << endl;
+}
+
+void t_csharp_generator::generate_csharp_struct_hashcode(ofstream& out, t_struct* tstruct) {
+  indent(out) << "public override int GetHashCode() {" << endl;
+  indent_up();
+  
+  indent(out) << "int hashcode = 0;" << endl;
+  indent(out) << "unchecked {" << endl;
+  indent_up();
+  
+  const vector<t_field*>& fields = tstruct->get_members();
+  vector<t_field*>::const_iterator f_iter;
+  
+  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+    t_type* ttype = (*f_iter)->get_type();
+    indent(out) << "hashcode = (hashcode * 397) ^ ";
+    if (field_is_required((*f_iter))) {
+    out << "(";
+    } else if ( nullable_) {
+      out << "(" << prop_name((*f_iter)) << " == null ? 0 : ";
+    }else {
+      out << "(!__isset." << (*f_iter)->get_name() << " ? 0 : ";
+    }
+    if (ttype->is_container()) {
+    	out << "(TCollections.GetHashCode("
+    		<< prop_name((*f_iter))
+    		<< "))";
+    } else {
+		out << "("
+			<< prop_name((*f_iter))
+			<< ".GetHashCode())";
+    }
+    out << ");" << endl;
+  }
+  
+  indent_down();
+  indent(out) << "}" << endl;
+  indent(out) << "return hashcode;" << endl;
+  
+  indent_down();
+  indent(out) << "}" << endl << endl;
+}
+
 void t_csharp_generator::generate_service(t_service* tservice) {
   string f_service_name = namespace_dir_ + "/" + service_name_ + ".cs";
   f_service_.open(f_service_name.c_str());
@@ -2394,6 +2493,7 @@ THRIFT_REGISTER_GENERATOR(csharp, "C#",
 "    wcf:             Adds bindings for WCF to generated classes.\n"
 "    serial:          Add serialization support to generated classes.\n"
 "    nullable:        Use nullable types for properties.\n"
+"    hashcode:        Generate a hashcode and equals implementation for classes.\n"
 "    union:           Use new union typing, which includes a static read function for union types.\n"
 )
 

http://git-wip-us.apache.org/repos/asf/thrift/blob/b706b1a9/lib/csharp/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/csharp/Makefile.am b/lib/csharp/Makefile.am
index 9b07f4f..f13f90a 100644
--- a/lib/csharp/Makefile.am
+++ b/lib/csharp/Makefile.am
@@ -19,6 +19,7 @@
 
 THRIFTCODE= \
             src/Collections/THashSet.cs \
+            src/Collections/TCollections.cs \
             src/Properties/AssemblyInfo.cs \
             src/Protocol/TAbstractBase.cs \
             src/Protocol/TBase.cs \

http://git-wip-us.apache.org/repos/asf/thrift/blob/b706b1a9/lib/csharp/src/Collections/TCollections.cs
----------------------------------------------------------------------
diff --git a/lib/csharp/src/Collections/TCollections.cs b/lib/csharp/src/Collections/TCollections.cs
new file mode 100644
index 0000000..23fd8da
--- /dev/null
+++ b/lib/csharp/src/Collections/TCollections.cs
@@ -0,0 +1,94 @@
+/**
+ * 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;
+using System.Collections;
+
+namespace Thrift.Collections
+{
+	public class TCollections
+	{
+		/// <summary>
+		/// This will return true if the two collections are value-wise the same.
+		/// If the collection contains a collection, the collections will be compared using this method.
+		/// </summary>
+		public static bool Equals (IEnumerable first, IEnumerable second)
+		{
+			if (first == null && second == null)
+			{
+				return true;
+			}
+			if (first == null || second == null)
+			{
+				return false;
+			}
+			IEnumerator fiter = first.GetEnumerator ();
+			IEnumerator siter = second.GetEnumerator ();
+
+			bool fnext = fiter.MoveNext ();
+			bool snext = siter.MoveNext ();
+			while (fnext && snext)
+			{
+				IEnumerable fenum = fiter.Current as IEnumerable;
+				IEnumerable senum = siter.Current as IEnumerable;
+				if (fenum != null && senum != null)
+				{
+					if (!Equals(fenum, senum))
+					{
+						return false;
+					}
+				}
+				else if (fenum == null ^ senum == null)
+				{
+					return false;
+				}
+				else if (!Equals(fiter.Current, siter.Current))
+				{
+					return false;
+				}
+				fnext = fiter.MoveNext();
+				snext = siter.MoveNext();
+			}
+
+			return fnext == snext;
+		}
+
+		/// <summary>
+		/// This returns a hashcode based on the value of the enumerable.
+		/// </summary>
+		public static int GetHashCode (IEnumerable enumerable)
+		{
+			if (enumerable == null)
+			{
+				return 0;
+			}
+
+			int hashcode = 0;
+			foreach (Object obj in enumerable)
+			{
+				IEnumerable enum2 = obj as IEnumerable;
+				int objHash = enum2 == null ? obj.GetHashCode () : GetHashCode (enum2);
+				unchecked
+				{
+					hashcode = (hashcode * 397) ^ (objHash);
+				}
+			}
+			return hashcode;
+		}
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/thrift/blob/b706b1a9/lib/csharp/src/Thrift.WP7.csproj
----------------------------------------------------------------------
diff --git a/lib/csharp/src/Thrift.WP7.csproj b/lib/csharp/src/Thrift.WP7.csproj
index be38bc8..3d5b027 100644
--- a/lib/csharp/src/Thrift.WP7.csproj
+++ b/lib/csharp/src/Thrift.WP7.csproj
@@ -70,6 +70,7 @@
     <Reference Include="System.Net" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Collections\TCollections.cs" />
     <Compile Include="Collections\THashSet.cs" />
     <Compile Include="Properties\AssemblyInfo.WP7.cs" />
     <Compile Include="Protocol\TBase.cs" />

http://git-wip-us.apache.org/repos/asf/thrift/blob/b706b1a9/lib/csharp/src/Thrift.csproj
----------------------------------------------------------------------
diff --git a/lib/csharp/src/Thrift.csproj b/lib/csharp/src/Thrift.csproj
index 0263d72..0722c18 100644
--- a/lib/csharp/src/Thrift.csproj
+++ b/lib/csharp/src/Thrift.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?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
@@ -77,6 +77,7 @@
     <Reference Include="System.Web" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Collections\TCollections.cs" />
     <Compile Include="Collections\THashSet.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Protocol\TAbstractBase.cs" />
@@ -137,4 +138,4 @@
   <ProjectExtensions>
     <VisualStudio AllowExistingFolder="true" />
   </ProjectExtensions>
-</Project>
\ No newline at end of file
+</Project>


[2/2] git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/thrift

Posted by je...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/thrift


Project: http://git-wip-us.apache.org/repos/asf/thrift/repo
Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/1077ed67
Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/1077ed67
Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/1077ed67

Branch: refs/heads/master
Commit: 1077ed678d532850c5bff866124934197bbd0979
Parents: b706b1a 9a3a564
Author: Jens Geyer <je...@apache.org>
Authored: Mon Apr 29 22:10:35 2013 +0200
Committer: Jens Geyer <je...@apache.org>
Committed: Mon Apr 29 22:10:35 2013 +0200

----------------------------------------------------------------------
 Makefile.am                  |    2 -
 tutorial/ocaml/CalcClient.ml |   74 ++++++++++++++++++++++++++++++
 tutorial/ocaml/CalcServer.ml |   89 +++++++++++++++++++++++++++++++++++++
 tutorial/ocaml/README        |   15 ++++++
 tutorial/ocaml/_oasis        |   32 +++++++++++++
 5 files changed, 210 insertions(+), 2 deletions(-)
----------------------------------------------------------------------