Properties-load()源码

微笑、不失礼 提交于 2020-01-26 21:34:13

public class Properties

/**
 * Reads a property list (key and element pairs) from the input
 * byte stream. The input stream is in a simple line-oriented
 * format as specified in
 * {@link #load(java.io.Reader) load(Reader)} and is assumed to use
 * the ISO 8859-1 character encoding; that is each byte is one Latin1
 * character. Characters not in Latin1, and certain special characters,
 * are represented in keys and elements using Unicode escapes as defined in
 * section 3.3 of
 * <cite>The Java&trade; Language Specification</cite>.
 * <p>
 * The specified stream remains open after this method returns.
 *
 * @param      inStream   the input stream.
 * @exception  IOException  if an error occurred when reading from the
 *             input stream.
 * @throws     IllegalArgumentException if the input stream contains a
 *             malformed Unicode escape sequence.
 * @since 1.2
 */
public synchronized void load(InputStream inStream) throws IOException {
    load0(new LineReader(inStream));
}

private void load0 (LineReader lr) throws IOException {
    char[] convtBuf = new char[1024];
    int limit;
    int keyLen;
    int valueStart;
    char c;
    boolean hasSep;
    boolean precedingBackslash;

    while ((limit = lr.readLine()) >= 0) {
        c = 0;
        keyLen = 0;
        valueStart = limit;
        hasSep = false;

        //System.out.println("line=<" + new String(lineBuf, 0, limit) + ">");
        precedingBackslash = false;
        while (keyLen < limit) {
            c = lr.lineBuf[keyLen];
            //need check if escaped.
            if ((c == '=' ||  c == ':') && !precedingBackslash) {
                valueStart = keyLen + 1;
                hasSep = true;
                break;
            } else if ((c == ' ' || c == '\t' ||  c == '\f') && !precedingBackslash) {
                valueStart = keyLen + 1;
                break;
            }
            if (c == '\\') {
                precedingBackslash = !precedingBackslash;
            } else {
                precedingBackslash = false;
            }
            keyLen++;
        }
        while (valueStart < limit) {
            c = lr.lineBuf[valueStart];
            if (c != ' ' && c != '\t' &&  c != '\f') {
                if (!hasSep && (c == '=' ||  c == ':')) {
                    hasSep = true;
                } else {
                    break;
                }
            }
            valueStart++;
        }
        String key = loadConvert(lr.lineBuf, 0, keyLen, convtBuf);
        String value = loadConvert(lr.lineBuf, valueStart, limit - valueStart, convtBuf);
        put(key, value);
    }
}

/* Read in a "logical line" from an InputStream/Reader, skip all comment
 * and blank lines and filter out those leading whitespace characters
 * (\u0020, \u0009 and \u000c) from the beginning of a "natural line".
 * Method returns the char length of the "logical line" and stores
 * the line in "lineBuf".
 */
class LineReader {
    public LineReader(InputStream inStream) {
        this.inStream = inStream;
        inByteBuf = new byte[8192];
    }

    public LineReader(Reader reader) {
        this.reader = reader;
        inCharBuf = new char[8192];
    }

    byte[] inByteBuf;
    char[] inCharBuf;
    char[] lineBuf = new char[1024];
    int inLimit = 0;
    int inOff = 0;
    InputStream inStream;
    Reader reader;

    int readLine() throws IOException {
        int len = 0;
        char c = 0;

        boolean skipWhiteSpace = true;
        boolean isCommentLine = false;
        boolean isNewLine = true;
        boolean appendedLineBegin = false;
        boolean precedingBackslash = false;
        boolean skipLF = false;

        while (true) {
            if (inOff >= inLimit) {
                inLimit = (inStream==null)?reader.read(inCharBuf)
                                          :inStream.read(inByteBuf);
                inOff = 0;
                if (inLimit <= 0) {
                    if (len == 0 || isCommentLine) {
                        return -1;
                    }
                    if (precedingBackslash) {
                        len--;
                    }
                    return len;
                }
            }
            if (inStream != null) {
                //The line below is equivalent to calling a
                //ISO8859-1 decoder.
                c = (char) (0xff & inByteBuf[inOff++]);
            } else {
                c = inCharBuf[inOff++];
            }
            if (skipLF) {
                skipLF = false;
                if (c == '\n') {
                    continue;
                }
            }
            if (skipWhiteSpace) {
                if (c == ' ' || c == '\t' || c == '\f') {
                    continue;
                }
                if (!appendedLineBegin && (c == '\r' || c == '\n')) {
                    continue;
                }
                skipWhiteSpace = false;
                appendedLineBegin = false;
            }
            if (isNewLine) {
                isNewLine = false;
                if (c == '#' || c == '!') {
                    isCommentLine = true;
                    continue;
                }
            }

            if (c != '\n' && c != '\r') {
                lineBuf[len++] = c;
                if (len == lineBuf.length) {
                    int newLength = lineBuf.length * 2;
                    if (newLength < 0) {
                        newLength = Integer.MAX_VALUE;
                    }
                    char[] buf = new char[newLength];
                    System.arraycopy(lineBuf, 0, buf, 0, lineBuf.length);
                    lineBuf = buf;
                }
                //flip the preceding backslash flag
                if (c == '\\') {
                    precedingBackslash = !precedingBackslash;
                } else {
                    precedingBackslash = false;
                }
            }
            else {
                // reached EOL
                if (isCommentLine || len == 0) {
                    isCommentLine = false;
                    isNewLine = true;
                    skipWhiteSpace = true;
                    len = 0;
                    continue;
                }
                if (inOff >= inLimit) {
                    inLimit = (inStream==null)
                              ?reader.read(inCharBuf)
                              :inStream.read(inByteBuf);
                    inOff = 0;
                    if (inLimit <= 0) {
                        if (precedingBackslash) {
                            len--;
                        }
                        return len;
                    }
                }
                if (precedingBackslash) {
                    len -= 1;
                    //skip the leading whitespace characters in following line
                    skipWhiteSpace = true;
                    appendedLineBegin = true;
                    precedingBackslash = false;
                    if (c == '\r') {
                        skipLF = true;
                    }
                } else {
                    return len;
                }
            }
        }
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!