2005-07-20 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / corlib / Mono.Globalization.Unicode / managed-collation.patch
1 Index: corlib.dll.sources
2 ===================================================================
3 --- corlib.dll.sources  (revision 47350)
4 +++ corlib.dll.sources  (working copy)
5 @@ -8,6 +8,12 @@
6  Microsoft.Win32/Win32RegistryApi.cs
7  Microsoft.Win32/Win32ResultCode.cs
8  Microsoft.Win32.SafeHandles/SafeFileHandle.cs
9 +Mono.Globalization.Unicode/CodePointIndexer.cs
10 +Mono.Globalization.Unicode/MSCompatUnicodeTable.cs
11 +Mono.Globalization.Unicode/MSCompatUnicodeTableUtil.cs
12 +Mono.Globalization.Unicode/SimpleCollator.cs
13 +Mono.Globalization.Unicode/SortKey.cs
14 +Mono.Globalization.Unicode/SortKeyBuffer.cs
15  Mono/Runtime.cs
16  Mono.Math/BigInteger.cs
17  Mono.Math.Prime/ConfidenceFactor.cs
18 @@ -300,7 +306,6 @@
19  System.Globalization/NumberFormatInfo.cs
20  System.Globalization/NumberStyles.cs
21  System.Globalization/RegionInfo.cs
22 -System.Globalization/SortKey.cs
23  System.Globalization/StringInfo.cs
24  System.Globalization/TaiwanCalendar.cs
25  System.Globalization/TextElementEnumerator.cs
26 Index: Makefile
27 ===================================================================
28 --- Makefile    (revision 47350)
29 +++ Makefile    (working copy)
30 @@ -3,13 +3,24 @@
31  include ../../build/rules.make
32  export __SECURITY_BOOTSTRAP_DB=$(topdir)/class/corlib
33  
34 +
35 +RESOURCE_FILES = \
36 +       collation.core.bin \
37 +       collation.tailoring.bin \
38 +       collation.cjkCHS.bin \
39 +       collation.cjkCHT.bin \
40 +       collation.cjkJA.bin \
41 +       collation.cjkKO.bin \
42 +       collation.cjkKOlv2.bin
43 +
44  # corlib is crazy to build so we skip build/library.make and do stuff
45  # ourselves.
46  #
47  # Here, we define a bunch of variables.
48  
49  corlib_flags = /unsafe /nostdlib
50 -LOCAL_MCS_FLAGS = /nowarn:649 /nowarn:169 /nowarn:414 -nowarn:612 -nowarn:618 -d:INSIDE_CORLIB
51 +LOCAL_MCS_FLAGS = /nowarn:649 /nowarn:169 /nowarn:414 -nowarn:612 -nowarn:618 -d:INSIDE_CORLIB \
52 +       $(RESOURCE_FILES:%=/resource:%)
53  
54  LIBRARY = corlib.dll
55  LIBRARY_NAME = mscorlib.dll
56 Index: System/String.cs
57 ===================================================================
58 --- System/String.cs    (revision 47350)
59 +++ System/String.cs    (working copy)
60 @@ -746,7 +746,7 @@
61                         if (this.length < value.length)
62                                 return false;
63  
64 -                       return (0 == Compare (this, 0, value, 0 , value.length));
65 +                       return CultureInfo.CurrentCulture.CompareInfo.IsPrefix (this, value);
66                 }
67  
68                 /* This method is culture insensitive */
69 Index: System.Globalization/CompareInfo.cs
70 ===================================================================
71 --- System.Globalization/CompareInfo.cs (revision 47350)
72 +++ System.Globalization/CompareInfo.cs (working copy)
73 @@ -34,12 +34,25 @@
74  using System.Reflection;
75  using System.Runtime.Serialization;
76  using System.Runtime.CompilerServices;
77 +using Mono.Globalization.Unicode;
78  
79  namespace System.Globalization
80  {
81         [Serializable]
82         public class CompareInfo : IDeserializationCallback
83         {
84 +               static readonly bool useManagedCollation =
85 +                       Environment.GetEnvironmentVariable ("MONO_USE_MANAGED_COLLATION")
86 +                       == "yes";
87 +
88 +               public static bool UseManagedCollation {
89 +                       get {
90 +                               if (!useManagedCollation)
91 +                                       return false;
92 +                               return MSCompatUnicodeTable.IsReady;
93 +                       }
94 +               }
95 +
96                 // Keep in synch with MonoCompareInfo in the runtime. 
97                 private int culture;
98                 [NonSerialized]
99 @@ -47,6 +60,9 @@
100                 [NonSerialized]
101                 private IntPtr ICU_collator;
102                 private int win32LCID;  // Unused, but MS.NET serializes this
103 +
104 +               [NonSerialized]
105 +               SimpleCollator collator;
106                 
107                 /* Hide the .ctor() */
108                 CompareInfo() {}
109 @@ -57,39 +73,59 @@
110                 internal CompareInfo (CultureInfo ci)
111                 {
112                         this.culture = ci.LCID;
113 -                       this.icu_name = ci.IcuName;
114 -                       this.construct_compareinfo (icu_name);
115 +                       if (UseManagedCollation) 
116 +                               collator = new SimpleCollator (ci);
117 +                       else {
118 +                               this.icu_name = ci.IcuName;
119 +                               this.construct_compareinfo (icu_name);
120 +                       }
121                 }
122                 
123                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
124                 private extern void free_internal_collator ();
125 -               
126 +
127                 ~CompareInfo ()
128                 {
129 -                       free_internal_collator ();
130 +                       if (UseManagedCollation)
131 +                               collator = null;
132 +                       else
133 +                               free_internal_collator ();
134                 }
135 -               
136 -               
137 +
138                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
139                 private extern int internal_compare (string str1, int offset1,
140                                                      int length1, string str2,
141                                                      int offset2, int length2,
142                                                      CompareOptions options);
143  
144 +               private int internal_compare_managed (string str1, int offset1,
145 +                                               int length1, string str2,
146 +                                               int offset2, int length2,
147 +                                               CompareOptions options)
148 +               {
149 +                       return collator.Compare (str1, offset1, length1,
150 +                               str2, offset2, length2, options);
151 +               }
152 +
153 +               private int internal_compare_switch (string str1, int offset1,
154 +                                               int length1, string str2,
155 +                                               int offset2, int length2,
156 +                                               CompareOptions options)
157 +               {
158 +                       return UseManagedCollation ?
159 +                               internal_compare_managed (str1, offset1, length1,
160 +                               str2, offset2, length2, options) :
161 +                               internal_compare (str1, offset1, length1,
162 +                               str2, offset2, length2, options);
163 +               }
164 +
165                 public virtual int Compare (string string1, string string2)
166                 {
167 -                       /* Short cuts... */
168 -                       if(string1.Length == 0) {
169 -                               if(string2.Length == 0) {
170 -                                       return(0);
171 -                               } else {
172 -                                       return(-1);
173 -                               }
174 -                       } else if(string2.Length == 0) {
175 -                               return(1);
176 -                       }
177 +                       /* Short cut... */
178 +                       if(string1.Length == 0 && string2.Length == 0)
179 +                               return(0);
180  
181 -                       return(internal_compare (string1, 0, string1.Length,
182 +                       return(internal_compare_switch (string1, 0, string1.Length,
183                                                  string2, 0, string2.Length,
184                                                  CompareOptions.None));
185                 }
186 @@ -97,18 +133,11 @@
187                 public virtual int Compare (string string1, string string2,
188                                             CompareOptions options)
189                 {
190 -                       /* Short cuts... */
191 -                       if(string1.Length == 0) {
192 -                               if(string2.Length == 0) {
193 -                                       return(0);
194 -                               } else {
195 -                                       return(-1);
196 -                               }
197 -                       } else if(string2.Length == 0) {
198 -                               return(1);
199 -                       }
200 +                       /* Short cut... */
201 +                       if(string1.Length == 0 && string2.Length == 0)
202 +                               return(0);
203  
204 -                       return(internal_compare (string1, 0, string1.Length,
205 +                       return(internal_compare_switch (string1, 0, string1.Length,
206                                                  string2, 0, string2.Length,
207                                                  options));
208                 }
209 @@ -121,18 +150,9 @@
210                          * the offset >= string length specified check
211                          * in the process...)
212                          */
213 -                       if(string1.Length == 0 ||
214 -                          offset1 == string1.Length) {
215 -                               if(string2.Length == 0 ||
216 -                                  offset2 == string2.Length) {
217 -                                       return(0);
218 -                               } else {
219 -                                       return(-1);
220 -                               }
221 -                       } else if(string2.Length == 0 ||
222 -                                 offset2 == string2.Length) {
223 -                               return(1);
224 -                       }
225 +                       if ((string1.Length == 0 || offset1 == string1.Length) &&
226 +                               (string2.Length == 0 || offset2 == string2.Length))
227 +                               return(0);
228  
229                         if(offset1 < 0 || offset2 < 0) {
230                                 throw new ArgumentOutOfRangeException ("Offsets must not be less than zero");
231 @@ -146,7 +166,7 @@
232                                 throw new ArgumentOutOfRangeException ("Offset2 is greater than or equal to the length of string2");
233                         }
234                         
235 -                       return(internal_compare (string1, offset1,
236 +                       return(internal_compare_switch (string1, offset1,
237                                                  string1.Length-offset1,
238                                                  string2, offset2,
239                                                  string2.Length-offset2,
240 @@ -162,18 +182,9 @@
241                          * the offset >= string length specified check
242                          * in the process...)
243                          */
244 -                       if(string1.Length == 0 ||
245 -                          offset1 == string1.Length) {
246 -                               if(string2.Length == 0 ||
247 -                                  offset2 == string2.Length) {
248 -                                       return(0);
249 -                               } else {
250 -                                       return(-1);
251 -                               }
252 -                       } else if(string2.Length == 0 ||
253 -                                 offset2 == string2.Length) {
254 -                               return(1);
255 -                       }
256 +                       if((string1.Length == 0 || offset1 == string1.Length) &&
257 +                               (string2.Length == 0 || offset2 == string2.Length))
258 +                               return(0);
259  
260                         if(offset1 < 0 || offset2 < 0) {
261                                 throw new ArgumentOutOfRangeException ("Offsets must not be less than zero");
262 @@ -187,7 +198,7 @@
263                                 throw new ArgumentOutOfRangeException ("Offset2 is greater than or equal to the length of string2");
264                         }
265                         
266 -                       return(internal_compare (string1, offset1,
267 +                       return(internal_compare_switch (string1, offset1,
268                                                  string1.Length-offset1,
269                                                  string2, offset2,
270                                                  string2.Length-offset1,
271 @@ -203,21 +214,13 @@
272                          * the offset >= string length specified check
273                          * in the process...)
274                          */
275 -                       if(string1.Length == 0 ||
276 -                          offset1 == string1.Length ||
277 -                          length1 == 0) {
278 -                               if(string2.Length == 0 ||
279 -                                  offset2 == string2.Length ||
280 -                                  length2 == 0) {
281 -                                       return(0);
282 -                               } else {
283 -                                       return(-1);
284 -                               }
285 -                       } else if(string2.Length == 0 ||
286 -                                 offset2 == string2.Length ||
287 -                                 length2 == 0) {
288 -                               return(1);
289 -                       }
290 +                       if((string1.Length == 0 ||
291 +                               offset1 == string1.Length ||
292 +                               length1 == 0) &&
293 +                               (string2.Length == 0 ||
294 +                               offset2 == string2.Length ||
295 +                               length2 == 0))
296 +                               return(0);
297  
298                         if(offset1 < 0 || length1 < 0 ||
299                            offset2 < 0 || length2 < 0) {
300 @@ -240,7 +243,7 @@
301                                 throw new ArgumentOutOfRangeException ("Length2 is greater than the number of characters from offset2 to the end of string2");
302                         }
303                         
304 -                       return(internal_compare (string1, offset1, length1,
305 +                       return(internal_compare_switch (string1, offset1, length1,
306                                                  string2, offset2, length2,
307                                                  CompareOptions.None));
308                 }
309 @@ -255,21 +258,13 @@
310                          * the offset >= string length specified check
311                          * in the process...)
312                          */
313 -                       if(string1.Length == 0 ||
314 -                          offset1 == string1.Length ||
315 -                          length1 == 0) {
316 -                               if(string2.Length == 0 ||
317 -                                  offset2 == string2.Length ||
318 -                                  length2 == 0) {
319 +                       if((string1.Length == 0 ||
320 +                               offset1 == string1.Length ||
321 +                               length1 == 0) &&
322 +                               (string2.Length == 0 ||
323 +                               offset2 == string2.Length ||
324 +                               length2 == 0))
325                                         return(0);
326 -                               } else {
327 -                                       return(-1);
328 -                               }
329 -                       } else if(string2.Length == 0 ||
330 -                                 offset2 == string2.Length ||
331 -                                 length2 == 0) {
332 -                               return(1);
333 -                       }
334  
335                         if(offset1 < 0 || length1 < 0 ||
336                            offset2 < 0 || length2 < 0) {
337 @@ -292,7 +287,7 @@
338                                 throw new ArgumentOutOfRangeException ("Length2 is greater than the number of characters from offset2 to the end of string2");
339                         }
340                         
341 -                       return(internal_compare (string1, offset1, length1,
342 +                       return(internal_compare_switch (string1, offset1, length1,
343                                                  string2, offset2, length2,
344                                                  options));
345                 }
346 @@ -372,6 +367,8 @@
347                 public virtual SortKey GetSortKey(string source,
348                                                   CompareOptions options)
349                 {
350 +                       if (UseManagedCollation)
351 +                               return collator.GetSortKey (source, options);
352                         SortKey key=new SortKey (culture, source, options);
353  
354                         /* Need to do the icall here instead of in the
355 @@ -460,7 +457,26 @@
356                                                    int count, char value,
357                                                    CompareOptions options,
358                                                    bool first);
359 -               
360 +
361 +               private int internal_index_managed (string s, int sindex,
362 +                       int count, char c, CompareOptions opt,
363 +                       bool first)
364 +               {
365 +                       return first ?
366 +                               collator.IndexOf (s, c, sindex, count, opt) :
367 +                               collator.LastIndexOf (s, c, sindex, count, opt);
368 +               }
369 +
370 +               private int internal_index_switch (string s, int sindex,
371 +                       int count, char c, CompareOptions opt,
372 +                       bool first)
373 +               {
374 +                       return UseManagedCollation &&
375 +                               (CompareOptions.Ordinal & opt) == 0 ?
376 +                               internal_index_managed (s, sindex, count, c, opt, first) :
377 +                               internal_index (s, sindex, count, c, opt, first);
378 +               }
379 +
380                 public virtual int IndexOf (string source, char value,
381                                             int startIndex, int count,
382                                             CompareOptions options)
383 @@ -492,7 +508,7 @@
384                                 }
385                                 return(-1);
386                         } else {
387 -                               return (internal_index (source, startIndex,
388 +                               return (internal_index_switch (source, startIndex,
389                                                         count, value, options,
390                                                         true));
391                         }
392 @@ -503,7 +519,26 @@
393                                                    int count, string value,
394                                                    CompareOptions options,
395                                                    bool first);
396 -               
397 +
398 +               private int internal_index_managed (string s1, int sindex,
399 +                       int count, string s2, CompareOptions opt,
400 +                       bool first)
401 +               {
402 +                       return first ?
403 +                               collator.IndexOf (s1, s2, sindex, count, opt) :
404 +                               collator.LastIndexOf (s1, s2, sindex, count, opt);
405 +               }
406 +
407 +               private int internal_index_switch (string s1, int sindex,
408 +                       int count, string s2, CompareOptions opt,
409 +                       bool first)
410 +               {
411 +                       return UseManagedCollation &&
412 +                               (CompareOptions.Ordinal & opt) == 0 ?
413 +                               internal_index_managed (s1, sindex, count, s2, opt, first) :
414 +                               internal_index (s1, sindex, count, s2, opt, first);
415 +               }
416 +
417                 public virtual int IndexOf (string source, string value,
418                                             int startIndex, int count,
419                                             CompareOptions options)
420 @@ -524,7 +559,7 @@
421                                 return(-1);
422                         }
423  
424 -                       return (internal_index (source, startIndex, count,
425 +                       return (internal_index_switch (source, startIndex, count,
426                                                 value, options, true));
427                 }
428  
429 @@ -543,6 +578,9 @@
430                                 throw new ArgumentNullException("prefix");
431                         }
432  
433 +                       if (UseManagedCollation)
434 +                               return collator.IsPrefix (source, prefix, options);
435 +
436                         if(source.Length < prefix.Length) {
437                                 return(false);
438                         } else {
439 @@ -567,6 +605,9 @@
440                                 throw new ArgumentNullException("suffix");
441                         }
442  
443 +                       if (UseManagedCollation)
444 +                               return collator.IsSuffix (source, suffix, options);
445 +
446                         if(source.Length < suffix.Length) {
447                                 return(false);
448                         } else {
449 @@ -682,7 +723,7 @@
450                                 }
451                                 return(-1);
452                         } else {
453 -                               return (internal_index (source, startIndex,
454 +                               return (internal_index_switch (source, startIndex,
455                                                         count, value, options,
456                                                         false));
457                         }
458 @@ -713,7 +754,7 @@
459                                 return(0);
460                         }
461  
462 -                       return(internal_index (source, startIndex, count,
463 +                       return(internal_index_switch (source, startIndex, count,
464                                                value, options, false));
465                 }
466  
467 @@ -724,13 +765,17 @@
468  
469                 void IDeserializationCallback.OnDeserialization(object sender)
470                 {
471 -                       /* This will build the ICU collator, and store
472 -                        * the pointer in ICU_collator
473 -                        */
474 -                       try {
475 -                               this.construct_compareinfo (icu_name);
476 -                       } catch {
477 -                               ICU_collator=IntPtr.Zero;
478 +                       if (UseManagedCollation) {
479 +                               collator = new SimpleCollator (new CultureInfo (culture));
480 +                       } else {
481 +                               /* This will build the ICU collator, and store
482 +                                * the pointer in ICU_collator
483 +                                */
484 +                               try {
485 +                                       this.construct_compareinfo (icu_name);
486 +                               } catch {
487 +                                       ICU_collator=IntPtr.Zero;
488 +                               }
489                         }
490                 }
491