unicodeescapingreader.java

来自「Groovy动态语言 运行在JVM中的动态语言 可以方便的处理业务逻辑变化大的业」· Java 代码 · 共 152 行

JAVA
152
字号
/**
 * Copyright 2005 Alan Green
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */


package org.codehaus.groovy.antlr;

import java.io.IOException;
import java.io.Reader;

import antlr.CharScanner;

/**
 * Translates GLS-defined unicode escapes into characters. Throws an exception
 * in the event of an invalid unicode escape being detected.
 *
 * <p>No attempt has been made to optimise this class for speed or
 * space.</p>
 *
 * @version $Revision: 2222 $
 */
public class UnicodeEscapingReader extends Reader {

    private Reader reader;
    private CharScanner lexer;
    private boolean hasNextChar = false;
    private int nextChar;
    private SourceBuffer sourceBuffer;

    /**
     * Constructor.
     * @param reader The reader that this reader will filter over.
     */
    public UnicodeEscapingReader(Reader reader,SourceBuffer sourceBuffer) {
        this.reader = reader;
        this.sourceBuffer = sourceBuffer;
    }

    /**
     * Sets the lexer that is using this reader. Must be called before the
     * lexer is used.
     */
    public void setLexer(CharScanner lexer) {
        this.lexer = lexer;
    }

    /**
     * Reads characters from the underlying reader.
     * @see java.io.Reader#read(char[],int,int)
     */
    public int read(char cbuf[], int off, int len) throws IOException {
        int c = 0;
        int count = 0;
        while (count < len && (c = read())!= -1) {
            cbuf[off + count] = (char) c;
            count++;
        }
        return (count == 0 && c == -1) ? -1 : count;
    }

    /**
     * Gets the next character from the underlying reader,
     * translating escapes as required.
     * @see java.io.Reader#close()
     */
    public int read() throws IOException {
        if (hasNextChar) {
            hasNextChar = false;
            write(nextChar);
            return nextChar;
        }

        int c = reader.read();
        if (c != '\\') {
            write(c);
            return c;
        }

        // Have one backslash, continue if next char is 'u'
        c = reader.read();
        if (c != 'u') {
            hasNextChar = true;
            nextChar = c;
            write('\\');
            return '\\';
        }

        // Swallow multiple 'u's
        do {
            c = reader.read();
        } while (c == 'u');

        // Get first hex digit
        checkHexDigit(c);
        StringBuffer charNum = new StringBuffer();
        charNum.append((char) c);

        // Must now be three more hex digits
        for (int i = 0; i < 3; i++) {
            c = reader.read();
            checkHexDigit(c);
            charNum.append((char) c);
        }
        int rv = Integer.parseInt(charNum.toString(), 16);
        write(rv);
        return rv;
    }
    private void write(int c) {
        if (sourceBuffer != null) {sourceBuffer.write(c);}
    }
    /**
     * Checks that the given character is indeed a hex digit.
     */
    private void checkHexDigit(int c) throws IOException {
        if (c >= '0' && c <= '9') {
            return;
        }
        if (c >= 'a' && c <= 'f') {
            return;
        }
        if (c >= 'A' && c <= 'F') {
            return;
        }
        // Causes the invalid escape to be skipped
        hasNextChar = true;
        nextChar = c;
        throw new IOException("Did not find four digit hex character code."
                + " line: " + lexer.getLine() + " col:" + lexer.getColumn());
    }

    /**
     * Closes this reader by calling close on the underlying reader.
     * @see java.io.Reader#close()
     */
    public void close() throws IOException {
        reader.close();
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?