tohtmlstream.java

来自「JAVA的一些源码 JAVA2 STANDARD EDITION DEVELO」· Java 代码 · 共 1,886 行 · 第 1/5 页

JAVA
1,886
字号
            {                elemContext = elemContext.push(namespaceURI,localName,name);                m_elemContext = elemContext;                elemContext.m_elementDesc = elemDesc;                elemContext.m_isRaw = (elemFlags & ElemDesc.RAW) != 0;            }                        if ((elemFlags & ElemDesc.HEADELEM) != 0)            {                // This is the <HEAD> element, do some special processing                closeStartTag();                elemContext.m_startTagOpen = false;                if (!m_omitMetaTag)                {                    if (m_doIndent)                        indent();                    writer.write(                        "<META http-equiv=\"Content-Type\" content=\"text/html; charset=");                    String encoding = getEncoding();                    String encode = Encodings.getMimeEncoding(encoding);                    writer.write(encode);                    writer.write("\">");                }            }        }        catch (IOException e)        {            throw new SAXException(e);        }    }    /**     *  Receive notification of the end of an element.     *     *     *  @param namespaceURI     *  @param localName     *  @param name The element type name     *  @throws org.xml.sax.SAXException Any SAX exception, possibly     *             wrapping another exception.     */    public final void endElement(        final String namespaceURI,        final String localName,        final String name)        throws org.xml.sax.SAXException    {        // deal with any pending issues        if (m_cdataTagOpen)            closeCDATA();        // if the element has a namespace, treat it like XML, not HTML        if (null != namespaceURI && namespaceURI.length() > 0)        {            super.endElement(namespaceURI, localName, name);            return;        }        try        {            ElemContext elemContext = m_elemContext;            final ElemDesc elemDesc = elemContext.m_elementDesc;            final int elemFlags = elemDesc.getFlags();            final boolean elemEmpty = (elemFlags & ElemDesc.EMPTY) != 0;            // deal with any indentation issues            if (m_doIndent)            {                final boolean isBlockElement = (elemFlags&ElemDesc.BLOCK) != 0;                boolean shouldIndent = false;                if (m_ispreserve)                {                    m_ispreserve = false;                }                else if (m_doIndent && (!m_inBlockElem || isBlockElement))                {                    m_startNewLine = true;                    shouldIndent = true;                }                if (!elemContext.m_startTagOpen && shouldIndent)                    indent(elemContext.m_currentElemDepth - 1);                m_inBlockElem = !isBlockElement;            }            final java.io.Writer writer = m_writer;            if (!elemContext.m_startTagOpen)            {                writer.write("</");                writer.write(name);                writer.write('>');            }            else            {                // the start-tag open when this method was called,                // so we need to process it now.                                if (m_tracer != null)                    super.fireStartElem(name);                // the starting tag was still open when we received this endElement() call                // so we need to process any gathered attributes NOW, before they go away.                int nAttrs = m_attributes.getLength();                if (nAttrs > 0)                {                    processAttributes(m_writer, nAttrs);                    // clear attributes object for re-use with next element                    m_attributes.clear();                }                if (!elemEmpty)                {                    // As per Dave/Paul recommendation 12/06/2000                    // if (shouldIndent)                    // writer.write('>');                    //  indent(m_currentIndent);                    writer.write("></");                    writer.write(name);                    writer.write('>');                }                else                {                    writer.write('>');                }            }                        // clean up because the element has ended            if ((elemFlags & ElemDesc.WHITESPACESENSITIVE) != 0)                m_ispreserve = true;            m_isprevtext = false;            // fire off the end element event            if (m_tracer != null)                super.fireEndElem(name);                                                   // OPTIMIZE-EMPTY                            if (elemEmpty)            {                // a quick exit if the HTML element had no children.                // This block of code can be removed if the corresponding block of code                // in startElement() also labeled with "OPTIMIZE-EMPTY" is also removed                m_elemContext = elemContext.m_prev;                return;            }            // some more clean because the element has ended.             if (!elemContext.m_startTagOpen)            {                if (m_doIndent && !m_preserves.isEmpty())                    m_preserves.pop();            }            m_elemContext = elemContext.m_prev;//            m_isRawStack.pop();        }        catch (IOException e)        {            throw new SAXException(e);        }    }    /**     * Process an attribute.     * @param   writer The writer to write the processed output to.     * @param   name   The name of the attribute.     * @param   value   The value of the attribute.     * @param   elemDesc The description of the HTML element      *           that has this attribute.     *     * @throws org.xml.sax.SAXException     */    protected void processAttribute(        java.io.Writer writer,        String name,        String value,        ElemDesc elemDesc)        throws IOException    {        writer.write(' ');        if (   ((value.length() == 0) || value.equalsIgnoreCase(name))            && elemDesc != null             && elemDesc.isAttrFlagSet(name, ElemDesc.ATTREMPTY))        {            writer.write(name);        }        else        {            // %REVIEW% %OPT%            // Two calls to single-char write may NOT            // be more efficient than one to string-write...            writer.write(name);            writer.write("=\"");            if (   elemDesc != null                && elemDesc.isAttrFlagSet(name, ElemDesc.ATTRURL))                writeAttrURI(writer, value, m_specialEscapeURLs);            else                writeAttrString(writer, value, this.getEncoding());            writer.write('"');        }    }    /**     * Tell if a character is an ASCII digit.     */    private boolean isASCIIDigit(char c)    {        return (c >= '0' && c <= '9');    }    /**     * Make an integer into an HH hex value.     * Does no checking on the size of the input, since this      * is only meant to be used locally by writeAttrURI.     *      * @param i must be a value less than 255.     *      * @return should be a two character string.     */    private static String makeHHString(int i)    {        String s = Integer.toHexString(i).toUpperCase();        if (s.length() == 1)        {            s = "0" + s;        }        return s;    }    /**    * Dmitri Ilyin: Makes sure if the String is HH encoded sign.    * @param str must be 2 characters long    *    * @return true or false    */    private boolean isHHSign(String str)    {        boolean sign = true;        try        {            char r = (char) Integer.parseInt(str, 16);        }        catch (NumberFormatException e)        {            sign = false;        }        return sign;    }    /**     * Write the specified <var>string</var> after substituting non ASCII characters,     * with <CODE>%HH</CODE>, where HH is the hex of the byte value.     *     * @param   string      String to convert to XML format.     * @param doURLEscaping True if we should try to encode as      *                      per http://www.ietf.org/rfc/rfc2396.txt.     *     * @throws org.xml.sax.SAXException if a bad surrogate pair is detected.     */    public void writeAttrURI(        final java.io.Writer writer, String string, boolean doURLEscaping)        throws IOException    {        // http://www.ietf.org/rfc/rfc2396.txt says:        // A URI is always in an "escaped" form, since escaping or unescaping a        // completed URI might change its semantics.  Normally, the only time        // escape encodings can safely be made is when the URI is being created        // from its component parts; each component may have its own set of        // characters that are reserved, so only the mechanism responsible for        // generating or interpreting that component can determine whether or        // not escaping a character will change its semantics. Likewise, a URI        // must be separated into its components before the escaped characters        // within those components can be safely decoded.        //        // ...So we do our best to do limited escaping of the URL, without         // causing damage.  If the URL is already properly escaped, in theory, this         // function should not change the string value.        final int end = string.length();        if (end > m_attrBuff.length)        {           m_attrBuff = new char[end*2 + 1];                       }        string.getChars(0,end, m_attrBuff, 0);         final char[] chars = m_attrBuff;        int cleanStart = 0;        int cleanLength = 0;                        char ch = 0;        for (int i = 0; i < end; i++)        {            ch = chars[i];            if ((ch < 32) || (ch > 126))            {                if (cleanLength > 0)                {                    writer.write(chars, cleanStart, cleanLength);                    cleanLength = 0;                }                if (doURLEscaping)                {                    // Encode UTF16 to UTF8.                    // Reference is Unicode, A Primer, by Tony Graham.                    // Page 92.                    // Note that Kay doesn't escape 0x20...                    //  if(ch == 0x20) // Not sure about this... -sb                    //  {                    //    writer.write(ch);                    //  }                    //  else                     if (ch <= 0x7F)                    {                        writer.write('%');                        writer.write(makeHHString(ch));                    }                    else if (ch <= 0x7FF)                    {                        // Clear low 6 bits before rotate, put high 4 bits in low byte,                         // and set two high bits.                        int high = (ch >> 6) | 0xC0;                        int low = (ch & 0x3F) | 0x80;                        // First 6 bits, + high bit                        writer.write('%');                        writer.write(makeHHString(high));                        writer.write('%');                        writer.write(makeHHString(low));                    }                    else if (isUTF16Surrogate(ch)) // high surrogate                    {                        // I'm sure this can be done in 3 instructions, but I choose                         // to try and do it exactly like it is done in the book, at least                         // until we are sure this is totally clean.  I don't think performance                         // is a big issue with this particular function, though I could be                         // wrong.  Also, the stuff below clearly does more masking than                         // it needs to do.                        // Clear high 6 bits.                        int highSurrogate = ((int) ch) & 0x03FF;                        // Middle 4 bits (wwww) + 1                        // "Note that the value of wwww from the high surrogate bit pattern                        // is incremented to make the uuuuu bit pattern in the scalar value                         // so the surrogate pair don't address the BMP."                        int wwww = ((highSurrogate & 0x03C0) >> 6);                        int uuuuu = wwww + 1;                        // next 4 bits                        int zzzz = (highSurrogate & 0x003C) >> 2;                        // low 2 bits                        int yyyyyy = ((highSurrogate & 0x0003) << 4) & 0x30;                        // Get low surrogate character.                        ch = chars[++i];                        // Clear high 6 bits.                        int lowSurrogate = ((int) ch) & 0x03FF;                        // put the middle 4 bits into the bottom of yyyyyy (byte 3)                        yyyyyy = yyyyyy | ((lowSurrogate & 0x03C0) >> 6);                        // bottom 6 bits.                        int xxxxxx = (lowSurrogate & 0x003F);                        int byte1 = 0xF0 | (uuuuu >> 2); // top 3 bits of uuuuu                        int byte2 =                            0x80 | (((uuuuu & 0x03) << 4) & 0x30) | zzzz;                        int byte3 = 0x80 | yyyyyy;                        int byte4 = 0x80 | xxxxxx;                        writer.write('%');

⌨️ 快捷键说明

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