Merge pull request #409 from Alkarex/patch-1
[mono.git] / mcs / tools / monkeydoc / Lucene.Net / Lucene.Net / Util / ArrayUtil.cs
1 /* 
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  * 
9  * http://www.apache.org/licenses/LICENSE-2.0
10  * 
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 using System;
19
20 namespace Mono.Lucene.Net.Util
21 {
22         
23         /// <summary> Methods for manipulating arrays.</summary>
24         public sealed class ArrayUtil
25         {
26                 /*
27                 Begin Apache Harmony code
28                 
29                 Revision taken on Friday, June 12. https://svn.apache.org/repos/asf/harmony/enhanced/classlib/archive/java6/modules/luni/src/main/java/java/lang/Integer.java
30                 
31                 */
32                 
33                 /// <summary> Parses the string argument as if it was an int value and returns the
34                 /// result. Throws NumberFormatException if the string does not represent an
35                 /// int quantity.
36                 /// 
37                 /// </summary>
38                 /// <param name="chars">a string representation of an int quantity.
39                 /// </param>
40                 /// <returns> int the value represented by the argument
41                 /// </returns>
42                 /// <throws>  NumberFormatException if the argument could not be parsed as an int quantity. </throws>
43                 public static int ParseInt(char[] chars)
44                 {
45                         return ParseInt(chars, 0, chars.Length, 10);
46                 }
47                 
48                 /// <summary> Parses a char array into an int.</summary>
49                 /// <param name="chars">the character array
50                 /// </param>
51                 /// <param name="offset">The offset into the array
52                 /// </param>
53                 /// <param name="len">The length
54                 /// </param>
55                 /// <returns> the int
56                 /// </returns>
57                 /// <throws>  NumberFormatException if it can't parse </throws>
58                 public static int ParseInt(char[] chars, int offset, int len)
59                 {
60                         return ParseInt(chars, offset, len, 10);
61                 }
62                 
63                 /// <summary> Parses the string argument as if it was an int value and returns the
64                 /// result. Throws NumberFormatException if the string does not represent an
65                 /// int quantity. The second argument specifies the radix to use when parsing
66                 /// the value.
67                 /// 
68                 /// </summary>
69                 /// <param name="chars">a string representation of an int quantity.
70                 /// </param>
71                 /// <param name="radix">the base to use for conversion.
72                 /// </param>
73                 /// <returns> int the value represented by the argument
74                 /// </returns>
75                 /// <throws>  NumberFormatException if the argument could not be parsed as an int quantity. </throws>
76                 public static int ParseInt(char[] chars, int offset, int len, int radix)
77                 {
78                         if (chars == null || radix < 2 || radix > 36)
79                         {
80                                 throw new System.FormatException();
81                         }
82                         int i = 0;
83                         if (len == 0)
84                         {
85                                 throw new System.FormatException("chars length is 0");
86                         }
87                         bool negative = chars[offset + i] == '-';
88                         if (negative && ++i == len)
89                         {
90                                 throw new System.FormatException("can't convert to an int");
91                         }
92                         if (negative == true)
93                         {
94                                 offset++;
95                                 len--;
96                         }
97                         return Parse(chars, offset, len, radix, negative);
98                 }
99                 
100                 
101                 private static int Parse(char[] chars, int offset, int len, int radix, bool negative)
102                 {
103                         int max = System.Int32.MinValue / radix;
104                         int result = 0;
105                         for (int i = 0; i < len; i++)
106                         {
107                                 int digit = (int) System.Char.GetNumericValue(chars[i + offset]);
108                                 if (digit == - 1)
109                                 {
110                                         throw new System.FormatException("Unable to parse");
111                                 }
112                                 if (max > result)
113                                 {
114                                         throw new System.FormatException("Unable to parse");
115                                 }
116                                 int next = result * radix - digit;
117                                 if (next > result)
118                                 {
119                                         throw new System.FormatException("Unable to parse");
120                                 }
121                                 result = next;
122                         }
123                         /*while (offset < len) {
124                         
125                         }*/
126                         if (!negative)
127                         {
128                                 result = - result;
129                                 if (result < 0)
130                                 {
131                                         throw new System.FormatException("Unable to parse");
132                                 }
133                         }
134                         return result;
135                 }
136                 
137                 
138                 /*
139                 
140                 END APACHE HARMONY CODE
141                 */
142                 
143                 
144                 public static int GetNextSize(int targetSize)
145                 {
146                         /* This over-allocates proportional to the list size, making room
147                         * for additional growth.  The over-allocation is mild, but is
148                         * enough to give linear-time amortized behavior over a long
149                         * sequence of appends() in the presence of a poorly-performing
150                         * system realloc().
151                         * The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
152                         */
153                         return (targetSize >> 3) + (targetSize < 9?3:6) + targetSize;
154                 }
155                 
156                 public static int GetShrinkSize(int currentSize, int targetSize)
157                 {
158                         int newSize = GetNextSize(targetSize);
159                         // Only reallocate if we are "substantially" smaller.
160                         // This saves us from "running hot" (constantly making a
161                         // bit bigger then a bit smaller, over and over):
162                         if (newSize < currentSize / 2)
163                                 return newSize;
164                         else
165                                 return currentSize;
166                 }
167                 
168                 public static int[] Grow(int[] array, int minSize)
169                 {
170                         if (array.Length < minSize)
171                         {
172                                 int[] newArray = new int[GetNextSize(minSize)];
173                                 Array.Copy(array, 0, newArray, 0, array.Length);
174                                 return newArray;
175                         }
176                         else
177                                 return array;
178                 }
179                 
180                 public static int[] Grow(int[] array)
181                 {
182                         return Grow(array, 1 + array.Length);
183                 }
184                 
185                 public static int[] Shrink(int[] array, int targetSize)
186                 {
187                         int newSize = GetShrinkSize(array.Length, targetSize);
188                         if (newSize != array.Length)
189                         {
190                                 int[] newArray = new int[newSize];
191                                 Array.Copy(array, 0, newArray, 0, newSize);
192                                 return newArray;
193                         }
194                         else
195                                 return array;
196                 }
197                 
198                 public static long[] Grow(long[] array, int minSize)
199                 {
200                         if (array.Length < minSize)
201                         {
202                                 long[] newArray = new long[GetNextSize(minSize)];
203                                 Array.Copy(array, 0, newArray, 0, array.Length);
204                                 return newArray;
205                         }
206                         else
207                                 return array;
208                 }
209                 
210                 public static long[] Grow(long[] array)
211                 {
212                         return Grow(array, 1 + array.Length);
213                 }
214                 
215                 public static long[] Shrink(long[] array, int targetSize)
216                 {
217                         int newSize = GetShrinkSize(array.Length, targetSize);
218                         if (newSize != array.Length)
219                         {
220                                 long[] newArray = new long[newSize];
221                                 Array.Copy(array, 0, newArray, 0, newSize);
222                                 return newArray;
223                         }
224                         else
225                                 return array;
226                 }
227                 
228                 public static byte[] Grow(byte[] array, int minSize)
229                 {
230                         if (array.Length < minSize)
231                         {
232                                 byte[] newArray = new byte[GetNextSize(minSize)];
233                                 Array.Copy(array, 0, newArray, 0, array.Length);
234                                 return newArray;
235                         }
236                         else
237                                 return array;
238                 }
239                 
240                 public static byte[] Grow(byte[] array)
241                 {
242                         return Grow(array, 1 + array.Length);
243                 }
244                 
245                 public static byte[] Shrink(byte[] array, int targetSize)
246                 {
247                         int newSize = GetShrinkSize(array.Length, targetSize);
248                         if (newSize != array.Length)
249                         {
250                                 byte[] newArray = new byte[newSize];
251                                 Array.Copy(array, 0, newArray, 0, newSize);
252                                 return newArray;
253                         }
254                         else
255                                 return array;
256                 }
257                 
258                 /// <summary> Returns hash of chars in range start (inclusive) to
259                 /// end (inclusive)
260                 /// </summary>
261                 public static int HashCode(char[] array, int start, int end)
262                 {
263                         int code = 0;
264                         for (int i = end - 1; i >= start; i--)
265                                 code = code * 31 + array[i];
266                         return code;
267                 }
268                 
269                 /// <summary> Returns hash of chars in range start (inclusive) to
270                 /// end (inclusive)
271                 /// </summary>
272                 public static int HashCode(byte[] array, int start, int end)
273                 {
274                         int code = 0;
275                         for (int i = end - 1; i >= start; i--)
276                                 code = code * 31 + array[i];
277                         return code;
278                 }
279         }
280 }