OSDN Git Service

* java/text/SimpleDateFormat.java: Re-merged with Classpath.
[pf3gnuchains/gcc-fork.git] / libjava / gnu / java / text / CharacterBreakIterator.java
1 /* CharacterBreakIterator.java - Default character BreakIterator.
2    Copyright (C) 1999, 2001 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10  
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 As a special exception, if you link this library with other files to
22 produce an executable, this library does not by itself cause the
23 resulting executable to be covered by the GNU General Public License.
24 This exception does not however invalidate any other reasons why the
25 executable file might be covered by the GNU General Public License. */
26
27
28 package gnu.java.text;
29
30 import java.text.BreakIterator;
31 import java.text.CharacterIterator;
32
33 /**
34  * @author Tom Tromey <tromey@cygnus.com>
35  * @date March 19, 1999
36  * Written using The Unicode Standard, Version 2.0.
37  */
38
39 public class CharacterBreakIterator extends BaseBreakIterator
40 {
41   // Hangul Jamo constants from Unicode book.
42   private static final int LBase = 0x1100;
43   private static final int VBase = 0x1161;
44   private static final int TBase = 0x11a7;
45   private static final int LCount = 19;
46   private static final int VCount = 21;
47   private static final int TCount = 28;
48
49   // Information about surrogates.
50   private static final int highSurrogateStart = 0xD800;
51   private static final int highSurrogateEnd = 0xDBFF;
52   private static final int lowSurrogateStart = 0xDC00;
53   private static final int lowSurrogateEnd = 0xDFFF;
54
55   public Object clone ()
56   {
57     return new CharacterBreakIterator (this);
58   }
59
60   public CharacterBreakIterator ()
61   {
62     iter = null;                // FIXME?
63   }
64
65   private CharacterBreakIterator (CharacterBreakIterator other)
66   {
67     iter = (CharacterIterator) other.iter.clone();
68   }
69
70   // Some methods to tell us different properties of characters.
71   private final boolean isL (char c)
72   {
73     return c >= LBase && c <= LBase + LCount;
74   }
75   private final boolean isV (char c)
76   {
77     return c >= VBase && c <= VBase + VCount;
78   }
79   private final boolean isT (char c)
80   {
81     return c >= TBase && c <= TBase + TCount;
82   }
83   private final boolean isLVT (char c)
84   {
85     return isL (c) || isV (c) || isT (c);
86   }
87   private final boolean isHighSurrogate (char c)
88   {
89     return c >= highSurrogateStart && c <= highSurrogateEnd;
90   }
91   private final boolean isLowSurrogate (char c)
92   {
93     return c >= lowSurrogateStart && c <= lowSurrogateEnd;
94   }
95
96   public int next ()
97   {
98     int end = iter.getEndIndex();
99     if (iter.getIndex() == end)
100       return DONE;
101
102     char c;
103     for (char prev = CharacterIterator.DONE; iter.getIndex() < end; prev = c)
104       {
105         c = iter.next();
106         if (c == CharacterIterator.DONE)
107           break;
108         int type = Character.getType(c);
109
110         // Break after paragraph separators.
111         if (type == Character.PARAGRAPH_SEPARATOR)
112           break;
113
114         // Now we need some lookahead.
115         char ahead = iter.next();
116         iter.previous();
117         if (ahead == CharacterIterator.DONE)
118           break;
119         int aheadType = Character.getType(ahead);
120
121         if (aheadType != Character.NON_SPACING_MARK
122             && ! isLowSurrogate (ahead)
123             && ! isLVT (ahead))
124           break;
125         if (! isLVT (c) && isLVT (ahead))
126           break;
127         if (isL (c) && ! isLVT (ahead)
128             && aheadType != Character.NON_SPACING_MARK)
129           break;
130         if (isV (c) && ! isV (ahead) && !isT (ahead)
131             && aheadType != Character.NON_SPACING_MARK)
132           break;
133         if (isT (c) && ! isT (ahead)
134             && aheadType != Character.NON_SPACING_MARK)
135           break;
136
137         if (! isHighSurrogate (c) && isLowSurrogate (ahead))
138           break;
139         if (isHighSurrogate (c) && ! isLowSurrogate (ahead))
140           break;
141         if (! isHighSurrogate (prev) && isLowSurrogate (c))
142           break;
143       }
144
145     return iter.getIndex();
146   }
147
148   public int previous ()
149   {
150     if (iter.getIndex() == iter.getBeginIndex())
151       return DONE;
152
153     int start = iter.getBeginIndex();
154     while (iter.getIndex() >= iter.getBeginIndex())
155       {
156         char c = iter.previous();
157         if (c == CharacterIterator.DONE)
158           break;
159         int type = Character.getType(c);
160
161         if (type != Character.NON_SPACING_MARK
162             && ! isLowSurrogate (c)
163             && ! isLVT (c))
164           break;
165
166         // Now we need some lookahead.
167         char ahead = iter.previous();
168         if (ahead == CharacterIterator.DONE)
169           {
170             iter.next();
171             break;
172           }
173         char ahead2 = iter.previous();
174         iter.next();
175         iter.next();
176         if (ahead2 == CharacterIterator.DONE)
177           break;
178         int aheadType = Character.getType(ahead);
179
180         if (aheadType == Character.PARAGRAPH_SEPARATOR)
181           break;
182
183         if (isLVT (c) && ! isLVT (ahead))
184           break;
185         if (! isLVT (c) && type != Character.NON_SPACING_MARK
186             && isL (ahead))
187           break;
188         if (! isV (c) && ! isT (c) && type != Character.NON_SPACING_MARK
189             && isV (ahead))
190           break;
191         if (! isT (c) && type != Character.NON_SPACING_MARK
192             && isT (ahead))
193           break;
194
195         if (isLowSurrogate (c) && ! isHighSurrogate (ahead))
196           break;
197         if (! isLowSurrogate (c) && isHighSurrogate (ahead))
198           break;
199         if (isLowSurrogate (ahead) && ! isHighSurrogate (ahead2))
200           break;
201       }
202
203     return iter.getIndex();
204   }
205 }