| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
/**  | 
 | 
 * This FilterReader class processes a sequence of characters from  | 
 | 
 * a source stream containing a mixture of 7-bit ASCII data and  | 
 | 
 * 'back-tick U' escaped sequences representing characters which have  | 
 | 
 * the possibility of being encoded in a user specified encoding  | 
 | 
 * The filter relies on knowing the target encoding and makes a  | 
 | 
 * determination as to whether a given supplied character in its  | 
 | 
 * source character stream is encodeable in the target encoding.  | 
 | 
 * If not, it is remains in its back-tick U escaped form.  | 
 | 
 */  | 
 | 
 | 
 | 
package sun.tools.native2ascii;  | 
 | 
import java.io.*;  | 
 | 
 | 
 | 
 | 
 | 
class A2NFilter extends FilterReader { | 
 | 
 | 
 | 
    // maintain a trailing buffer to hold any incompleted  | 
 | 
      | 
 | 
    private char[] trailChars = null;  | 
 | 
 | 
 | 
    public A2NFilter(Reader in) { | 
 | 
        super(in);  | 
 | 
    }  | 
 | 
 | 
 | 
    public int read(char[] buf, int off, int len) throws IOException { | 
 | 
        int numChars = 0;          | 
 | 
        int retChars = 0;          | 
 | 
 | 
 | 
        char[] cBuf = new char[len];  | 
 | 
        int cOffset = 0;           | 
 | 
        boolean eof = false;  | 
 | 
 | 
 | 
          | 
 | 
        if (trailChars != null) { | 
 | 
            for (int i = 0; i < trailChars.length; i++)  | 
 | 
                cBuf[i] = trailChars[i];  | 
 | 
            numChars = trailChars.length;  | 
 | 
            trailChars = null;  | 
 | 
        }  | 
 | 
 | 
 | 
        int n = in.read(cBuf, numChars, len - numChars);  | 
 | 
        if (n < 0) { | 
 | 
            eof = true;  | 
 | 
            if (numChars == 0)  | 
 | 
                return -1;                | 
 | 
        } else { | 
 | 
            numChars += n;  | 
 | 
        }  | 
 | 
 | 
 | 
        for (int i = 0; i < numChars;) { | 
 | 
            char c = cBuf[i++];  | 
 | 
 | 
 | 
            if (c != '\\' || (eof && numChars <= 5)) { | 
 | 
                // Not a backslash, so copy and continue  | 
 | 
                // Always pass non backslash chars straight thru  | 
 | 
                // for regular encoding. If backslash occurs in  | 
 | 
                // input stream at the final 5 chars then don't  | 
 | 
                // attempt to read-ahead and de-escape since these  | 
 | 
                // are literal occurrences of U+005C which need to  | 
 | 
                  | 
 | 
                buf[retChars++] = c;  | 
 | 
                continue;  | 
 | 
            }  | 
 | 
 | 
 | 
            int remaining = numChars - i;  | 
 | 
            if (remaining < 5) { | 
 | 
                // Might be the first character of a unicode escape, but we  | 
 | 
                  | 
 | 
                trailChars = new char[1 + remaining];  | 
 | 
                trailChars[0] = c;  | 
 | 
                for (int j = 0; j < remaining; j++)  | 
 | 
                    trailChars[1 + j] = cBuf[i + j];  | 
 | 
                break;  | 
 | 
            }  | 
 | 
            // At this point we have at least five characters remaining  | 
 | 
 | 
 | 
            c = cBuf[i++];  | 
 | 
            if (c != 'u') { | 
 | 
                  | 
 | 
                buf[retChars++] = '\\';  | 
 | 
                buf[retChars++] = c;  | 
 | 
                continue;  | 
 | 
            }  | 
 | 
 | 
 | 
              | 
 | 
            char rc = 0;  | 
 | 
            boolean isUE = true;  | 
 | 
            try { | 
 | 
                rc = (char)Integer.parseInt(new String(cBuf, i, 4), 16);  | 
 | 
            } catch (NumberFormatException x) { | 
 | 
                isUE = false;  | 
 | 
            }  | 
 | 
            if (isUE && Main.canConvert(rc)) { | 
 | 
                  | 
 | 
                buf[retChars++] = rc;  | 
 | 
                i += 4;   | 
 | 
            } else { | 
 | 
                  | 
 | 
                buf[retChars++] = '\\';  | 
 | 
                buf[retChars++] = 'u';  | 
 | 
                continue;  | 
 | 
            }  | 
 | 
 | 
 | 
        }  | 
 | 
 | 
 | 
        return retChars;  | 
 | 
    }  | 
 | 
 | 
 | 
    public int read() throws IOException { | 
 | 
        char[] buf = new char[1];  | 
 | 
 | 
 | 
        if (read(buf, 0, 1) == -1)  | 
 | 
            return -1;  | 
 | 
        else  | 
 | 
            return (int)buf[0];  | 
 | 
    }  | 
 | 
 | 
 | 
}  |