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