encodinginfo.java

来自「JAVA 所有包」· Java 代码 · 共 509 行 · 第 1/2 页

JAVA
509
字号
/* * Copyright 1999-2004 The Apache Software Foundation. * * 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. *//* * $Id: EncodingInfo.java,v 1.2.4.2 2005/09/15 12:01:24 suresh_emailid Exp $ */package com.sun.org.apache.xml.internal.serializer;import java.io.UnsupportedEncodingException;/** * Holds information about a given encoding, which is the Java name for the * encoding, the equivalent ISO name. * <p> * An object of this type has two useful methods * <pre> * isInEncoding(char ch); * </pre> * which can be called if the character is not the high one in * a surrogate pair and: * <pre> * isInEncoding(char high, char low); * </pre> * which can be called if the two characters from a high/low surrogate pair. * <p> * An EncodingInfo object is a node in a binary search tree. Such a node * will answer if a character is in the encoding, and do so for a given * range of unicode values (<code>m_first</code> to * <code>m_last</code>). It will handle a certain range of values * explicitly (<code>m_explFirst</code> to <code>m_explLast</code>). * If the unicode point is before that explicit range, that is it * is in the range <code>m_first <= value < m_explFirst</code>, then it will delegate to another EncodingInfo object for The root * of such a tree, m_before.  Likewise for values in the range  * <code>m_explLast < value <= m_last</code>, but delgating to <code>m_after</code> * <p> * Actually figuring out if a code point is in the encoding is expensive. So the * purpose of this tree is to cache such determinations, and not to build the * entire tree of information at the start, but only build up as much of the  * tree as is used during the transformation. * <p> * This Class is not a public API, and should only be used internally within * the serializer. *  * @xsl.usage internal */public final class EncodingInfo extends Object{    /**     * The ISO encoding name.     */    final String name;    /**     * The name used by the Java convertor.     */    final String javaName;    /**     * A helper object that we can ask if a     * single char, or a surrogate UTF-16 pair     * of chars that form a single character,     * is in this encoding.     */    private InEncoding m_encoding;        /**     * This is not a public API. It returns true if the     * char in question is in the encoding.     * @param ch the char in question.     * @xsl.usage internal     */    public boolean isInEncoding(char ch) {        if (m_encoding == null) {            m_encoding = new EncodingImpl();                        // One could put alternate logic in here to            // instantiate another object that implements the            // InEncoding interface. For example if the JRE is 1.4 or up            // we could have an object that uses JRE 1.4 methods        }        return m_encoding.isInEncoding(ch);     }        /**     * This is not a public API. It returns true if the     * character formed by the high/low pair is in the encoding.     * @param high a char that the a high char of a high/low surrogate pair.     * @param low a char that is the low char of a high/low surrogate pair.     * @xsl.usage internal     */    public boolean isInEncoding(char high, char low) {        if (m_encoding == null) {            m_encoding = new EncodingImpl();                        // One could put alternate logic in here to            // instantiate another object that implements the            // InEncoding interface. For example if the JRE is 1.4 or up            // we could have an object that uses JRE 1.4 methods        }        return m_encoding.isInEncoding(high, low);     }    /**     * Create an EncodingInfo object based on the ISO name and Java name.     * If both parameters are null any character will be considered to     * be in the encoding. This is useful for when the serializer is in     * temporary output state, and has no assciated encoding.     *     * @param name reference to the ISO name.     * @param javaName reference to the Java encoding name.     */    public EncodingInfo(String name, String javaName)    {        this.name = name;        this.javaName = javaName;    }                /**     * A simple interface to isolate the implementation.     * We could also use some new JRE 1.4 methods in another implementation     * provided we use reflection with them.     * <p>     * This interface is not a public API,     * and should only be used internally within the serializer.      * @xsl.usage internal     */    private interface InEncoding {        /**         * Returns true if the char is in the encoding         */        public boolean isInEncoding(char ch);        /**         * Returns true if the high/low surrogate pair forms         * a character that is in the encoding.         */        public boolean isInEncoding(char high, char low);    }    /**     * This class implements the      */    private class EncodingImpl implements InEncoding {                public boolean isInEncoding(char ch1) {            final boolean ret;            int codePoint = Encodings.toCodePoint(ch1);            if (codePoint < m_explFirst) {                // The unicode value is before the range                // that we explictly manage, so we delegate the answer.                                // If we don't have an m_before object to delegate to, make one.                if (m_before == null)                    m_before =                        new EncodingImpl(                            m_encoding,                            m_first,                            m_explFirst - 1,                            codePoint);                ret = m_before.isInEncoding(ch1);            } else if (m_explLast < codePoint) {                // The unicode value is after the range                // that we explictly manage, so we delegate the answer.                                // If we don't have an m_after object to delegate to, make one.                if (m_after == null)                    m_after =                        new EncodingImpl(                            m_encoding,                            m_explLast + 1,                            m_last,                            codePoint);                ret = m_after.isInEncoding(ch1);            } else {                // The unicode value is in the range we explitly handle                final int idx = codePoint - m_explFirst;                                // If we already know the answer, just return it.                if (m_alreadyKnown[idx])                    ret = m_isInEncoding[idx];                else {                    // We don't know the answer, so find out,                    // which may be expensive, then cache the answer                     ret = inEncoding(ch1, m_encoding);                    m_alreadyKnown[idx] = true;                    m_isInEncoding[idx] = ret;                }            }            return ret;        }        public boolean isInEncoding(char high, char low) {            final boolean ret;            int codePoint = Encodings.toCodePoint(high,low);            if (codePoint < m_explFirst) {                // The unicode value is before the range                // that we explictly manage, so we delegate the answer.                                // If we don't have an m_before object to delegate to, make one.                if (m_before == null)                    m_before =                        new EncodingImpl(                            m_encoding,                            m_first,                            m_explFirst - 1,                            codePoint);                ret = m_before.isInEncoding(high,low);            } else if (m_explLast < codePoint) {                // The unicode value is after the range                // that we explictly manage, so we delegate the answer.                                // If we don't have an m_after object to delegate to, make one.                if (m_after == null)                    m_after =                        new EncodingImpl(                            m_encoding,                            m_explLast + 1,                            m_last,                            codePoint);                ret = m_after.isInEncoding(high,low);            } else {                // The unicode value is in the range we explitly handle                final int idx = codePoint - m_explFirst;                                // If we already know the answer, just return it.                if (m_alreadyKnown[idx])                    ret = m_isInEncoding[idx];                else {                    // We don't know the answer, so find out,                    // which may be expensive, then cache the answer                     ret = inEncoding(high, low, m_encoding);                    m_alreadyKnown[idx] = true;                    m_isInEncoding[idx] = ret;                }            }            return ret;        }

⌨️ 快捷键说明

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