/[classpath]/classpath/java/lang/Character.java
ViewVC logotype

Diff of /classpath/java/lang/Character.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.20 by ericb, Sun Feb 17 07:30:03 2002 UTC revision 1.21 by ericb, Mon Feb 18 20:07:17 2002 UTC
# Line 39  exception statement from your version. * Line 39  exception statement from your version. *
39  package java.lang;  package java.lang;
40    
41  import java.io.Serializable;  import java.io.Serializable;
42  import java.io.File;  import gnu.java.lang.CharData;
 import java.io.DataInputStream;  
 import java.io.FileInputStream;  
 import java.io.RandomAccessFile;  
 import java.io.IOException;  
 import gnu.java.lang.ClassLoaderHelper;  
43    
44  /**  /**
45   * Wrapper class for the primitive char data type.  In addition,   * Wrapper class for the primitive char data type.  In addition, this class
46   * this class allows one to retrieve property information and   * allows one to retrieve property information and perform transformations
47   * perform transformations on the 57,707 defined characters in the   * on the 57,707 defined characters in the Unicode Standard, Version 3.0.0.
48   * Unicode Standard, Version 3.0.0.  java.lang.Character is designed   * java.lang.Character is designed to be very dynamic, and as such, it
49   * to be very dynamic, and as such, it retrieves information on   * retrieves information on the Unicode character set from a separate
50   * the Unicode character set from a separate database, which   * database, gnu.java.lang.CharData, which can be easily upgraded.
  * can be easily upgraded.  
51   *   *
52   * <p>For predicates, boundaries are used to describe   * <p>For predicates, boundaries are used to describe
53   * the set of characters for which the method will return true.   * the set of characters for which the method will return true.
# Line 90  public final class Character implements Line 84  public final class Character implements
84       */       */
85      protected Subset(String name)      protected Subset(String name)
86      {      {
87          // Note that name.toString() is name, unless name was null.
88        this.name = name.toString();        this.name = name.toString();
89      }      }
90    
# Line 132  public final class Character implements Line 127  public final class Character implements
127     * A family of character subsets in the Unicode specification. A character     * A family of character subsets in the Unicode specification. A character
128     * is in at most one of these blocks.     * is in at most one of these blocks.
129     *     *
130     * This class was generated by doc/unicode/unicode-blocks.pl.     * This inner class was generated by doc/unicode/unicode-blocks.pl.
131     *     *
132       * @author doc/unicode/unicode-blocks.pl (written by Eric Blake)
133     * @since 1.2     * @since 1.2
134     */     */
135    public static final class UnicodeBlock extends Subset    public static final class UnicodeBlock extends Subset
# Line 1379  public final class Character implements Line 1375  public final class Character implements
1375     */     */
1376    public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18;    public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18;
1377    
1378    /** Stores unicode blocks in gnu/java/locale/block.uni. */    /**
1379    private static final Block blocks[];     * Stores unicode block offset lookup table. Exploit package visibility of
1380       * String.value to avoid copying the array.
1381    /** Stores titlecase information in gnu/java/locale/titlecase.uni. */     * @see #readChar(char)
1382    private static final char tcs[][];     * @see CharData#BLOCKS
1383       */
1384    /** Stores unicode data in gnu/java/locale/character.uni. */    private static final char[] blocks = CharData.BLOCKS.value;
   private static final byte[] unicodeData;  
