FileDocCategorySizeDatePackage
UnicodeParser.javaAPI DocphoneME MR2 API (J2ME)6160Wed May 02 18:00:36 BST 2007com.sun.perseus.parser

UnicodeParser

public class UnicodeParser extends AbstractParser
The UnicodeParser class converts attributes conforming to the <hkern>'s u1/u2 attributes syntax.
version
$Id: UnicodeParser.java,v 1.2 2006/04/21 06:40:32 st125089 Exp $

Fields Summary
Constructors Summary
Methods Summary
public int[][]parseUnicode(java.lang.String unicode)
Parses the input unicode range value and turns it into a set of two (possibly identical) unicode range values.

param
unicode unicode range string to parse
return
an array of unicode ranges of size 2.
throws
IllegalArgumentException if unicode is null.


        setString(unicode);
        
        if (unicode.length() == 0) {
            throw new IllegalArgumentException();
        }
        
        // Slow motion parser to simplify memory allocation

        // First count the number of ranges (',' seperated)
        int ranges = 1;
        while ((current = read()) != -1) {
            if (current == ',") {
                ranges++;
            }
        }

        setString(unicode);
        current = read();

        int[][] result = new int[ranges][];
        int cur = 0;
        while (current != -1) {
            if (current == 'U") {
                result[cur] = parseUnicodeRange(',");
            } else {
                if (current == ',") {
                    throw new IllegalArgumentException();
                }
                result[cur] = new int[2];
                result[cur][0] = current;
                result[cur][1] = current;
                current = read();
                if (current != ',") {
                    if (current != -1) {
                        throw new IllegalArgumentException();
                    }
                } else {
                    current = read();
                }
            }
            
            cur++;
        }

        return result;
    
protected int[]parseUnicodeRange(char endOn)

param
endOn specifies the character value that defines the end of the unicode value.
return
an array of two integers defining the lower and upper values in the unicode range.

        current = read();
        if (current != '+") {
            throw new IllegalArgumentException();
        }

        // Now, read the first unicode value. The acceptable 
        // values are: [0-9A-Fa-f?]
        StringBuffer sb = new StringBuffer();
        current = read();
        loop : while (current != -1 && current != ',") {
            switch (current) {
            case '0": case '1": case '2": case '3": case '4": case '5":
            case '6": case '7": case '8": case '9": case 'a": case 'b":
            case 'c": case 'd": case 'e": case 'f": case 'A": case 'B":
            case 'C": case 'D": case 'E": case 'F": case '?":
                break;
            case '-":
                break loop;
            default:
                throw new IllegalArgumentException();
            }
            sb.append((char) current);
            current = read();
        }

        // If we hit a '-', it means that the 
        // first value is a plain hex value
        int[] result = new int[2];
        try {
            if (current == '-") {
                result[0] = Integer.parseInt(sb.toString(), 16);
                current = read();
                int v = 0;
                int c = 0;
                int cur = 0;
                while (current != -1 && current != ',") {
                    switch (current) {
                    case '0": case '1": case '2": case '3": case '4":
                    case '5": case '6": case '7": case '8": case '9":
                        v = current - 0x30;
                                break;
                    case 'a": case 'b": case 'c": case 'd": case 'e":case 'f":
                        v = current - 0x57;
                        break;
                    case 'A": case 'B": case 'C": case 'D": case 'E": case 'F":
                        v = current - 0x37;
                        break;
                    default:
                        throw new IllegalArgumentException();
                    }
                    if (c > 0) {
                        cur <<= 4;
                    }
                    cur |= (0xff & v);
                    c++;
                    current = read();
                }
                if (c == 0) {
                    throw new IllegalArgumentException();
                }
                result[1] = cur;
            } else {
                String low = sb.toString();
                String high = low;
                low = low.replace('?", '0");
                high = high.replace('?", 'F");
                result[0] = Integer.parseInt(low, 16);
                result[1] = Integer.parseInt(high, 16);
            }
        } catch (NumberFormatException nfe) {
            throw new IllegalArgumentException();
        }
        
        return result;