2004-04-30 Dick Porter <dick@ximian.com>
[mono.git] / mcs / class / corlib / System.Globalization / StringInfo.cs
1 //
2 // System.Globalization.StringInfo.cs
3 //
4 // Author:
5 //      Dick Porter (dick@ximian.com)
6 //
7 // (C) 2002 Ximian, Inc.
8 // (C) 2004 Novell, Inc.
9 //
10
11 using System.Collections;
12
13 namespace System.Globalization {
14
15         [Serializable]
16         public class StringInfo {
17                 public StringInfo()
18                 {
19                 }
20
21                 public static string GetNextTextElement(string str)
22                 {
23                         if(str == null || str.Length == 0) {
24                                 throw new ArgumentNullException("string is null");
25                         }
26                         return(GetNextTextElement (str, 0));
27                 }
28
29                 public static string GetNextTextElement(string str, int index)
30                 {
31                         if(str == null) {
32                                 throw new ArgumentNullException("string is null");
33                         }
34
35                         if(index < 0 || index >= str.Length) {
36                                 throw new ArgumentOutOfRangeException ("Index is not valid");
37                         }
38
39                         /* Find the next base character, surrogate
40                          * pair or combining character sequence
41                          */
42
43                         char ch = str[index];
44                         UnicodeCategory cat = char.GetUnicodeCategory (ch);
45
46                         if (cat == UnicodeCategory.Surrogate) {
47                                 /* Check that it's a high surrogate
48                                  * followed by a low surrogate
49                                  */
50                                 if (ch >= 0xD800 && ch <= 0xDBFF) {
51                                         if ((index + 1) < str.Length &&
52                                             str[index + 1] >= 0xDC00 &&
53                                             str[index + 1] <= 0xDFFF) {
54                                                 /* A valid surrogate pair */
55                                                 return(str.Substring (index, 2));
56                                         } else {
57                                                 /* High surrogate on its own */
58                                                 return(new String (ch, 1));
59                                         }
60                                 } else {
61                                         /* Low surrogate on its own */
62                                         return(new String (ch, 1));
63                                 }
64                         } else {
65                                 /* Look for a base character, which
66                                  * may or may not be followed by a
67                                  * series of combining characters
68                                  */
69
70                                 if (cat == UnicodeCategory.NonSpacingMark ||
71                                     cat == UnicodeCategory.SpacingCombiningMark ||
72                                     cat == UnicodeCategory.EnclosingMark) {
73                                         /* Not a base character */
74                                         return(new String (ch, 1));
75                                 }
76                                 
77                                 int count = 1;
78
79                                 while (index + count < str.Length) {
80                                         cat = char.GetUnicodeCategory (str[index + count]);
81                                         if (cat != UnicodeCategory.NonSpacingMark &&
82                                             cat != UnicodeCategory.SpacingCombiningMark &&
83                                             cat != UnicodeCategory.EnclosingMark) {
84                                                 /* Finished the sequence */
85                                                 break;
86                                         }
87                                         count++;
88                                 }
89
90                                 return(str.Substring (index, count));
91                         }
92                 }
93
94                 public static TextElementEnumerator GetTextElementEnumerator(string str)
95                 {
96                         if(str == null || str.Length == 0) {
97                                 throw new ArgumentNullException("string is null");
98                         }
99                         return(new TextElementEnumerator (str, 0));
100                 }
101
102                 public static TextElementEnumerator GetTextElementEnumerator(string str, int index)
103                 {
104                         if(str == null) {
105                                 throw new ArgumentNullException("string is null");
106                         }
107
108                         if(index < 0 || index >= str.Length) {
109                                 throw new ArgumentOutOfRangeException ("Index is not valid");
110                         }
111                         
112                         return(new TextElementEnumerator (str, index));
113                 }
114                 
115                 public static int[] ParseCombiningCharacters(string str)
116                 {
117                         if(str == null) {
118                                 throw new ArgumentNullException("string is null");
119                         }
120
121                         ArrayList indices = new ArrayList (str.Length);
122                         TextElementEnumerator tee = GetTextElementEnumerator (str);
123
124                         tee.Reset ();
125                         while(tee.MoveNext ()) {
126                                 indices.Add (tee.ElementIndex);
127                         }
128
129                         return((int[])indices.ToArray (typeof (int)));
130                 }
131         }
132 }