001: /***
002: * Retrotranslator: a Java bytecode transformer that translates Java classes
003: * compiled with JDK 5.0 into classes that can be run on JVM 1.4.
004: *
005: * Copyright (c) 2005 - 2008 Taras Puchko
006: * All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: * 3. Neither the name of the copyright holders nor the names of its
017: * contributors may be used to endorse or promote products derived from
018: * this software without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
021: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
022: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
023: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
024: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
025: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
026: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
027: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
028: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
029: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
030: * THE POSSIBILITY OF SUCH DAMAGE.
031: */package net.sf.retrotranslator.runtime.java.lang;
032:
033: /**
034: * @author Taras Puchko
035: */
036: public class _Character {
037:
038: private static final int SURROGATE_MASK = 0x3FF;
039: private static final Character[] cache = new Character[128];
040:
041: static {
042: for (int i = 0; i < cache.length; i++) {
043: cache[i] = new Character((char) i);
044: }
045: }
046:
047: public static int charCount(int codePoint) {
048: return codePoint < Character.MIN_SUPPLEMENTARY_CODE_POINT ? 1
049: : 2;
050: }
051:
052: public static int codePointAt(char[] chars, int index) {
053: return codePointAt(chars, index, chars.length);
054: }
055:
056: public static int codePointAt(char[] chars, int index, int limit) {
057: if (index >= limit || limit < 0 || limit > chars.length) {
058: throw new IndexOutOfBoundsException();
059: }
060: char highChar = chars[index];
061: if (isHighSurrogate(highChar) && ++index < limit) {
062: char lowChar = chars[index];
063: if (isLowSurrogate(lowChar)) {
064: return toCodePoint(highChar, lowChar);
065: }
066: }
067: return highChar;
068: }
069:
070: public static int codePointAt(CharSequence sequence, int index) {
071: char highChar = sequence.charAt(index);
072: if (isHighSurrogate(highChar) && ++index < sequence.length()) {
073: char lowChar = sequence.charAt(index);
074: if (isLowSurrogate(lowChar)) {
075: return toCodePoint(highChar, lowChar);
076: }
077: }
078: return highChar;
079: }
080:
081: public static int codePointBefore(char[] chars, int index) {
082: return codePointBefore(chars, index, 0);
083: }
084:
085: public static int codePointBefore(char[] chars, int index, int start) {
086: if (index <= start || start < 0 || start >= chars.length) {
087: throw new IndexOutOfBoundsException();
088: }
089: char lowChar = chars[--index];
090: if (isLowSurrogate(lowChar) && index > start) {
091: char highChar = chars[index - 1];
092: if (isHighSurrogate(highChar)) {
093: return toCodePoint(highChar, lowChar);
094: }
095: }
096: return lowChar;
097: }
098:
099: public static int codePointBefore(CharSequence sequence, int index) {
100: char lowChar = sequence.charAt(--index);
101: if (isLowSurrogate(lowChar) && index > 0) {
102: char highChar = sequence.charAt(index - 1);
103: if (isHighSurrogate(highChar)) {
104: return toCodePoint(highChar, lowChar);
105: }
106: }
107: return lowChar;
108: }
109:
110: public static int codePointCount(char[] chars, int offset, int count) {
111: int endIndex = offset + count;
112: if (offset < 0 || offset > endIndex || endIndex > chars.length) {
113: throw new IndexOutOfBoundsException();
114: }
115: int result = 0;
116: for (int i = offset; i < endIndex; result++) {
117: if (isHighSurrogate(chars[i++]) && i < endIndex
118: && isLowSurrogate(chars[i])) {
119: i++;
120: }
121: }
122: return result;
123: }
124:
125: public static int codePointCount(CharSequence sequence,
126: int beginIndex, int endIndex) {
127: if (beginIndex < 0 || beginIndex > endIndex
128: || endIndex > sequence.length()) {
129: throw new IndexOutOfBoundsException();
130: }
131: int result = 0;
132: for (int i = beginIndex; i < endIndex; result++) {
133: if (isHighSurrogate(sequence.charAt(i++)) && i < endIndex
134: && isLowSurrogate(sequence.charAt(i))) {
135: i++;
136: }
137: }
138: return result;
139: }
140:
141: public static int digit(int codePoint, int radix) {
142: return isBasic(codePoint) ? Character.digit((char) codePoint,
143: radix) : -1;
144: }
145:
146: public static byte getDirectionality(int codePoint) {
147: return isBasic(codePoint) ? Character
148: .getDirectionality((char) codePoint)
149: : Character.DIRECTIONALITY_UNDEFINED;
150: }
151:
152: public static int getNumericValue(int codePoint) {
153: return isBasic(codePoint) ? Character
154: .getNumericValue((char) codePoint) : -1;
155: }
156:
157: public static int getType(int codePoint) {
158: return isBasic(codePoint) ? Character.getType((char) codePoint)
159: : Character.UNASSIGNED;
160: }
161:
162: public static boolean isDefined(int codePoint) {
163: return isBasic(codePoint)
164: && Character.isDefined((char) codePoint);
165: }
166:
167: public static boolean isDigit(int codePoint) {
168: return isBasic(codePoint)
169: && Character.isDigit((char) codePoint);
170: }
171:
172: public static boolean isHighSurrogate(char aChar) {
173: return aChar >= Character.MIN_HIGH_SURROGATE
174: && aChar <= Character.MAX_HIGH_SURROGATE;
175: }
176:
177: public static boolean isIdentifierIgnorable(int codePoint) {
178: return isBasic(codePoint)
179: && Character.isIdentifierIgnorable((char) codePoint);
180: }
181:
182: public static boolean isISOControl(int codePoint) {
183: return isBasic(codePoint)
184: && Character.isISOControl((char) codePoint);
185: }
186:
187: public static boolean isJavaIdentifierPart(int codePoint) {
188: return isBasic(codePoint)
189: && Character.isJavaIdentifierPart((char) codePoint);
190: }
191:
192: public static boolean isJavaIdentifierStart(int codePoint) {
193: return isBasic(codePoint)
194: && Character.isJavaIdentifierStart((char) codePoint);
195: }
196:
197: public static boolean isLetter(int codePoint) {
198: return isBasic(codePoint)
199: && Character.isLetter((char) codePoint);
200: }
201:
202: public static boolean isLetterOrDigit(int codePoint) {
203: return isBasic(codePoint)
204: && Character.isLetterOrDigit((char) codePoint);
205: }
206:
207: public static boolean isLowerCase(int codePoint) {
208: return isBasic(codePoint)
209: && Character.isLowerCase((char) codePoint);
210: }
211:
212: public static boolean isLowSurrogate(char aChar) {
213: return aChar >= Character.MIN_LOW_SURROGATE
214: && aChar <= Character.MAX_LOW_SURROGATE;
215: }
216:
217: public static boolean isMirrored(int codePoint) {
218: return isBasic(codePoint)
219: && Character.isMirrored((char) codePoint);
220: }
221:
222: public static boolean isSpaceChar(int codePoint) {
223: return isBasic(codePoint)
224: && Character.isSpaceChar((char) codePoint);
225: }
226:
227: public static boolean isSupplementaryCodePoint(int codePoint) {
228: return codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT
229: && codePoint <= Character.MAX_CODE_POINT;
230: }
231:
232: public static boolean isSurrogatePair(char highChar, char lowChar) {
233: return isHighSurrogate(highChar) && isLowSurrogate(lowChar);
234: }
235:
236: public static boolean isTitleCase(int codePoint) {
237: return isBasic(codePoint)
238: && Character.isTitleCase((char) codePoint);
239: }
240:
241: public static boolean isUnicodeIdentifierPart(int codePoint) {
242: return isBasic(codePoint)
243: && Character.isUnicodeIdentifierPart((char) codePoint);
244: }
245:
246: public static boolean isUnicodeIdentifierStart(int codePoint) {
247: return isBasic(codePoint)
248: && Character.isUnicodeIdentifierStart((char) codePoint);
249: }
250:
251: public static boolean isUpperCase(int codePoint) {
252: return isBasic(codePoint)
253: && Character.isUpperCase((char) codePoint);
254: }
255:
256: public static boolean isValidCodePoint(int codePoint) {
257: return codePoint >= Character.MIN_CODE_POINT
258: && codePoint <= Character.MAX_CODE_POINT;
259: }
260:
261: public static boolean isWhitespace(int codePoint) {
262: return isBasic(codePoint)
263: && Character.isWhitespace((char) codePoint);
264: }
265:
266: public static int offsetByCodePoints(char[] chars, int start,
267: int count, int index, int codePointOffset) {
268: int endIndex = start + count;
269: if (start < 0 || start > endIndex || endIndex > chars.length
270: || index < start || index > endIndex) {
271: throw new IndexOutOfBoundsException();
272: }
273: if (codePointOffset >= 0) {
274: for (int i = 0; i < codePointOffset; i++) {
275: if (index >= endIndex) {
276: throw new IndexOutOfBoundsException();
277: }
278: if (isHighSurrogate(chars[index++]) && index < endIndex
279: && isLowSurrogate(chars[index])) {
280: index++;
281: }
282: }
283: } else {
284: for (int i = codePointOffset; i < 0; i++) {
285: if (index <= start) {
286: throw new IndexOutOfBoundsException();
287: }
288: if (isLowSurrogate(chars[--index]) && index > start
289: && isHighSurrogate(chars[index - 1])) {
290: index--;
291: }
292: }
293: }
294: return index;
295: }
296:
297: public static int offsetByCodePoints(CharSequence sequence,
298: int index, int codePointOffset) {
299: if (index < 0 || index > sequence.length()) {
300: throw new IndexOutOfBoundsException();
301: }
302: if (codePointOffset >= 0) {
303: for (int i = 0; i < codePointOffset; i++) {
304: if (isHighSurrogate(sequence.charAt(index++))
305: && index < sequence.length()
306: && isLowSurrogate(sequence.charAt(index))) {
307: index++;
308: }
309: }
310: } else {
311: for (int i = codePointOffset; i < 0; i++) {
312: if (isLowSurrogate(sequence.charAt(--index))
313: && index > 0
314: && isHighSurrogate(sequence.charAt(index - 1))) {
315: index--;
316: }
317: }
318: }
319: return index;
320: }
321:
322: public static char reverseBytes(char ch) {
323: return (char) (ch >> 8 & 0xFF | ch << 8);
324: }
325:
326: public static char[] toChars(int codePoint) {
327: char[] chars = new char[charCount(codePoint)];
328: toChars(codePoint, chars, 0);
329: return chars;
330: }
331:
332: public static int toChars(int codePoint, char[] chars, int index) {
333: if (!isValidCodePoint(codePoint)) {
334: throw new IllegalArgumentException();
335: }
336: if (codePoint < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
337: chars[index] = (char) codePoint;
338: return 1;
339: } else {
340: chars[index] = (char) (((codePoint - Character.MIN_SUPPLEMENTARY_CODE_POINT) >>> 10) | Character.MIN_HIGH_SURROGATE);
341: chars[index + 1] = (char) ((codePoint & SURROGATE_MASK) | Character.MIN_LOW_SURROGATE);
342: return 2;
343: }
344: }
345:
346: public static int toCodePoint(char highChar, char lowChar) {
347: return ((highChar & SURROGATE_MASK) << 10 | (lowChar & SURROGATE_MASK))
348: + Character.MIN_SUPPLEMENTARY_CODE_POINT;
349: }
350:
351: public static int toLowerCase(int codePoint) {
352: return isBasic(codePoint) ? Character
353: .toLowerCase((char) codePoint) : codePoint;
354: }
355:
356: public static int toTitleCase(int codePoint) {
357: return isBasic(codePoint) ? Character
358: .toTitleCase((char) codePoint) : codePoint;
359: }
360:
361: public static int toUpperCase(int codePoint) {
362: return isBasic(codePoint) ? Character
363: .toUpperCase((char) codePoint) : codePoint;
364: }
365:
366: public static Character valueOf(char c) {
367: return c <= 127 ? cache[c] : new Character(c);
368: }
369:
370: private static boolean isBasic(int codePoint) {
371: return codePoint >= 0
372: && codePoint < Character.MIN_SUPPLEMENTARY_CODE_POINT;
373: }
374:
375: }
|