1385    
1386    /** Caches the most recently used CharAttr. */    /**
1387    private static CharAttr cachedCharAttr;     * Stores unicode attribute offset lookup table. Exploit package visibility
1388       * of String.value to avoid copying the array.
1389       * @see CharData#DATA
1390       */
1391      private static final char[] data = CharData.DATA.value;
1392    
1393    /** The size of a block in gnu/java/locale/block.uni. */    /**
1394    private static final int BLOCK_SIZE = 6;     * Stores unicode numeric value attribute table. Exploit package visibility
1395       * of String.value to avoid copying the array.
1396       * @see CharData#NUM_VALUE
1397       */
1398      private static final char[] numValue = CharData.NUM_VALUE.value;
1399    
1400    /** The size of an attribute in gnu/java/locale/character.uni. */    /**
1401    private static final int ATTR_SIZE = 8;     * Stores unicode uppercase attribute table. Exploit package visibility
1402       * of String.value to avoid copying the array.
1403       * @see CharData#UPPER
1404       */
1405      private static final char[] upper = CharData.UPPER.value;
1406    
1407    /**    /**
1408     * Open up the Unicode attribute database and read the index into memory.     * Stores unicode lowercase attribute table. Exploit package visibility
1409     * These files were generated by doc/unicode/unicode-muncher.pl.     * of String.value to avoid copying the array.
1410       * @see CharData#LOWER
1411     */     */
1412    static    private static final char[] lower = CharData.LOWER.value;
   {  
     File cFile = ClassLoaderHelper.getSystemResourceAsFile(  
                    "/gnu/java/locale/character.uni");  
     File blockFile = ClassLoaderHelper.getSystemResourceAsFile(  
                    "/gnu/java/locale/block.uni");  
     File tcFile = ClassLoaderHelper.getSystemResourceAsFile(  
                    "/gnu/java/locale/titlecase.uni");  
     if (cFile == null || blockFile == null || tcFile == null)  
       throw new InternalError("Cannot locate Unicode attribute database.");  
1413    
1414      blocks = new Block[(int) blockFile.length() / BLOCK_SIZE];    /**
1415      try     * Stores unicode direction attribute table. Exploit package visibility
1416        {     * of String.value to avoid copying the array.
1417          DataInputStream blockIS     * @see CharData#DIRECTION
1418            = new DataInputStream(new FileInputStream(blockFile));     */
1419          for (int i = 0; i < blocks.length; i++)    private static final char[] direction = CharData.DIRECTION.value;
           {  
             char start = blockIS.readChar();  
             char end = blockIS.readChar();  
             short offset = blockIS.readShort();  
             blocks[i] = new Block(start, end, offset);  
           }  
       }  
     catch (IOException e)  
       {  
         throw new InternalError("Error reading block file: " + e);  
       }  
1420    
1421      tcs = new char[(int) tcFile.length() / 4][2];    /**
1422      try     * Stores unicode titlecase table. Exploit package visibility of
1423        {     * String.value to avoid copying the array.
1424          DataInputStream tcIS     * @see CharData#TITLE
1425            = new DataInputStream(new FileInputStream(tcFile));     */
1426          for (int i = 0; i < tcs.length; i++)    private static final char[] title = CharData.TITLE.value;
           {  
             tcs[i][0] = tcIS.readChar();  
             tcs[i][1] = tcIS.readChar();  
           }  
       }  
     catch (IOException e)  
       {  
         throw new InternalError("Error reading titlecase file: " + e);  
       }  
1427    
1428      try    /**
1429        {     * Mask for grabbing the type out of the contents of data.
1430          RandomAccessFile charFile = new RandomAccessFile(cFile, "r");     * @see CharData#DATA
1431          unicodeData = new byte[(int) charFile.length()];     */
1432          charFile.readFully(unicodeData, 0, unicodeData.length);    private static final int TYPE_MASK = 0x1F;
       }  
     catch (IOException e)  
       {  
         throw new InternalError("Error reading Unicode attribute file: "  
                                 + e);  
       }  
