namespace System
{
[Serializable]
+#if NET_2_0
+ [ComVisible (true)]
+#endif
// FIXME: We are doing way to many double/triple exception checks for the overloaded functions"
// FIXME: Sort overloads parameter checks are VERY inconsistent"
public abstract class Array : ICloneable, ICollection, IList, IEnumerable
}
#if NET_2_0
+ // FIXME: they should not be exposed, but there are some
+ // dependent code in the runtime.
protected int InternalArray__ICollection_get_Count<T> ()
{
return Length;
if (this.Rank > 1)
throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
if (index + this.GetLength (0) > array.GetLowerBound (0) + array.GetLength (0))
- throw new ArgumentException ();
+ throw new ArgumentException ("Destination array was not long " +
+ "enough. Check destIndex and length, and the array's " +
+ "lower bounds.");
if (array.Rank > 1)
throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
if (index < 0)
protected void InternalArray__set_Item<T> (int index, T item)
{
- throw new NotSupportedException ("Collection is read-only");
+ if (unchecked ((uint) index) >= unchecked ((uint) Length))
+ throw new ArgumentOutOfRangeException ("index");
+
+ SetGenericValueImpl (index, ref item);
}
// CAUTION! No bounds checking!
[MethodImplAttribute (MethodImplOptions.InternalCall)]
internal extern void GetGenericValueImpl<T> (int pos, out T value);
+ // CAUTION! No bounds checking!
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern void SetGenericValueImpl<T> (int pos, ref T value);
+
internal struct InternalEnumerator<T> : IEnumerator<T>
{
const int NOT_STARTED = -2;
int iCmp = 0;
try {
while (iMin <= iMax) {
- int iMid = (iMin + iMax) / 2;
+ // Be careful with overflow
+ // http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html
+ int iMid = iMin + ((iMax - iMin) / 2);
object elt = array.GetValueImpl (iMid);
iCmp = comparer.Compare (elt, value);
int dest_pos = destinationIndex - destinationArray.GetLowerBound (0);
// re-ordered to avoid possible integer overflow
- if (source_pos > sourceArray.Length - length || dest_pos > destinationArray.Length - length)
+ if (source_pos > sourceArray.Length - length)
throw new ArgumentException ("length");
+ if (dest_pos > destinationArray.Length - length) {
+ string msg = "Destination array was not long enough. Check " +
+ "destIndex and length, and the array's lower bounds";
+#if NET_2_0
+ throw new ArgumentException (msg, string.Empty);
+#else
+ throw new ArgumentException (msg);
+#endif
+ }
+
if (sourceArray.Rank != destinationArray.Rank)
throw new RankException (Locale.GetText ("Arrays must be of same size."));
if (array is double[])
return new Swapper (array.double_swapper);
- return new Swapper (array.obj_swapper);
+ // gmcs refuses to compile this
+ //return new Swapper (array.generic_swapper<T>);
+ return new Swapper (array.slow_swapper);
}
#endif
array [j] = val;
}
+#if NET_2_0
+ void generic_swapper<T> (int i, int j) {
+ T[] array = this as T[];
+ T val = array [i];
+ array [i] = array [j];
+ array [j] = val;
+ }
+#endif
+
static int new_gap (int gap)
{
gap = (gap * 10) / 13;
int low = low0;
int high = high0;
- object objPivot = keys.GetValueImpl ((low + high) / 2);
+ // Be careful with overflows
+ int mid = low + ((high - low) / 2);
+ object objPivot = keys.GetValueImpl (mid);
while (low <= high) {
// Move the walls in
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<T> (T [] array)
{
if (array == null)
Sort<T, T> (array, null, 0, array.Length, null);
}
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<TKey, TValue> (TKey [] keys, TValue [] items)
{
if (keys == null)
Sort<TKey, TValue> (keys, items, 0, keys.Length, null);
}
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<T> (T [] array, IComparer<T> comparer)
{
if (array == null)
Sort<T, T> (array, null, 0, array.Length, comparer);
}
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<TKey, TValue> (TKey [] keys, TValue [] items, IComparer<TKey> comparer)
{
if (keys == null)
Sort<TKey, TValue> (keys, items, 0, keys.Length, comparer);
}
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<T> (T [] array, int index, int length)
{
if (array == null)
Sort<T, T> (array, null, index, length, null);
}
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<TKey, TValue> (TKey [] keys, TValue [] items, int index, int length)
{
Sort<TKey, TValue> (keys, items, index, length, null);
}
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<T> (T [] array, int index, int length, IComparer<T> comparer)
{
if (array == null)
Sort<T, T> (array, null, index, length, comparer);
}
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<TKey, TValue> (TKey [] keys, TValue [] items, int index, int length, IComparer<TKey> comparer)
{
if (keys == null)
int low = low0;
int high = high0;
- K keyPivot = keys [(low + high) / 2];
+ // Be careful with overflows
+ int mid = low + ((high - low) / 2);
+ K keyPivot = keys [mid];
while (low <= high) {
// Move the walls in
int low = low0;
int high = high0;
- T keyPivot = array [(low + high) / 2];
+ // Be careful with overflows
+ int mid = low + ((high - low) / 2);
+ T keyPivot = array [mid];
while (low <= high) {
// Move the walls in
if (this.Rank > 1)
throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
if (index + this.GetLength (0) > array.GetLowerBound (0) + array.GetLength (0))
- throw new ArgumentException ();
+ throw new ArgumentException ("Destination array was not long " +
+ "enough. Check destIndex and length, and the array's " +
+ "lower bounds.");
if (array.Rank > 1)
throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
if (index < 0)
int iCmp = 0;
try {
while (iMin <= iMax) {
- int iMid = (iMin + iMax) / 2;
+ // Be careful with overflows
+ int iMid = iMin + ((iMax - iMin) / 2);
iCmp = comparer.Compare (value, array [iMid]);
if (iCmp == 0)