001 
002 /*
003  *  JScripter Emulation 1.0 - To Script Java
004  *  Copyright (C) 2008-2011  J.J.Liu<jianjunliu@126.com> <http://www.jscripter.org>
005  *  
006  *  This program is free software: you can redistribute it and/or modify
007  *  it under the terms of the GNU Affero General Public License as published by
008  *  the Free Software Foundation, either version 3 of the License, or
009  *  (at your option) any later version.
010  *  
011  *  This program is distributed in the hope that it will be useful,
012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014  *  GNU Affero General Public License for more details.
015  *  
016  *  You should have received a copy of the GNU Affero General Public License
017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
018  */
019 
020 package org.jscripter.emu.java.lang;
021 
022 import org.jscripter.emu.java.io.Serializable;
023 
024 import js.Js;
025 import js.core.JsGlobal;
026 
027 /**
028  * <p><b>Internally</b> represents primitive char values, emulating a standard <tt>java.lang</tt> interface or 
029  * class with the same simple name as this one.</p>
030  * <p>This interface or class is only used internally by JS re-compiler implementations.</p>
031  * <p>Please refer to <a href="http://java.sun.com/docs/">the Java API Standards</a> for detail description of the original class or interface.</p>
032  * 
033  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.jscripter.org" target="_blank">http://www.jscripter.org</a>
034  * 
035  * @javascript Re-compilers must redirect the resolution of the emulated original Java class or interface to this one.
036  */
037 public final class Character implements Comparable<Character>, Serializable
038 {
039     /**
040      * <p>Internally stores the minimum radix available for conversion to and from strings.</p>
041      * @since 1.0
042      * @javascript Re-compilers must report error on end-users directly using this field.
043      */
044     public static final int MIN_RADIX = 2;
045     /**
046      * <p>Internally stores the maximum radix available for conversion to and from strings.</p>
047      * @since 1.0
048      * @javascript Re-compilers must report error on end-users directly using this field.
049      */
050     public static final int MAX_RADIX = 36;
051 
052     /**
053      * <p>Internally stores constant the smallest value of type char, ''.</p>
054      * @since 1.0
055      * @javascript Re-compilers must report error on end-users directly using this field.
056      */
057     public static final char MIN_VALUE = '\u0000';
058     /**
059      * <p>Internally stores constant the largest value of type char, '￿'.</p>
060      * @since 1.0
061      * @javascript Re-compilers must report error on end-users directly using this field.
062      */
063     public static final char MAX_VALUE = '\uFFFF';
064 
065     /**
066      * <p>Returns the numeric value of a character in the specified radix.</p>
067      * @param ch A character to be converted.
068      * @param radix The radix.
069      * @return The numeric value represented by the character in the specified radix.
070      * @since 1.0
071      * @javascript Re-compilers must report error on end-users directly using this method.
072      */
073     public static final int digit(char ch, int radix) {
074         if (radix < 2 || radix > 36) {
075             return -1;
076         }
077         if (ch >= '0' && ch < '0' + Math.min(radix, 10)) {
078             return ch - '0';
079         }
080         if (ch >= 'a' && ch < (radix + 'a' - 10)) {
081             return ch - 'a' + 10;
082         }
083         if (ch >= 'A' && ch < (radix + 'A' - 10)) {
084             return ch - 'A' + 10;
085         }
086         return -1;
087     }
088 
089     /**
090      * <p>Determines the character representation for a specific digit in the specified radix.</p>
091      * <p>If the value of <tt>radix</tt> is not a valid radix, or the value of <tt>digit</tt> is not 
092      * a valid digit in the specified radix, the <tt>null</tt> character ('') is returned.</p>
093      * <p>The <tt>radix</tt> argument is valid if it is greater than or equal to {@link #MIN_RADIX} 
094      * and less than or equal to {@link #MAX_RADIX}. The <tt>digit</tt> argument is valid if 
095      * <tt>0 &lt;= digit &lt; radix.</p>
096      * <p>If the <tt>digit</tt> is less than 10, then <tt>'0' + digit</tt> is returned. Otherwise, 
097      * the value <tt>'a' + digit - 10</tt> is returned</p>
098      * <p></p>
099      * @param digit A number to convert to a character.
100      * @param radix The radix.
101      * @return The char representation of the specified digit in the specified radix.
102      * @since 1.0
103      * @javascript Re-compilers must report error on end-users directly using this method.
104      */
105     public static final char forDigit(int digit, int radix) {
106         if (radix < 2 || radix > 36) {
107             return 0;
108         }
109         if (digit < 0 || digit >= radix) {
110             return 0;
111         }
112         if (digit < 10) {
113             return (char) ('0' + digit);
114         } else {
115             return (char) ('a' + digit - 10);
116         }
117     }
118 
119     /**
120      * <p>Determines if the specified character is a digit.</p>
121      * @param ch A character to be tested.
122      * @return <tt>true</tt> if the character is a digit; <tt>false</tt> otherwise.
123      * @since 1.0
124      * @javascript Re-compilers must report error on end-users directly using this method.
125      */
126     public static final synchronized boolean isDigit(char ch) {
127         return Js.neq(
128                 null, 
129                 JsGlobal.String.prototype.match.with().call(
130                         JsGlobal.String.with().fromCharCode(ch),
131                         Js.re("\\d")
132                 )
133         );
134     }
135 
136     /**
137      * <p>Determines if the specified character is a letter.</p>
138      * @param ch A character to be tested.
139      * @return <tt>true</tt> if the character is a letter; <tt>false</tt> otherwise.
140      * @since 1.0
141      * @javascript Re-compilers must report error on end-users directly using this method.
142      */
143     public static final synchronized boolean isLetter(char ch) {
144         return Js.neq(
145                 null, 
146                 JsGlobal.String.prototype.match.with().call(
147                         JsGlobal.String.with().fromCharCode(ch),
148                         Js.re("[A-Z]", "i")
149                 )
150         );
151     }
152 
153     /**
154      * <p>Determines if the specified character is a letter or digit.</p>
155      * @param ch A character to be tested.
156      * @return <tt>true</tt> if the character is a letter or digit; <tt>false</tt> otherwise.
157      * @since 1.0
158      * @javascript Re-compilers must report error on end-users directly using this method.
159      */
160     public static final synchronized boolean isLetterOrDigit(char ch) {
161         return Js.neq(
162                 null, 
163                 JsGlobal.String.prototype.match.with().call(
164                         JsGlobal.String.with().fromCharCode(ch),
165                         Js.re("[A-Z]\\d", "i")
166                 )
167         );
168     }
169 
170     /**
171      * <p>Determines if the specified character is a lower-case character.</p>
172      * @param ch A character to be tested.
173      * @return <tt>true</tt> if the character is lower-case; <tt>false</tt> otherwise.
174      * @since 1.0
175      * @javascript Re-compilers must report error on end-users directly using this method.
176      */
177     public static final synchronized boolean isLowerCase(char ch) {
178         return Js.and(java.lang.Boolean.valueOf(Js.eq(toLowerCase(ch), ch)), java.lang.Boolean.valueOf(isLetter(ch)));
179     }
180 
181     /**
182      * <p>Determines if the specified character is ISO-LATIN-1 white space.</p>
183      * @param ch A character to be tested.
184      * @return <tt>true</tt> if the character is ISO-LATIN-1 white space; <tt>false</tt> otherwise.
185      * @since 1.0
186      * @javascript Re-compilers must report error on end-users directly using this method.
187      */
188     public static final boolean isSpace(char ch) {
189         switch (ch) {
190             case ' ' :
191             case '\n':
192             case '\t':
193             case '\f':
194             case '\r':
195                 return true;
196             default:
197                 return false;
198         }
199     }
200 
201     /**
202      * <p>Determines if the specified character is a upper-case character.</p>
203      * @param ch A character to be tested.
204      * @return <tt>true</tt> if the character is upper-case; <tt>false</tt> otherwise.
205      * @since 1.0
206      * @javascript Re-compilers must report error on end-users directly using this method.
207      */
208     public static final synchronized boolean isUpperCase(char ch) {
209         return Js.eq(toUpperCase(ch), ch) && isLetter(ch);
210     }
211 
212     /**
213      * <p>Converts the character argument to lower-case.</p>
214      * @param ch A character to be converted.
215      * @return The lower-case equivalent of the character, if any; otherwise, the character itself.
216      * @since 1.0
217      * @javascript Re-compilers must report error on end-users directly using this method.
218      */
219     public static final synchronized char toLowerCase(char ch) {
220         return JsGlobal.String.with().fromCharCode(ch).toLowerCase().charAt(0); 
221     }
222 
223     /**
224      * <p>Returns a string representing the specified char. The result is a string of length 1 
225      * consisting solely of the specified char.</p>
226      * @param c A character to be converted.
227      * @return The string representation of the specified char.
228      * @since 1.0
229      * @javascript Re-compilers must report error on end-users directly using this method.
230      */
231     public static final synchronized java.lang.String toString(char c) {
232         return String.valueOf(c);
233     }
234 
235     /**
236      * <p>Converts the character argument to upper-case.</p>
237      * @param ch A character to be converted.
238      * @return The upper-case equivalent of the character, if any; otherwise, the character itself.
239      * @since 1.0
240      * @javascript Re-compilers must report error on end-users directly using this method.
241      */
242     public static final synchronized char toUpperCase(char ch) {
243         return JsGlobal.String.with().fromCharCode(ch).toUpperCase().charAt(0); 
244     }
245 
246     /**
247      * <p>Returns a {@link Character} representing the specified char value.</p>
248      * @param c A char value.
249      * @return A {@link Character} representing <tt>c</tt>.
250      * @since 1.0
251      * @javascript Re-compilers must report error on end-users directly using this method.
252      * As a "synchronized" static emulating method, its invocation should be re-compiled into in-lined code for efficiency.
253      */
254     public static final synchronized Character valueOf(char c) {
255         return new Character(c);
256     }
257 
258     /**
259      * <p>Allocates a {@link Character} representing the char argument.</p>
260      * @param value A char value.
261      * @since 1.0
262      * @javascript Re-compilers must report error on end-users directly using this constructor.
263      * A re-compiler simply replaces an invocation of this constructor with its argument.
264      */
265     public Character(char value) {
266     }
267 
268     /**
269      * <p>Returns the value of this {@link Character} as a char primitive.</p>
270      * @return The primitive char value.
271      * @since 1.0
272      * @javascript Re-compilers must report error on end-users directly using this method.
273      * A re-compiler simply replaces an invocation of this native method with the current {@link Boolean}.
274      */
275     public final native char charValue();
276 
277     /**
278      * <p>Compares two {@link Character}s numerically.</p>
279      * @param c The {@link Character} to be compared.
280      * @return 0 if this {@link Character} is equal to the argument {@link Character}; a value less than 0 
281      * if this {@link Character} is numerically less than the argument {@link Character}; and a value greater 
282      * than 0 if this {@link Character} is numerically greater than the argument {@link Character} (unsigned comparison).
283      * Note that this is strictly a numerical comparison; it is not locale-dependent.
284      * @since 1.0
285      * @javascript Re-compilers must report error on end-users directly using this method.
286      * For efficiency, the invocation of this instance emulation method with single statement can be in-lined in re-compilation.
287      */
288     public final int compareTo(Character c) {
289         return ((java.lang.Integer)Js.cond(
290                 Js.lt(this, c),
291                 -1, 
292                 Js.cond(
293                         Js.gt(this, c),
294                         1, 
295                         0
296                 )
297         )).intValue();
298     }
299 
300     /**
301      * <p>Compares this {@link Character} to the specified object.</p>
302      * <p>Returns <tt>true</tt> if and only if the argument is not <tt>null</tt> and is a {@link Character} 
303      * that represents the same value as this {@link Character}.</p>
304      * @param o The object to compare with.
305      * @return <tt>true</tt> if the {@link Character}s represent the same value; <tt>false</tt> otherwise.
306      * @since 1.0
307      * @javascript Re-compilers must report error on end-users directly using this method.
308      * For efficiency, the invocation of this instance emulation method with single statement can be in-lined in re-compilation.
309      */
310     @Override
311     public final boolean equals(java.lang.Object o) {
312         return Js.eq(this, o);
313     }
314 
315     /**
316      * <p>Returns a hash code for this {@link Character}.</p>
317      * @return A hash code value for this {@link Character}.
318      * @since 1.0
319      * @javascript Re-compilers must report error on end-users directly using this method.
320      * For efficiency, the invocation of this instance emulation method with single statement can be in-lined in re-compilation.
321      */
322     @Override
323     public final int hashCode() {
324         return (int)((java.lang.Character)(java.lang.Object)this).charValue();
325     }
326 
327     /**
328      * <p>Returns a string representing this {@link Character}'s value.</p>
329      * <p>The result is a string of length 1 whose sole component is the primitive char value 
330      * represented by this {@link Character}.</p>
331      * @return A string representation of this {@link Character}.
332      * @since 1.0
333      * @javascript Re-compilers must report error on end-users directly using this method.
334      */
335     @Override
336     public final java.lang.String toString() {
337         return String.valueOf(((java.lang.Character)(java.lang.Object)this).charValue());
338     }
339 }