1433    
1434      cachedCharAttr = new CharAttr('\0', false, CONTROL, -1, '\0', '\0',    /** Mask for grabbing the non-breaking space flag out of the contents of
1435                                    DIRECTIONALITY_BOUNDARY_NEUTRAL, false);     * data.
1436    }     * @see CharData#DATA
1437       */
1438      private static final int NO_BREAK_MASK = 0x20;
1439    
1440    /**    /** Mask for grabbing the mirrored directionality flag out of the contents
1441     * Grabs a character out of the Unicode attribute database. See     * of data.
1442     * doc/unicode/unicode.database.format for details of the fields.     * @see CharData#DATA
    *  
    * @param ch the character to look up  
    * @return the character's CharAttr  
1443     */     */
1444    private static CharAttr readChar(char ch)    private static final int MIRROR_MASK = 0x40;
   {  
     CharAttr cached = cachedCharAttr;  
     if (cached.ch == ch)  
       return cached;  
   
     Block b = getBlock(ch);  
     if (b == null)  
       return cachedCharAttr = new CharAttr(ch, false, UNASSIGNED, -1, ch, ch,  
                                            DIRECTIONALITY_UNDEFINED, false);  
     int offset = b.compressed ? b.offset  
       : (b.offset + (ch - b.start) * ATTR_SIZE);  
     byte flags = unicodeData[offset];  
     boolean noBreakSpace = (flags & 0x20) == 0x20;  
     byte category = (byte) (flags & 0x1F);  
     // numericValue, uppercase, and lowercase are signed in unicode.uni.  
     int numericValue = (unicodeData[offset + 1] << 8)  
       | (unicodeData[offset + 2] & 0xFF);  
     char uppercase = (char) (ch - ((unicodeData[offset + 3] << 8)  
                                    | (unicodeData[offset + 4] & 0xFF)));  
     char lowercase = (char) (ch - ((unicodeData[offset + 5] << 8)  
                                    | (unicodeData[offset + 6] & 0xFF)));  
     if (b.compressed && numericValue >= 0)  
       numericValue += ch - b.start;  
     byte directionality = unicodeData[offset + 7];  
     boolean mirrored = (flags & 0x40) == 0x40;  
   
     return cachedCharAttr = new CharAttr(ch, noBreakSpace, category,  
                                          numericValue, uppercase, lowercase,  
                                          directionality, mirrored);  
   }  
1445    
1446    /**    /**
1447     * Locates which block a character's information resides in.     * Grabs an attribute offset from the Unicode attribute database. The lower
1448       * 5 bits are the character type, the next 2 bits are flags, and the top
1449       * 9 bits are the offset into the attribute tables.
1450     *     *
1451     * @param ch the character to look up     * @param ch the character to look up
1452     * @return the block, or null     * @return the character's attribute offset and type
1453       * @see CharData#DATA
1454       * @see CharData#SHIFT
1455     */     */
1456    private static Block getBlock(char ch)    private static char readChar(char ch)
1457    {    {
1458      // Simple binary search.      return data[blocks[ch >> CharData.SHIFT]
1459      int low = 0;                  + (ch & ~(-1 << CharData.SHIFT))];
     int hi = blocks.length - 1;  
     while (low <= hi)  
       {  
         int mid = (low + hi) >> 1;  
         Block b = blocks[mid];  
         if (ch < b.start)  
           hi = mid - 1;  
         else if (ch > b.end)  
           low = mid + 1;  
         else  
           return b;  
       }  
     return null;  
1460    }    }
1461    
1462    /**    /**
# Line 1577  public final class Character implements Line 1510  public final class Character implements
1510     */     */
1511    public String toString()    public String toString()
1512    {    {
1513        // This assumes that String.valueOf(char) can create a single-character
1514        // String more efficiently than through the public API.
1515      return String.valueOf(value);      return String.valueOf(value);
1516    }    }
1517    
# Line 1589  public final class Character implements Line 1524  public final class Character implements
1524     */     */
1525    public String toString(char ch)    public String toString(char ch)
1526    {    {
1527        // This assumes that String.valueOf(char) can create a single-character
1528        // String more efficiently than through the public API.
1529      return String.valueOf(ch);      return String.valueOf(ch);
1530    }    }
1531    
# Line 1680  public final class Character implements Line 1617  public final class Character implements
1617     */     */
1618    public static boolean isDefined(char ch)    public static boolean isDefined(char ch)
1619    {    {
1620      return getBlock(ch) != null;      return getType(ch) == UNASSIGNED;
1621    }    }
1622    
1623    /**    /**
# Line 1703  public final class Character implements Line 1640  public final class Character implements
1640     */     */
1641    public static boolean isLetter(char ch)    public static boolean isLetter(char ch)
1642    {    {
1643      int category = getType(ch);      return ((1 << getType(ch))
1644      return category >= UPPERCASE_LETTER && category <= OTHER_LETTER;              & ((1 << UPPERCASE_LETTER)
1645                   | (1 << LOWERCASE_LETTER)
1646                   | (1 << TITLECASE_LETTER)
1647                   | (1 << MODIFIER_LETTER)
1648                   | (1 << OTHER_LETTER))) != 0;
1649    }    }
1650    
1651    /**    /**
# Line 1724  public final class Character implements Line 1665  public final class Character implements
1665     */     */
1666    public static boolean isLetterOrDigit(char ch)    public static boolean isLetterOrDigit(char ch)
1667    {    {
1668      int category = getType(ch);      return ((1 << getType(ch))
1669      return (category <= OTHER_LETTER && category >= UPPERCASE_LETTER)              & ((1 << UPPERCASE_LETTER)
1670        || category == DECIMAL_DIGIT_NUMBER;                 | (1 << LOWERCASE_LETTER)
1671                   | (1 << TITLECASE_LETTER)
1672                   | (1 << MODIFIER_LETTER)
1673                   | (1 << OTHER_LETTER)
1674                   | (1 << DECIMAL_DIGIT_NUMBER))) != 0;
1675    }    }
1676    
1677    /**    /**
# Line 1790  public final class Character implements Line 1735  public final class Character implements
1735     */     */
1736    public static boolean isJavaIdentifierStart(char ch)    public static boolean isJavaIdentifierStart(char ch)
1737    {    {
1738      int category = getType(ch);      return ((1 << getType(ch))
1739      return (category <= OTHER_LETTER && category >= UPPERCASE_LETTER)              & ((1 << UPPERCASE_LETTER)
1740        || category == LETTER_NUMBER || category == CURRENCY_SYMBOL                 | (1 << LOWERCASE_LETTER)
1741        || category == CONNECTOR_PUNCTUATION;                 | (1 << TITLECASE_LETTER)
1742                   | (1 << MODIFIER_LETTER)
1743                   | (1 << OTHER_LETTER)
1744                   | (1 << LETTER_NUMBER)
1745                   | (1 << CURRENCY_SYMBOL)
1746                   | (1 << CONNECTOR_PUNCTUATION))) != 0;
1747    }    }
1748    
1749    /**    /**
# Line 1818  public final class Character implements Line 1768  public final class Character implements
1768    public static boolean isJavaIdentifierPart(char ch)    public static boolean isJavaIdentifierPart(char ch)
1769    {    {
1770      int category = getType(ch);      int category = getType(ch);
1771      if (category == CONTROL)      return ((1 << category)
1772        return isIdentifierIgnorable(ch);              & ((1 << UPPERCASE_LETTER)
1773      return  (category <= NON_SPACING_MARK && category >= UPPERCASE_LETTER)                 | (1 << LOWERCASE_LETTER)
1774        || (category <= LETTER_NUMBER && category >= COMBINING_SPACING_MARK)                 | (1 << TITLECASE_LETTER)
1775        || category == CURRENCY_SYMBOL || category == CONNECTOR_PUNCTUATION                 | (1 << MODIFIER_LETTER)
1776        || category == FORMAT;                 | (1 << OTHER_LETTER)
1777                   | (1 << NON_SPACING_MARK)
1778                   | (1 << COMBINING_SPACING_MARK)
1779                   | (1 << DECIMAL_DIGIT_NUMBER)
1780                   | (1 << LETTER_NUMBER)
1781                   | (1 << CURRENCY_SYMBOL)
1782                   | (1 << CONNECTOR_PUNCTUATION)
1783                   | (1 << FORMAT))) != 0
1784          || (category == CONTROL && isIdentifierIgnorable(ch));
1785    }    }
1786    
1787    /**    /**
# Line 1842  public final class Character implements Line 1800  public final class Character implements
1800     */     */
1801    public static boolean isUnicodeIdentifierStart(char ch)    public static boolean isUnicodeIdentifierStart(char ch)
1802    {    {
1803      int category = getType(ch);      return ((1 << getType(ch))
1804      return (category <= OTHER_LETTER && category >= UPPERCASE_LETTER)              & ((1 << UPPERCASE_LETTER)
1805        || category == LETTER_NUMBER;                 | (1 << LOWERCASE_LETTER)
1806                   | (1 << TITLECASE_LETTER)
1807                   | (1 << MODIFIER_LETTER)
1808                   | (1 << OTHER_LETTER)
1809                   | (1 << LETTER_NUMBER))) != 0;
1810    }    }
1811    
1812    /**    /**
# Line 1868  public final class Character implements Line 1830  public final class Character implements
1830    public static boolean isUnicodeIdentifierPart(char ch)    public static boolean isUnicodeIdentifierPart(char ch)
1831    {    {
1832      int category = getType(ch);      int category = getType(ch);
1833      if (category == CONTROL)      return ((1 << category)
1834        return isIdentifierIgnorable(ch);              & ((1 << UPPERCASE_LETTER)
1835      return  (category <= NON_SPACING_MARK && category >= UPPERCASE_LETTER)                 | (1 << LOWERCASE_LETTER)
1836        || (category <= LETTER_NUMBER && category >= COMBINING_SPACING_MARK)                 | (1 << TITLECASE_LETTER)
1837        || category == CONNECTOR_PUNCTUATION || category == FORMAT;                 | (1 << MODIFIER_LETTER)
1838                   | (1 << OTHER_LETTER)
1839                   | (1 << NON_SPACING_MARK)
1840                   | (1 << COMBINING_SPACING_MARK)
1841                   | (1 << DECIMAL_DIGIT_NUMBER)
1842                   | (1 << LETTER_NUMBER)
1843                   | (1 << CONNECTOR_PUNCTUATION)
1844                   | (1 << FORMAT))) != 0
1845          || (category == CONTROL && isIdentifierIgnorable(ch));
1846    }    }
1847    
1848    /**    /**
# Line 1893  public final class Character implements Line 1863  public final class Character implements
1863     */     */
1864    public static boolean isIdentifierIgnorable(char ch)    public static boolean isIdentifierIgnorable(char ch)
1865    {    {
1866      return ch <= '\u0008' || (ch <= '\u001B' && ch >= '\u000E')      return (ch <= '\u009F' && (ch < '\t' || ch >= '\u007F'
1867        || (ch <= '\u009F' && ch >= '\u007F') || getType(ch) == FORMAT;                                 || (ch <= '\u001B' && ch >= '\u000E')))
1868          || getType(ch) == FORMAT;
1869    }    }
1870    
1871    /**    /**
# Line 1912  public final class Character implements Line 1883  public final class Character implements
1883     */     */
1884    public static char toLowerCase(char ch)    public static char toLowerCase(char ch)
1885    {    {
1886      return readChar(ch).lowercase;      // Signedness doesn't matter, as result is cast back to char.
1887        return (char) (ch + lower[readChar(ch) >> 7]);
1888    }    }
1889    
1890    /**    /**
# Line 1930  public final class Character implements Line 1902  public final class Character implements
1902     */     */
1903    public static char toUpperCase(char ch)    public static char toUpperCase(char ch)
1904    {    {
1905      return readChar(ch).uppercase;      // Signedness doesn't matter, as result is cast back to char.
1906        return (char) (ch + upper[readChar(ch) >> 7]);
1907    }    }
1908    
1909    /**    /**
# Line 1947  public final class Character implements Line 1920  public final class Character implements
1920     */     */
1921    public static char toTitleCase(char ch)    public static char toTitleCase(char ch)
1922    {    {
1923      for (int i = 0; i < tcs.length; i++)      // As title is short, it doesn't hurt to exhaustively iterate over it.
1924        if (tcs[i][0] == ch)      for (int i = title.length - 2; i >= 0; i -= 2)
1925          return tcs[i][1];        if (title[i] == ch)
1926            return title[i + 1];
1927      return toUpperCase(ch);      return toUpperCase(ch);
1928    }    }
1929    
# Line 1975  public final class Character implements Line 1949  public final class Character implements
1949    {    {
1950      if (radix < MIN_RADIX || radix > MAX_RADIX)      if (radix < MIN_RADIX || radix > MAX_RADIX)
1951        return -1;        return -1;
1952      CharAttr attr = readChar(ch);      char attr = readChar(ch);
1953      int category = attr.category;      if (((1 << (attr & TYPE_MASK))
1954      if (category == DECIMAL_DIGIT_NUMBER || category == LOWERCASE_LETTER           & ((1 << UPPERCASE_LETTER)
1955          || category == UPPERCASE_LETTER)              | (1 << LOWERCASE_LETTER)
1956                | (1 << DECIMAL_DIGIT_NUMBER))) != 0)
1957        {        {
1958          int digit = attr.numericValue;          // Signedness doesn't matter; 0xffff vs. -1 are both rejected.
1959            int digit = numValue[attr >> 7];
1960          return (digit >= 0 && digit < radix) ? digit : -1;          return (digit >= 0 && digit < radix) ? digit : -1;
1961        }        }
1962      return -1;      return -1;
# Line 2015  public final class Character implements Line 1991  public final class Character implements
1991     */     */
1992    public static int getNumericValue(char ch)    public static int getNumericValue(char ch)
1993    {    {
1994      return readChar(ch).numericValue;      // Treat numValue as signed.
1995        return (short) numValue[readChar(ch) >> 7];
1996    }    }
1997    
1998    /**    /**
# Line 2033  public final class Character implements Line 2010  public final class Character implements
2010     */     */
2011    public static boolean isSpace(char ch)    public static boolean isSpace(char ch)
2012    {    {
2013      return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\f';      // Performing the subtraction up front alleviates need to compare longs.
2014        return ch-- <= ' ' && ((1 << ch)
2015                               & ((1 << (' ' - 1))
2016                                  | (1 << ('\t' - 1))
2017                                  | (1 << ('\n' - 1))
2018                                  | (1 << ('\r' - 1))
2019                                  | (1 << ('\f' - 1)))) != 0;
2020    }    }
2021    
2022    /**    /**
# Line 2049  public final class Character implements Line 2032  public final class Character implements
2032     */     */
2033    public static boolean isSpaceChar(char ch)    public static boolean isSpaceChar(char ch)
2034    {    {
2035      int category = readChar(ch).category;      return ((1 << getType(ch))
2036      return category >= SPACE_SEPARATOR && category <= PARAGRAPH_SEPARATOR;              & ((1 << SPACE_SEPARATOR)
2037                   | (1 << LINE_SEPARATOR)
2038                   | (1 << PARAGRAPH_SEPARATOR))) != 0;
2039    }    }
2040    
2041    /**    /**
# Line 2072  public final class Character implements Line 2057  public final class Character implements
2057     */     */
2058    public static boolean isWhitespace(char ch)    public static boolean isWhitespace(char ch)
2059    {    {
2060      if ((ch <= '\r' && ch >= '\u0009') || (ch <= '\u001F' && ch >= '\u001C'))      int attr = readChar(ch);
2061        return true;      return ((((1 << (attr & TYPE_MASK))
2062      CharAttr attr = readChar(ch);                & ((1 << SPACE_SEPARATOR)
2063      int category = attr.category;                   | (1 << LINE_SEPARATOR)
2064      return (category == SPACE_SEPARATOR && ! attr.noBreakSpace)                   | (1 << PARAGRAPH_SEPARATOR))) != 0)
2065        || category == LINE_SEPARATOR || category == PARAGRAPH_SEPARATOR;              && (attr & NO_BREAK_MASK) == 0)
2066          || (ch <= '\u001F' && ((1 << ch)
2067                                 & ((1 << '\t')
2068                                    | (1 << '\n')
2069                                    | (1 << '\u000B')
2070                                    | (1 << '\u000C')
2071                                    | (1 << '\r')
2072                                    | (1 << '\u001C')
2073                                    | (1 << '\u001D')
2074                                    | (1 << '\u001E')
2075                                    | (1 << '\u001F'))) != 0);
2076    }    }
2077    
2078    /**    /**
# Line 2135  public final class Character implements Line 2130  public final class Character implements
2130     */     */
2131    public static int getType(char ch)    public static int getType(char ch)
2132    {    {
2133      return readChar(ch).category;      return readChar(ch) & TYPE_MASK;
2134    }    }
2135    
2136    /**    /**
# Line 2191  public final class Character implements Line 2186  public final class Character implements
2186     */     */
2187    public static byte getDirectionality(char ch)    public static byte getDirectionality(char ch)
2188    {    {
2189      return readChar(ch).directionality;      // The result will correctly be signed.
2190        return (byte) direction[readChar(ch) >> 7];
2191    }    }
2192    
2193    /**    /**
# Line 2205  public final class Character implements Line 2201  public final class Character implements
2201     */     */
2202    public static boolean isMirrored(char ch)    public static boolean isMirrored(char ch)
2203    {    {
2204      return readChar(ch).mirrored;      return (readChar(ch) & MIRROR_MASK) != 0;
2205    }    }
2206    
2207    /**    /**
# Line 2239  public final class Character implements Line 2235  public final class Character implements
2235    {    {
2236      return compareTo((Character) o);      return compareTo((Character) o);
2237    }    }
   
   /**  
    * Represents an entry in gnu/java/locale/block.uni.  
    */  
   private static final class Block  
   {  
     /** The start character of a compressed block. */  
     final char start;  
     /** The end character of a compressed block. */  
     final char end;  
     /** True if the block represents multiple characters. */  
     final boolean compressed;  
     /** The offset of the block. */  
     final int offset;  
   
     /**  
      * Construct a block.  
      * @param start the start character  
      * @param end the end character  
      * @param offset the offset and compression of the block: the most  
      *        significant bit is the compression, the remainder are the offset  
      */  
     Block(char start, char end, short offset)  
     {  
       this.start = start;  
       this.end = end;  
       this.compressed = offset < 0;  
       this.offset = offset & Short.MAX_VALUE;  
     }  
   } // class Block  
   
   /**  
    * Represents all the attributes stored for a character.  
    */  
   private static final class CharAttr  
   {  
     /** The character of this attribute. */  
     final char ch;  
     /** If the character is a non-breaking space. */  
     final boolean noBreakSpace;  
     /** The character category. */  
     final int category;  
     /** The character value. */  
     final int numericValue;  
     /** The uppercase version of the character. */  
     final char uppercase;  
     /** The lowercase version of the character. */  
     final char lowercase;  
     /** The directionality of the character. */  
     final byte directionality;  
     /** Whether the character is mirrored. */  
     final boolean mirrored;  
   
     /**  
      * Construct the attributes for a character.  
      * @param ch the character  
      * @param noBreakSpace if it is a non-breaking space  
      * @param category its category  
      * @param numericValue its value, or -1 (none), -2 (not representable)  
      * @param uppercase the uppercase version, or '\0'  
      * @param lowercase the lowercase version, or '\0'  
      * @param directionality the directionality  
      * @param mirrored if it is mirrored  
      */  
     CharAttr(char ch, boolean noBreakSpace, byte category, int numericValue,  
              char uppercase, char lowercase, byte directionality,  
              boolean mirrored)  
     {  
       this.ch = ch;  
       this.noBreakSpace = noBreakSpace;  
       this.category = category;  
       this.numericValue = numericValue;  
       this.uppercase = uppercase == '\0' ? ch : uppercase;  
       this.lowercase = lowercase == '\0' ? ch : lowercase;  
       this.directionality = directionality;  
       this.mirrored = mirrored;  
     }  
   } // class CharAttr  
2238  } //class Character  } //class Character

Legend:
Removed from v.1.20  
changed lines
  Added in v.1.21

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26