PageRenderTime 41ms CodeModel.GetById 0ms RepoModel.GetById 1ms app.codeStats 0ms

/source/library/Interlace/Erlang/Tuple.cs

https://bitbucket.org/VahidN/interlace
C# | 218 lines | 98 code | 29 blank | 91 comment | 17 complexity | e6380d8be340d27b8e0bcabe426f69a7 MD5 | raw file
  1. #region Using Directives and Copyright Notice
  2. // Copyright (c) 2007-2010, Computer Consultancy Pty Ltd
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are met:
  7. // * Redistributions of source code must retain the above copyright
  8. // notice, this list of conditions and the following disclaimer.
  9. // * Redistributions in binary form must reproduce the above copyright
  10. // notice, this list of conditions and the following disclaimer in the
  11. // documentation and/or other materials provided with the distribution.
  12. // * Neither the name of the Computer Consultancy Pty Ltd nor the
  13. // names of its contributors may be used to endorse or promote products
  14. // derived from this software without specific prior written permission.
  15. //
  16. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. // ARE DISCLAIMED. IN NO EVENT SHALL COMPUTER CONSULTANCY PTY LTD BE LIABLE
  20. // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22. // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  26. // DAMAGE.
  27. #endregion
  28. // Portions of this code were originally developed for Bit Plantation BitLibrary.
  29. // (Portions Copyright © 2006 Bit Plantation)
  30. using System;
  31. using System.Collections.Generic;
  32. using System.Collections;
  33. using System.Text;
  34. using System.IO;
  35. using System.Net;
  36. namespace Interlace.Erlang
  37. {
  38. /// <summary>
  39. /// Represents an Erlang style tuple.
  40. /// </summary>
  41. public class Tuple
  42. {
  43. object[] _elements;
  44. /// <summary>
  45. /// Initializes a new instance of the <see cref="Tuple"/> class.
  46. /// </summary>
  47. /// <param name="elements">The elements that make up the tuple items.</param>
  48. public Tuple(params object[] elements)
  49. {
  50. _elements = elements;
  51. }
  52. /// <summary>
  53. /// Gets the object at the specified index.
  54. /// </summary>
  55. /// <value>The object.</value>
  56. public object this[int index]
  57. {
  58. get { return _elements[index]; }
  59. }
  60. /// <summary>
  61. /// Gets the number of items in the tuple.
  62. /// </summary>
  63. /// <value>The number of items.</value>
  64. public int Length
  65. {
  66. get { return _elements.Length; }
  67. }
  68. T InternalAt<T>(int i)
  69. {
  70. if (i < 0) throw new IndexOutOfRangeException();
  71. if (_elements.Length <= i) throw new ErlangProtocolException(string.Format(
  72. "A tuple of at least {0} (but possibly more) items was expected, and " +
  73. "a tuple with only {1} elements was received", i + 1, _elements.Length));
  74. if (typeof(T).Equals(typeof(string)) && _elements[i] is List<object>)
  75. {
  76. List<object> list = _elements[i] as List<object>;
  77. if (list.Count == 0) return (T)(object)"";
  78. }
  79. if (!(_elements[i] is T)) throw new ErlangProtocolException(string.Format(
  80. "The element at index {0} of a tuple is not the correct type."));
  81. return (T)_elements[i];
  82. }
  83. /// <summary>
  84. /// Gets the tuple at the given index, throwing an <see cref="T:ErlangProtocolException" /> if
  85. /// the tuple either does not have the specified element or if the element is not the correct type.
  86. /// </summary>
  87. /// <param name="i">The index of the element to return.</param>
  88. /// <returns>The tuple at the specified index.</returns>
  89. public Tuple TupleAt(int i)
  90. {
  91. return InternalAt<Tuple>(i);
  92. }
  93. /// <summary>
  94. /// Gets the string at the given index, throwing an <see cref="T:ErlangProtocolException" /> if
  95. /// the tuple either does not have the specified element or if the element is not the correct type.
  96. /// </summary>
  97. /// <param name="i">The index of the element to return.</param>
  98. /// <returns>The string at the specified index.</returns>
  99. public string StringAt(int i)
  100. {
  101. return InternalAt<string>(i);
  102. }
  103. /// <summary>
  104. /// Gets the integer at the given index, throwing an <see cref="T:ErlangProtocolException" /> if
  105. /// the tuple either does not have the specified element or if the element is not the correct type.
  106. /// </summary>
  107. /// <param name="i">The index of the element to return.</param>
  108. /// <returns>The integer at the specified index.</returns>
  109. public int IntegerAt(int i)
  110. {
  111. return InternalAt<int>(i);
  112. }
  113. /// <summary>
  114. /// Gets the atom at the given index, throwing an <see cref="T:ErlangProtocolException" /> if
  115. /// the tuple either does not have the specified element or if the element is not the correct type.
  116. /// </summary>
  117. /// <param name="i">The index of the element to return.</param>
  118. /// <returns>The atom at the specified index.</returns>
  119. public Atom AtomAt(int i)
  120. {
  121. return InternalAt<Atom>(i);
  122. }
  123. /// <summary>
  124. /// Gets the object at the given index, throwing an <see cref="T:ErlangProtocolException" /> if
  125. /// the tuple does not have the specified element.
  126. /// </summary>
  127. /// <param name="i">The index of the element to return.</param>
  128. /// <returns>The atom at the specified index.</returns>
  129. public object ObjectAt(int i)
  130. {
  131. return InternalAt<object>(i);
  132. }
  133. /// <summary>
  134. /// Determines whether the specified <see cref="T:System.Object"></see> is equal to the current <see cref="T:System.Object"></see>.
  135. /// </summary>
  136. /// <param name="obj">The <see cref="T:System.Object"></see> to compare with the current <see cref="T:System.Object"></see>.</param>
  137. /// <returns>
  138. /// true if the specified <see cref="T:System.Object"></see> is equal to the current <see cref="T:System.Object"></see>; otherwise, false.
  139. /// </returns>
  140. public override bool Equals(object obj)
  141. {
  142. Tuple rhs = obj as Tuple;
  143. if (rhs == null) return false;
  144. if (_elements.Length != rhs.Length) return false;
  145. for (int i = 0; i < _elements.Length; i++)
  146. {
  147. if (!Object.Equals(_elements[i], rhs._elements[i])) return false;
  148. }
  149. return true;
  150. }
  151. /// <summary>
  152. /// Serves as a hash function for a particular type. <see cref="M:System.Object.GetHashCode"></see> is suitable for use in hashing algorithms and data structures like a hash table.
  153. /// </summary>
  154. /// <returns>
  155. /// A hash code for the current <see cref="T:System.Object"></see>.
  156. /// </returns>
  157. public override int GetHashCode()
  158. {
  159. int hashCode = 0x00010001 * _elements.Length;
  160. for (int i = 0; i < _elements.Length; i++)
  161. {
  162. if (_elements[i] != null)
  163. {
  164. hashCode ^= _elements[i].GetHashCode();
  165. }
  166. else
  167. {
  168. hashCode ^= 0x00020002 * i;
  169. }
  170. }
  171. return hashCode;
  172. }
  173. /// <summary>
  174. /// Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
  175. /// </summary>
  176. /// <returns>
  177. /// A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
  178. /// </returns>
  179. public override string ToString()
  180. {
  181. string[] elementStrings = new string[_elements.Length];
  182. for (int i = 0; i < _elements.Length; i++)
  183. {
  184. elementStrings[i] = _elements[i].ToString();
  185. }
  186. return string.Format("Tuple({0})", string.Join(", ", elementStrings));
  187. }
  188. }
  189. }