Merge pull request #1624 from esdrubal/getprocesstimes
[mono.git] / mcs / class / corlib / System / IntPtr.cs
index aab0523d7dde83b7043eb9c8c751554ef174322d..c449de83997a3b308b1df8fbe881eb053f166dc3 100644 (file)
 
 using System.Globalization;
 using System.Runtime.Serialization;
-
-#if NET_2_0
 using System.Runtime.ConstrainedExecution;
-#endif
+using System.Diagnostics.Contracts;
 
 namespace System
 {
        [Serializable]
+       [System.Runtime.InteropServices.ComVisible (true)]
        public unsafe struct IntPtr : ISerializable
        {
-               private void *value;
+               private void *m_value;
 
                public static readonly IntPtr Zero;
 
-               public IntPtr (int i32)
+               [ReliabilityContract (Consistency.MayCorruptInstance, Cer.MayFail)]
+               public IntPtr (int value)
                {
-                       value = (void *) i32;
+                       m_value = (void *) value;
                }
 
-               public IntPtr (long i64)
+               [ReliabilityContract (Consistency.MayCorruptInstance, Cer.MayFail)]
+               public IntPtr (long value)
                {
-                       if (((i64 > Int32.MaxValue) || (i64 < Int32.MinValue)) && (IntPtr.Size < 8)) {
+                       /* FIXME: Needs to figure the exact check which works on all architectures */
+                       /*
+                       if (((value >> 32 > 0) || (value < 0)) && (IntPtr.Size < 8)) {
                                throw new OverflowException (
                                        Locale.GetText ("This isn't a 64bits machine."));
                        }
+                       */
 
-                       value = (void *) i64;
+                       m_value = (void *) value;
                }
 
                [CLSCompliant (false)]
-               unsafe public IntPtr (void *ptr)
+               [ReliabilityContract (Consistency.MayCorruptInstance, Cer.MayFail)]
+               unsafe public IntPtr (void *value)
                {
-                       value = ptr;
+                       m_value = value;
                }
 
                private IntPtr (SerializationInfo info, StreamingContext context)
                {
                        long savedValue = info.GetInt64 ("value");
-                       value = (void *) savedValue;
+                       m_value = (void *) savedValue;
                }
 
                public static int Size {
-#if NET_2_0
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-#endif
                        get {
                                return sizeof (void *);
                        }
@@ -99,90 +102,83 @@ namespace System
                        if (info == null)
                                throw new ArgumentNullException ("info");
 
-                       info.AddValue ("value", (long) value);
+                       info.AddValue ("value", ToInt64 ());
                }
 
-               public override bool Equals (object o)
+               public override bool Equals (object obj)
                {
-                       if (!(o is System.IntPtr))
+                       if (!(obj is System.IntPtr))
                                return false;
 
-                       return ((IntPtr) o).value == value;
+                       return ((IntPtr) obj).m_value == m_value;
                }
 
                public override int GetHashCode ()
                {
-                       return (int) value;
+                       return (int) m_value;
                }
 
-#if NET_2_0
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-#endif
                public int ToInt32 ()
                {
-                       return (int) value;
+                       return (int) m_value;
                }
 
-#if NET_2_0
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-#endif
                public long ToInt64 ()
                {
-                       return (long) value;
+                       // pointer to long conversion is done using conv.u8 by the compiler
+                       if (Size == 4)
+                               return (long)(int)m_value;
+                       else
+                               return (long)m_value;
                }
 
                [CLSCompliant (false)]
-#if NET_2_0
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-#endif
                unsafe public void *ToPointer ()
                {
-                       return value;
+                       return m_value;
                }
 
                override public string ToString ()
+               {
+                       return ToString (null);
+               }
+
+               public string ToString (string format)
                {
                        if (Size == 4)
-                               return ((int) value).ToString ();
+                               return ((int) m_value).ToString (format, null);
                        else
-                               return ((long) value).ToString ();
+                               return ((long) m_value).ToString (format, null);
                }
 
-#if NET_2_0
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-#endif
-               public static bool operator == (IntPtr a, IntPtr b)
+               public static bool operator == (IntPtr value1, IntPtr value2)
                {
-                       return (a.value == b.value);
+                       return (value1.m_value == value2.m_value);
                }
 
-#if NET_2_0
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-#endif
-               public static bool operator != (IntPtr a, IntPtr b)
+               public static bool operator != (IntPtr value1, IntPtr value2)
                {
-                       return (a.value != b.value);
+                       return (value1.m_value != value2.m_value);
                }
 
-#if NET_2_0
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-#endif
+               [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
                public static explicit operator IntPtr (int value)
                {
                        return new IntPtr (value);
                }
 
-#if NET_2_0
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-#endif
+               [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
                public static explicit operator IntPtr (long value)
                {
                        return new IntPtr (value);
                }
 
-#if NET_2_0
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-#endif         
+               [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
                [CLSCompliant (false)]
                unsafe public static explicit operator IntPtr (void *value)
                {
@@ -191,18 +187,50 @@ namespace System
 
                public static explicit operator int (IntPtr value)
                {
-                       return (int) value.value;
+                       return (int) value.m_value;
                }
 
                public static explicit operator long (IntPtr value)
                {
-                       return (long) value.value;
+                       return value.ToInt64 ();
                }
 
                [CLSCompliant (false)]
                unsafe public static explicit operator void * (IntPtr value)
                {
-                       return value.value;
+                       return value.m_value;
+               }
+
+               [ReliabilityContract (Consistency.MayCorruptInstance, Cer.MayFail)]
+               public static IntPtr Add (IntPtr pointer, int offset)
+               {
+                       return (IntPtr) (unchecked (((byte *) pointer) + offset));
+               }
+
+               [ReliabilityContract (Consistency.MayCorruptInstance, Cer.MayFail)]
+               public static IntPtr Subtract (IntPtr pointer, int offset)
+               {
+                       return (IntPtr) (unchecked (((byte *) pointer) - offset));
+               }
+
+               [ReliabilityContract (Consistency.MayCorruptInstance, Cer.MayFail)]
+               public static IntPtr operator + (IntPtr pointer, int offset)
+               {
+                       return (IntPtr) (unchecked (((byte *) pointer) + offset));
+               }
+
+               [ReliabilityContract (Consistency.MayCorruptInstance, Cer.MayFail)]
+               public static IntPtr operator - (IntPtr pointer, int offset)
+               {
+                       return (IntPtr) (unchecked (((byte *) pointer) - offset));
+               }
+
+               // fast way to compare IntPtr to (IntPtr)0 while IntPtr.Zero doesn't work due to slow statics access
+               [Pure]
+               [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+               internal unsafe bool IsNull()
+               {
+                       return m_value == null;
                }
        }
 }