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