2010-03-18 Carlos Alberto Cortez <calberto.cortez@gmail.com>
[mono.git] / mcs / class / corlib / System / IntPtr.cs
index b13f43c2fb0a39d63332a1dcd5cb5dc39014694b..1b36f47d372556da378adc0b7f3946659d67d0d6 100644 (file)
 //
 // (C) Ximian, Inc.  http://www.ximian.com
 //
-// Remarks:                    Requires '/unsafe' compiler option.  This class uses void*,
-//                                     in overloaded constructors, conversion, and cast members in 
-//                                     the public interface.  Using pointers is not valid CLS and 
-//                                     the methods in question have been marked with  the 
-//                                     CLSCompliant attribute that avoid compiler warnings.
+// Remarks:
+//   Requires '/unsafe' compiler option.  This class uses void*,
+//   in overloaded constructors, conversion, and cast members in 
+//   the public interface.  Using pointers is not valid CLS and 
+//   the methods in question have been marked with  the 
+//   CLSCompliant attribute that avoid compiler warnings.
 //
 // FIXME: How do you specify a native int in C#?  I am going to have to do some figuring out
 //
 
-using System;
-using System.Runtime.Serialization;
-
-#if __MonoCS__
-#else
-[
-    assembly: System.CLSCompliant(true)
-]
-#endif
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
 
-namespace System {
+using System.Globalization;
+using System.Runtime.Serialization;
+using System.Runtime.ConstrainedExecution;
 
-       [
-               CLSCompliant(true)
-       ]
+namespace System
+{
        [Serializable]
-       public unsafe struct IntPtr : ISerializable {
-
-               private void *value;
+       [System.Runtime.InteropServices.ComVisible (true)]
+       public unsafe struct IntPtr : ISerializable
+       {
+               private void *m_value;
 
                public static readonly IntPtr Zero;
 
-               static IntPtr ()
+               [ReliabilityContract (Consistency.MayCorruptInstance, Cer.MayFail)]
+               public IntPtr (int value)
                {
-                       Zero.value = (void *) 0;
-               }
-               
-               public IntPtr (int i32)
-               {
-                       value = (void *) i32;
+                       m_value = (void *) value;
                }
 
-               public IntPtr (long i64)
+               [ReliabilityContract (Consistency.MayCorruptInstance, Cer.MayFail)]
+               public IntPtr (long value)
                {
-                       value = (void *) i64;
+                       /* 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."));
+                       }
+                       */
+
+                       m_value = (void *) value;
                }
 
-               [
-                       CLSCompliant(false)
-               ]
-               unsafe public IntPtr (void *ptr)
+               [CLSCompliant (false)]
+               [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 {
+               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                        get {
                                return sizeof (void *);
                        }
                }
 
-               public void GetObjectData (SerializationInfo si, StreamingContext sc)
+               void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
                {
-                       if( si == null )
-                               throw new ArgumentNullException( "si" );
-        
-                       si.AddValue("value", (long) value);
+                       if (info == null)
+                               throw new ArgumentNullException ("info");
+
+                       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;
                }
 
+               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                public int ToInt32 ()
                {
-                       return (int) value;
+                       return (int) m_value;
                }
 
+               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                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)
-               ]
+               [CLSCompliant (false)]
+               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                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);
                        else
-                               return ((long) value).ToString ();
+                               return ((long) m_value).ToString (format);
                }
 
-               public static bool operator == (IntPtr a, IntPtr b)
+               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
+               public static bool operator == (IntPtr value1, IntPtr value2)
                {
-                       return (a.value == b.value);
+                       return (value1.m_value == value2.m_value);
                }
 
-               public static bool operator != (IntPtr a, IntPtr b)
+               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
+               public static bool operator != (IntPtr value1, IntPtr value2)
                {
-                       return (a.value != b.value);
+                       return (value1.m_value != value2.m_value);
                }
 
+               [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
                public static explicit operator IntPtr (int value)
                {
                        return new IntPtr (value);
                }
 
+               [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
                public static explicit operator IntPtr (long value)
                {
                        return new IntPtr (value);
                }
-               
-               [
-                       CLSCompliant(false)
-               ]
+
+               [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
+               [CLSCompliant (false)]
                unsafe public static explicit operator IntPtr (void *value)
                {
                        return new IntPtr (value);
@@ -152,20 +186,44 @@ 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)
-               ]
+               [CLSCompliant (false)]
                unsafe public static explicit operator void * (IntPtr value)
                {
-                       return value.value;
+                       return value.m_value;
+               }
+
+#if NET_4_0
+               [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));
+               }
+#endif
        }
 }