IntPtr.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Globalization;
  5. using System.Runtime.CompilerServices;
  6. using System.Runtime.Serialization;
  7. using System.Runtime.Versioning;
  8. #if BIT64
  9. using nint = System.Int64;
  10. #else
  11. using nint = System.Int32;
  12. #endif
  13. namespace System
  14. {
  15. [Serializable]
  16. [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
  17. public readonly struct IntPtr : IEquatable<IntPtr>, ISerializable
  18. {
  19. // WARNING: We allow diagnostic tools to directly inspect this member (_value).
  20. // See https://github.com/dotnet/corert/blob/master/Documentation/design-docs/diagnostics/diagnostics-tools-contract.md for more details.
  21. // Please do not change the type, the name, or the semantic usage of this member without understanding the implication for tools.
  22. // Get in touch with the diagnostics team if you have questions.
  23. private readonly unsafe void* _value; // Do not rename (binary serialization)
  24. [Intrinsic]
  25. public static readonly IntPtr Zero;
  26. [Intrinsic]
  27. [NonVersionable]
  28. public unsafe IntPtr(int value)
  29. {
  30. _value = (void*)value;
  31. }
  32. [Intrinsic]
  33. [NonVersionable]
  34. public unsafe IntPtr(long value)
  35. {
  36. #if BIT64
  37. _value = (void*)value;
  38. #else
  39. _value = (void*)checked((int)value);
  40. #endif
  41. }
  42. [CLSCompliant(false)]
  43. [Intrinsic]
  44. [NonVersionable]
  45. public unsafe IntPtr(void* value)
  46. {
  47. _value = value;
  48. }
  49. private unsafe IntPtr(SerializationInfo info, StreamingContext context)
  50. {
  51. long l = info.GetInt64("value");
  52. if (Size == 4 && (l > int.MaxValue || l < int.MinValue))
  53. throw new ArgumentException(SR.Serialization_InvalidPtrValue);
  54. _value = (void*)l;
  55. }
  56. unsafe void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
  57. {
  58. if (info == null)
  59. throw new ArgumentNullException(nameof(info));
  60. info.AddValue("value", ToInt64());
  61. }
  62. public unsafe override bool Equals(object obj)
  63. {
  64. if (obj is IntPtr)
  65. {
  66. return (_value == ((IntPtr)obj)._value);
  67. }
  68. return false;
  69. }
  70. unsafe bool IEquatable<IntPtr>.Equals(IntPtr other)
  71. {
  72. return _value == other._value;
  73. }
  74. public unsafe override int GetHashCode()
  75. {
  76. #if BIT64
  77. long l = (long)_value;
  78. return (unchecked((int)l) ^ (int)(l >> 32));
  79. #else
  80. return unchecked((int)_value);
  81. #endif
  82. }
  83. [Intrinsic]
  84. [NonVersionable]
  85. public unsafe int ToInt32()
  86. {
  87. #if BIT64
  88. long l = (long)_value;
  89. return checked((int)l);
  90. #else
  91. return (int)_value;
  92. #endif
  93. }
  94. [Intrinsic]
  95. [NonVersionable]
  96. public unsafe long ToInt64()
  97. {
  98. return (nint)_value;
  99. }
  100. [Intrinsic]
  101. [NonVersionable]
  102. public static unsafe explicit operator IntPtr(int value)
  103. {
  104. return new IntPtr(value);
  105. }
  106. [Intrinsic]
  107. [NonVersionable]
  108. public static unsafe explicit operator IntPtr(long value)
  109. {
  110. return new IntPtr(value);
  111. }
  112. [CLSCompliant(false)]
  113. [Intrinsic]
  114. [NonVersionable]
  115. public static unsafe explicit operator IntPtr(void* value)
  116. {
  117. return new IntPtr(value);
  118. }
  119. [CLSCompliant(false)]
  120. [Intrinsic]
  121. [NonVersionable]
  122. public static unsafe explicit operator void* (IntPtr value)
  123. {
  124. return value._value;
  125. }
  126. [Intrinsic]
  127. [NonVersionable]
  128. public static unsafe explicit operator int(IntPtr value)
  129. {
  130. #if BIT64
  131. long l = (long)value._value;
  132. return checked((int)l);
  133. #else
  134. return (int)value._value;
  135. #endif
  136. }
  137. [Intrinsic]
  138. [NonVersionable]
  139. public static unsafe explicit operator long(IntPtr value)
  140. {
  141. return (nint)value._value;
  142. }
  143. [Intrinsic]
  144. [NonVersionable]
  145. public static unsafe bool operator ==(IntPtr value1, IntPtr value2)
  146. {
  147. return value1._value == value2._value;
  148. }
  149. [Intrinsic]
  150. [NonVersionable]
  151. public static unsafe bool operator !=(IntPtr value1, IntPtr value2)
  152. {
  153. return value1._value != value2._value;
  154. }
  155. [NonVersionable]
  156. public static IntPtr Add(IntPtr pointer, int offset)
  157. {
  158. return pointer + offset;
  159. }
  160. [Intrinsic]
  161. [NonVersionable]
  162. public static unsafe IntPtr operator +(IntPtr pointer, int offset)
  163. {
  164. return new IntPtr((nint)pointer._value + offset);
  165. }
  166. [NonVersionable]
  167. public static IntPtr Subtract(IntPtr pointer, int offset)
  168. {
  169. return pointer - offset;
  170. }
  171. [Intrinsic]
  172. [NonVersionable]
  173. public static unsafe IntPtr operator -(IntPtr pointer, int offset)
  174. {
  175. return new IntPtr((nint)pointer._value - offset);
  176. }
  177. public static int Size
  178. {
  179. [Intrinsic]
  180. [NonVersionable]
  181. get
  182. {
  183. return sizeof(nint);
  184. }
  185. }
  186. [CLSCompliant(false)]
  187. [Intrinsic]
  188. [NonVersionable]
  189. #if PROJECTN
  190. [System.Runtime.CompilerServices.DependencyReductionRootAttribute]
  191. #endif
  192. public unsafe void* ToPointer()
  193. {
  194. return _value;
  195. }
  196. public unsafe override string ToString()
  197. {
  198. return ((nint)_value).ToString(CultureInfo.InvariantCulture);
  199. }
  200. public unsafe string ToString(string format)
  201. {
  202. return ((nint)_value).ToString(format, CultureInfo.InvariantCulture);
  203. }
  204. }
  205. }