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;
public T Current {
get {
- if (idx < 0)
- throw new InvalidOperationException ();
+ if (idx == NOT_STARTED)
+ throw new InvalidOperationException ("Enumeration has not started. Call MoveNext");
+ if (idx == FINISHED)
+ throw new InvalidOperationException ("Enumeration already finished");
return array.InternalArray__get_Item<T> (array.Length - 1 - idx);
}
void IEnumerator.Reset ()
{
- throw new NotImplementedException ();
+ idx = NOT_STARTED;
}
object IEnumerator.Current {
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."));
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
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)