5 // Ben Maurer (bmaurer@ximian.com)
6 // Jensen Somers <jensen.somers@gmail.com>
7 // Marek Safar (marek.safar@gmail.com)
9 // Copyright (C) 2004 Novell
10 // Copyright (C) 2012 Xamarin, Inc (http://www.xamarin.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Collections;
33 using System.Collections.Generic;
38 public struct ArraySegment<T>
40 : IList<T>, IReadOnlyList<T>
44 readonly int offset, count;
46 public ArraySegment (T [] array, int offset, int count)
49 throw new ArgumentNullException ("array");
52 throw new ArgumentOutOfRangeException ("offset", "Non-negative number required.");
55 throw new ArgumentOutOfRangeException ("count", "Non-negative number required.");
57 if (offset > array.Length)
58 throw new ArgumentException ("out of bounds");
60 // now offset is valid, or just beyond the end.
61 // Check count -- do it this way to avoid overflow on 'offset + count'
62 if (array.Length - offset < count)
63 throw new ArgumentException ("out of bounds", "offset");
70 public ArraySegment (T [] array)
73 throw new ArgumentNullException ("array");
77 this.count = array.Length;
85 get { return offset; }
92 public override bool Equals (Object obj)
94 if (obj is ArraySegment<T>) {
95 return this.Equals((ArraySegment<T>) obj);
100 public bool Equals (ArraySegment<T> obj)
102 if ((this.array == obj.Array) && (this.offset == obj.Offset) && (this.count == obj.Count))
107 public override int GetHashCode ()
109 return ((this.array.GetHashCode() ^ this.offset) ^ this.count);
112 public static bool operator ==(ArraySegment<T> a, ArraySegment<T> b)
117 public static bool operator !=(ArraySegment<T> a, ArraySegment<T> b)
119 return !(a.Equals(b));
123 bool ICollection<T>.IsReadOnly {
129 T IReadOnlyList<T>.this[int index] {
131 return ((IList<T>) this)[index];
135 T IList<T>.this[int index] {
137 if (index < 0 || index >= count)
138 throw new ArgumentOutOfRangeException ("index");
140 return array[offset + index];
143 if (index < 0 || index >= count)
144 throw new ArgumentOutOfRangeException ("index");
146 array[offset + index] = value;
150 void ICollection<T>.Add (T item)
152 throw new NotSupportedException ();
155 void ICollection<T>.Clear ()
157 throw new NotSupportedException ();
160 bool ICollection<T>.Remove (T item)
162 throw new NotSupportedException ();
165 void IList<T>.Insert (int index, T item)
167 throw new NotSupportedException ();
170 void IList<T>.RemoveAt (int index)
172 throw new NotSupportedException ();
175 bool ICollection<T>.Contains (T item)
177 return System.Array.IndexOf (array, item, offset, count) >= 0;
180 void ICollection<T>.CopyTo (T[] array, int arrayIndex)
182 System.Array.Copy (this.array, offset, array, arrayIndex, count);
185 IEnumerator<T> IEnumerable<T>.GetEnumerator ()
187 for (int i = 0; i < count; ++i)
188 yield return array[offset + i];
191 IEnumerator IEnumerable.GetEnumerator ()
193 return ((IEnumerable<T>) this).GetEnumerator ();
196 int IList<T>.IndexOf (T item)
198 var res = System.Array.IndexOf (array, item, offset, count);
199 return res < 0 ? -1 : res - offset;