PageRenderTime 59ms CodeModel.GetById 36ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/otp.net/Otp/Erlang/Tuple.cs

https://github.com/gebi/jungerl
C# | 333 lines | 180 code | 31 blank | 122 comment | 47 complexity | b0ab9edcd3f03612c3395b8e9176f5f1 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, AGPL-1.0
  1. /*``The contents of this file are subject to the Erlang Public License,
  2. * Version 1.1, (the "License"); you may not use this file except in
  3. * compliance with the License. You should have received a copy of the
  4. * Erlang Public License along with this software. If not, it can be
  5. * retrieved via the world wide web at http://www.erlang.org/.
  6. *
  7. * Software distributed under the License is distributed on an "AS IS"
  8. * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  9. * the License for the specific language governing rights and limitations
  10. * under the License.
  11. *
  12. * The Initial Developer of the Original Code is Ericsson Utvecklings AB.
  13. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
  14. * AB. All Rights Reserved.''
  15. *
  16. * Converted from Java to C# by Vlad Dumitrescu (vlad_Dumitrescu@hotmail.com)
  17. * Contribution: Serge Aleynikov (added pattern matching)
  18. */
  19. namespace Otp.Erlang
  20. {
  21. using System;
  22. /*
  23. * Provides a C# representation of Erlang tuples. Tuples are created
  24. * from one or more arbitrary Erlang terms.
  25. *
  26. * <p> The arity of the tuple is the number of elements it contains.
  27. * Elements are indexed from 0 to (arity-1) and can be retrieved
  28. * individually by using the appropriate index.
  29. **/
  30. [Serializable]
  31. public class Tuple:Erlang.Object
  32. {
  33. private Object[] elems = null;
  34. /*
  35. * Create a unary tuple containing the given element.
  36. *
  37. * @param elem the element to create the tuple from.
  38. *
  39. * @exception C#.lang.IllegalArgumentException if the array is
  40. * empty (null).
  41. *
  42. public Tuple(Object elem)
  43. {
  44. if (elem == null)
  45. {
  46. throw new System.ArgumentException("Tuple element cannot be null");
  47. }
  48. this.elems = new Object[1];
  49. elems[0] = elem;
  50. }
  51. */
  52. /*
  53. * Create a tuple from an array of terms.
  54. *
  55. * @param elems the array of terms to create the tuple from.
  56. *
  57. * @exception C#.lang.IllegalArgumentException if the array is
  58. * empty (null) or contains null elements.
  59. */
  60. public Tuple(Object[] elems):this(elems, 0, elems.Length)
  61. {
  62. }
  63. /*
  64. * Create a tuple from an array of terms.
  65. *
  66. * @param elems the array of terms to create the tuple from.
  67. * @param start the offset of the first term to insert.
  68. * @param count the number of terms to insert.
  69. *
  70. * @exception C#.lang.IllegalArgumentException if the array is
  71. * empty (null) or contains null elements.
  72. */
  73. public Tuple(Object[] elems, int start, int count)
  74. {
  75. if ((elems == null) || (count < 1))
  76. {
  77. throw new System.ArgumentException("Cannot make an empty tuple");
  78. }
  79. else
  80. {
  81. this.elems = new Object[count];
  82. for (int i = 0; i < count; i++)
  83. {
  84. if (elems[start + i] != null)
  85. {
  86. this.elems[i] = elems[start + i];
  87. }
  88. else
  89. {
  90. throw new System.ArgumentException("Tuple element cannot be null (element" + (start + i) + ")");
  91. }
  92. }
  93. }
  94. }
  95. /*
  96. * Create a tuple from an array of terms.
  97. *
  98. * @param elems the array of terms to create the tuple from.
  99. * @param start the offset of the first term to insert.
  100. * @param count the number of terms to insert.
  101. *
  102. * @exception C#.lang.IllegalArgumentException if the array is
  103. * empty (null) or contains null elements.
  104. **/
  105. public Tuple(params System.Object[] elems)
  106. {
  107. if (elems == null)
  108. elems = new Object[] {};
  109. else
  110. {
  111. this.elems = new Object[elems.Length];
  112. for (int i = 0; i < elems.Length; i++)
  113. {
  114. if (elems[i] == null)
  115. throw new System.ArgumentException("Tuple element cannot be null (element" + i + ")");
  116. else
  117. {
  118. System.Object o = elems[i];
  119. if (o is int) this.elems[i] = new Int((int)o);
  120. else if (o is string) this.elems[i] = new String((string)o);
  121. else if (o is float) this.elems[i] = new Double((float)o);
  122. else if (o is double) this.elems[i] = new Double((double)o);
  123. else if (o is Erlang.Object) this.elems[i] = (Erlang.Object)o;
  124. //else if (o is BigInteger) this.elems[i] = (BigInteger)o;
  125. else if (o is uint) this.elems[i] = new UInt((int)o);
  126. else if (o is short) this.elems[i] = new Short((short)o);
  127. else if (o is ushort) this.elems[i] = new UShort((short)o);
  128. else
  129. throw new System.ArgumentException("Unknown type of element[" + i + "]: " + o.GetType().ToString());
  130. }
  131. }
  132. }
  133. }
  134. /*
  135. * Create a tuple from a stream containing an tuple encoded in Erlang
  136. * external format.
  137. *
  138. * @param buf the stream containing the encoded tuple.
  139. *
  140. * @exception DecodeException if the buffer does not
  141. * contain a valid external representation of an Erlang tuple.
  142. **/
  143. public Tuple(OtpInputStream buf)
  144. {
  145. int arity = buf.read_tuple_head();
  146. if (arity > 0)
  147. {
  148. this.elems = new Object[arity];
  149. for (int i = 0; i < arity; i++)
  150. {
  151. elems[i] = buf.read_any();
  152. }
  153. }
  154. }
  155. /*
  156. * Get the arity of the tuple.
  157. *
  158. * @return the number of elements contained in the tuple.
  159. **/
  160. public virtual int arity()
  161. {
  162. return elems.Length;
  163. }
  164. /*
  165. * Get the specified element from the tuple.
  166. *
  167. * @param i the index of the requested element. Tuple elements are
  168. * numbered as array elements, starting at 0.
  169. *
  170. * @return the requested element, of null if i is not a valid
  171. * element index.
  172. **/
  173. public virtual Object elementAt(int i)
  174. {
  175. if ((i >= arity()) || (i < 0))
  176. return null;
  177. return elems[i];
  178. }
  179. /*
  180. * Get all the elements from the tuple as an array.
  181. *
  182. * @return an array containing all of the tuple's elements.
  183. **/
  184. public virtual Object[] elements()
  185. {
  186. Object[] res = new Object[arity()];
  187. Array.Copy(this.elems, 0, res, 0, res.Length);
  188. return res;
  189. }
  190. public Object this[int index]
  191. {
  192. get { return this.elems[index]; }
  193. set { this.elems[index] = value; }
  194. }
  195. /*
  196. * Get the string representation of the tuple.
  197. *
  198. * @return the string representation of the tuple.
  199. **/
  200. public override System.String ToString()
  201. {
  202. int i;
  203. System.Text.StringBuilder s = new System.Text.StringBuilder();
  204. int arity = (int) (elems.Length);
  205. s.Append("{");
  206. for (i = 0; i < arity; i++)
  207. {
  208. if (i > 0)
  209. s.Append(",");
  210. s.Append(elems[i].ToString());
  211. }
  212. s.Append("}");
  213. return s.ToString();
  214. }
  215. /*
  216. * Convert this tuple to the equivalent Erlang external representation.
  217. *
  218. * @param buf an output stream to which the encoded tuple should be
  219. * written.
  220. **/
  221. public override void encode(OtpOutputStream buf)
  222. {
  223. int arity = (int) (elems.Length);
  224. buf.write_tuple_head(arity);
  225. for (int i = 0; i < arity; i++)
  226. {
  227. buf.write_any(elems[i]);
  228. }
  229. }
  230. /*
  231. * Determine if two tuples are equal. Tuples are equal if they have
  232. * the same arity and all of the elements are equal.
  233. *
  234. * @param o the tuple to compare to.
  235. *
  236. * @return true if the tuples have the same arity and all the
  237. * elements are equal.
  238. **/
  239. public override bool Equals(System.Object o)
  240. {
  241. if (!(o is Tuple))
  242. return false;
  243. Tuple t = (Tuple) o;
  244. int a = this.arity();
  245. if (a != t.arity())
  246. return false;
  247. for (int i = 0; i < a; i++)
  248. {
  249. if (!this.elems[i].Equals(t.elems[i]))
  250. return false;
  251. // early exit
  252. }
  253. return true;
  254. }
  255. public override int GetHashCode()
  256. {
  257. return 1;
  258. }
  259. public override System.Object clone()
  260. {
  261. Tuple newTuple = (Tuple) (base.clone());
  262. newTuple.elems = new Object[elems.Length];
  263. elems.CopyTo(newTuple.elems, 0);
  264. return newTuple;
  265. }
  266. public override bool subst(ref Object a_term, VarBind binding)
  267. {
  268. System.Collections.Generic.List<Erlang.Object> result =
  269. new System.Collections.Generic.List<Erlang.Object>();
  270. bool changed = false;
  271. foreach (Erlang.Object term in this.elems)
  272. {
  273. Erlang.Object obj = null;
  274. if (term.subst(ref obj, binding))
  275. result.Add(obj);
  276. else
  277. {
  278. changed = true;
  279. result.Add(term);
  280. }
  281. }
  282. if (!changed)
  283. return false;
  284. a_term = new Erlang.Tuple(result.ToArray());
  285. return true;
  286. }
  287. public override bool match(Erlang.Object pattern, VarBind binding)
  288. {
  289. if (pattern is Erlang.Var)
  290. pattern.match(this, binding);
  291. else if (!(pattern is Erlang.Tuple))
  292. return false;
  293. Erlang.Tuple tup = pattern as Erlang.Tuple;
  294. if (arity() != tup.arity())
  295. return false;
  296. for (int i = 0; i < arity(); ++i)
  297. if (!elems[i].match(tup[i], binding))
  298. return false;
  299. return true;
  300. }
  301. }
  302. }