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 + -
显示快捷键?