Merge pull request #409 from Alkarex/patch-1
[mono.git] / mcs / tools / monkeydoc / Lucene.Net / Lucene.Net / Document / NumberTools.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 using NumericUtils = Mono.Lucene.Net.Util.NumericUtils;
21 using NumericRangeQuery = Mono.Lucene.Net.Search.NumericRangeQuery;
22
23 namespace Mono.Lucene.Net.Documents
24 {
25         
26         // do not remove this class in 3.0, it may be needed to decode old indexes!
27         
28         /// <summary> Provides support for converting longs to Strings, and back again. The strings
29         /// are structured so that lexicographic sorting order is preserved.
30         /// 
31         /// <p/>
32         /// That is, if l1 is less than l2 for any two longs l1 and l2, then
33         /// NumberTools.longToString(l1) is lexicographically less than
34         /// NumberTools.longToString(l2). (Similarly for "greater than" and "equals".)
35         /// 
36         /// <p/>
37         /// This class handles <b>all</b> long values (unlike
38         /// {@link Mono.Lucene.Net.Documents.DateField}).
39         /// 
40         /// </summary>
41         /// <deprecated> For new indexes use {@link NumericUtils} instead, which
42         /// provides a sortable binary representation (prefix encoded) of numeric
43         /// values.
44         /// To index and efficiently query numeric values use {@link NumericField}
45         /// and {@link NumericRangeQuery}.
46         /// This class is included for use with existing
47         /// indices and will be removed in a future release.
48         /// </deprecated>
49     [Obsolete("For new indexes use NumericUtils instead, which provides a sortable binary representation (prefix encoded) of numeric values. To index and efficiently query numeric values use NumericField and NumericRangeQuery. This class is included for use with existing indices and will be removed in a future release.")]
50         public class NumberTools
51         {
52                 
53                 private const int RADIX = 36;
54                 
55                 private const char NEGATIVE_PREFIX = '-';
56                 
57                 // NB: NEGATIVE_PREFIX must be < POSITIVE_PREFIX
58                 private const char POSITIVE_PREFIX = '0';
59                 
60                 //NB: this must be less than
61                 /// <summary> Equivalent to longToString(Long.MIN_VALUE)</summary>
62 #if !PRE_LUCENE_NET_2_0_0_COMPATIBLE
63                 public static readonly System.String MIN_STRING_VALUE = NEGATIVE_PREFIX + "0000000000000";
64 #else
65         public static readonly System.String MIN_STRING_VALUE = NEGATIVE_PREFIX + "0000000000000000";
66 #endif
67                 
68                 /// <summary> Equivalent to longToString(Long.MAX_VALUE)</summary>
69 #if !PRE_LUCENE_NET_2_0_0_COMPATIBLE
70                 public static readonly System.String MAX_STRING_VALUE = POSITIVE_PREFIX + "1y2p0ij32e8e7";
71 #else
72         public static readonly System.String MAX_STRING_VALUE = POSITIVE_PREFIX + "7fffffffffffffff";
73 #endif
74                 
75                 /// <summary> The length of (all) strings returned by {@link #longToString}</summary>
76                 public static readonly int STR_SIZE = MIN_STRING_VALUE.Length;
77                 
78                 /// <summary> Converts a long to a String suitable for indexing.</summary>
79                 public static System.String LongToString(long l)
80                 {
81                         
82                         if (l == System.Int64.MinValue)
83                         {
84                                 // special case, because long is not symmetric around zero
85                                 return MIN_STRING_VALUE;
86                         }
87                         
88                         System.Text.StringBuilder buf = new System.Text.StringBuilder(STR_SIZE);
89                         
90                         if (l < 0)
91                         {
92                                 buf.Append(NEGATIVE_PREFIX);
93                                 l = System.Int64.MaxValue + l + 1;
94                         }
95                         else
96                         {
97                                 buf.Append(POSITIVE_PREFIX);
98                         }
99 #if !PRE_LUCENE_NET_2_0_0_COMPATIBLE
100             System.String num = ToString(l);
101 #else
102             System.String num = System.Convert.ToString(l, RADIX);
103 #endif
104                         
105                         int padLen = STR_SIZE - num.Length - buf.Length;
106                         while (padLen-- > 0)
107                         {
108                                 buf.Append('0');
109                         }
110                         buf.Append(num);
111                         
112                         return buf.ToString();
113                 }
114                 
115                 /// <summary> Converts a String that was returned by {@link #longToString} back to a
116                 /// long.
117                 /// 
118                 /// </summary>
119                 /// <throws>  IllegalArgumentException </throws>
120                 /// <summary>             if the input is null
121                 /// </summary>
122                 /// <throws>  NumberFormatException </throws>
123                 /// <summary>             if the input does not parse (it was not a String returned by
124                 /// longToString()).
125                 /// </summary>
126                 public static long StringToLong(System.String str)
127                 {
128                         if (str == null)
129                         {
130                                 throw new System.NullReferenceException("string cannot be null");
131                         }
132                         if (str.Length != STR_SIZE)
133                         {
134                                 throw new System.FormatException("string is the wrong size");
135                         }
136                         
137                         if (str.Equals(MIN_STRING_VALUE))
138                         {
139                                 return System.Int64.MinValue;
140                         }
141                         
142                         char prefix = str[0];
143 #if !PRE_LUCENE_NET_2_0_0_COMPATIBLE
144                         long l = ToLong(str.Substring(1));
145 #else
146             long l = System.Convert.ToInt64(str.Substring(1), RADIX);
147 #endif
148                         
149                         if (prefix == POSITIVE_PREFIX)
150                         {
151                                 // nop
152                         }
153                         else if (prefix == NEGATIVE_PREFIX)
154                         {
155                                 l = l - System.Int64.MaxValue - 1;
156                         }
157                         else
158                         {
159                                 throw new System.FormatException("string does not begin with the correct prefix");
160                         }
161                         
162                         return l;
163                 }
164
165 #if !PRE_LUCENE_NET_2_0_0_COMPATIBLE
166         #region BASE36 OPS 
167         static System.String digits = "0123456789abcdefghijklmnopqrstuvwxyz";
168         static long[] powersOf36 = 
169             {
170                 1L,
171                 36L,
172                 36L*36L,
173                 36L*36L*36L,
174                 36L*36L*36L*36L,
175                 36L*36L*36L*36L*36L,
176                 36L*36L*36L*36L*36L*36L,
177                 36L*36L*36L*36L*36L*36L*36L,
178                 36L*36L*36L*36L*36L*36L*36L*36L,
179                 36L*36L*36L*36L*36L*36L*36L*36L*36L,
180                 36L*36L*36L*36L*36L*36L*36L*36L*36L*36L,
181                 36L*36L*36L*36L*36L*36L*36L*36L*36L*36L*36L,
182                 36L*36L*36L*36L*36L*36L*36L*36L*36L*36L*36L*36L
183             };
184
185         public static System.String ToString(long lval)
186         {
187             if (lval == 0)
188             {
189                 return "0";
190             }
191
192             int maxStrLen = powersOf36.Length;
193             long curval = lval;
194
195             char[] tb = new char[maxStrLen];
196             int outpos = 0;
197             for (int i = 0; i < maxStrLen; i++)
198             {
199                 long pval = powersOf36[maxStrLen - i - 1];
200                 int pos = (int)(curval / pval);
201                 tb[outpos++] = digits.Substring(pos, 1).ToCharArray()[0];
202                 curval = curval % pval;
203             }
204             if (outpos == 0)
205                 tb[outpos++] = '0';
206             return new System.String(tb, 0, outpos).TrimStart('0');
207         }
208
209         public static long ToLong(System.String t)
210         {
211             long ival = 0;
212             char[] tb = t.ToCharArray();
213             for (int i = 0; i < tb.Length; i++)
214             {
215                 ival += powersOf36[i] * digits.IndexOf(tb[tb.Length - i - 1]);
216             }
217             return ival;
218         }
219         #endregion
220 #endif
221         }
222 }