jaxp/src/com/sun/org/apache/xml/internal/serializer/SerializerTraceWriter.java
author lana
Tue, 18 Mar 2014 17:49:48 -0700
changeset 23377 2af1ddf102a4
parent 12457 c348e06f0e82
permissions -rw-r--r--
Merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6
7f561c08de6b Initial load
duke
parents:
diff changeset
     1
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
     2
 * reserved comment block
7f561c08de6b Initial load
duke
parents:
diff changeset
     3
 * DO NOT REMOVE OR ALTER!
7f561c08de6b Initial load
duke
parents:
diff changeset
     4
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
     5
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
     6
 * Copyright 2003-2004 The Apache Software Foundation.
7f561c08de6b Initial load
duke
parents:
diff changeset
     7
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
     8
 * Licensed under the Apache License, Version 2.0 (the "License");
7f561c08de6b Initial load
duke
parents:
diff changeset
     9
 * you may not use this file except in compliance with the License.
7f561c08de6b Initial load
duke
parents:
diff changeset
    10
 * You may obtain a copy of the License at
7f561c08de6b Initial load
duke
parents:
diff changeset
    11
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    12
 *     http://www.apache.org/licenses/LICENSE-2.0
7f561c08de6b Initial load
duke
parents:
diff changeset
    13
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    14
 * Unless required by applicable law or agreed to in writing, software
7f561c08de6b Initial load
duke
parents:
diff changeset
    15
 * distributed under the License is distributed on an "AS IS" BASIS,
7f561c08de6b Initial load
duke
parents:
diff changeset
    16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7f561c08de6b Initial load
duke
parents:
diff changeset
    17
 * See the License for the specific language governing permissions and
7f561c08de6b Initial load
duke
parents:
diff changeset
    18
 * limitations under the License.
7f561c08de6b Initial load
duke
parents:
diff changeset
    19
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    20
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
    21
 * $Id: SerializerTraceWriter.java,v 1.2.4.1 2005/09/15 08:15:25 suresh_emailid Exp $
7f561c08de6b Initial load
duke
parents:
diff changeset
    22
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    23
package com.sun.org.apache.xml.internal.serializer;
7f561c08de6b Initial load
duke
parents:
diff changeset
    24
7f561c08de6b Initial load
duke
parents:
diff changeset
    25
import java.io.IOException;
7f561c08de6b Initial load
duke
parents:
diff changeset
    26
import java.io.OutputStream;
7f561c08de6b Initial load
duke
parents:
diff changeset
    27
import java.io.Writer;
7f561c08de6b Initial load
duke
parents:
diff changeset
    28
7f561c08de6b Initial load
duke
parents:
diff changeset
    29
/**
7f561c08de6b Initial load
duke
parents:
diff changeset
    30
 * This class wraps the real writer, it only purpose is to send
7f561c08de6b Initial load
duke
parents:
diff changeset
    31
 * CHARACTERTOSTREAM events to the trace listener.
7f561c08de6b Initial load
duke
parents:
diff changeset
    32
 * Each method immediately sends the call to the wrapped writer unchanged, but
7f561c08de6b Initial load
duke
parents:
diff changeset
    33
 * in addition it collects characters to be issued to a trace listener.
7f561c08de6b Initial load
duke
parents:
diff changeset
    34
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    35
 * In this way the trace
7f561c08de6b Initial load
duke
parents:
diff changeset
    36
 * listener knows what characters have been written to the output Writer.
7f561c08de6b Initial load
duke
parents:
diff changeset
    37
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    38
 * There may still be differences in what the trace events say is going to the
7f561c08de6b Initial load
duke
parents:
diff changeset
    39
 * output writer and what is really going there. These differences will be due
7f561c08de6b Initial load
duke
parents:
diff changeset
    40
 * to the fact that this class is UTF-8 encoding before emiting the trace event
7f561c08de6b Initial load
duke
parents:
diff changeset
    41
 * and the underlying writer may not be UTF-8 encoding. There may also be
7f561c08de6b Initial load
duke
parents:
diff changeset
    42
 * encoding differences.  So the main pupose of this class is to provide a
7f561c08de6b Initial load
duke
parents:
diff changeset
    43
 * resonable facsimile of the true output.
7f561c08de6b Initial load
duke
parents:
diff changeset
    44
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    45
 * @xsl.usage internal
7f561c08de6b Initial load
duke
parents:
diff changeset
    46
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    47
final class SerializerTraceWriter extends Writer implements WriterChain
7f561c08de6b Initial load
duke
parents:
diff changeset
    48
{
7f561c08de6b Initial load
duke
parents:
diff changeset
    49
7f561c08de6b Initial load
duke
parents:
diff changeset
    50
    /** The real writer to immediately write to.
7f561c08de6b Initial load
duke
parents:
diff changeset
    51
     * This reference may be null, in which case nothing is written out, but
7f561c08de6b Initial load
duke
parents:
diff changeset
    52
     * only the trace events are fired for output.
7f561c08de6b Initial load
duke
parents:
diff changeset
    53
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    54
    private final java.io.Writer m_writer;
7f561c08de6b Initial load
duke
parents:
diff changeset
    55
7f561c08de6b Initial load
duke
parents:
diff changeset
    56
    /** The tracer to send events to */
7f561c08de6b Initial load
duke
parents:
diff changeset
    57
    private final SerializerTrace m_tracer;
7f561c08de6b Initial load
duke
parents:
diff changeset
    58
7f561c08de6b Initial load
duke
parents:
diff changeset
    59
    /** The size of the internal buffer, just to keep too many
7f561c08de6b Initial load
duke
parents:
diff changeset
    60
     * events from being sent to the tracer
7f561c08de6b Initial load
duke
parents:
diff changeset
    61
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    62
    private int buf_length;
7f561c08de6b Initial load
duke
parents:
diff changeset
    63
7f561c08de6b Initial load
duke
parents:
diff changeset
    64
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    65
     * Internal buffer to collect the characters to go to the trace listener.
7f561c08de6b Initial load
duke
parents:
diff changeset
    66
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
    67
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    68
    private byte buf[];
7f561c08de6b Initial load
duke
parents:
diff changeset
    69
7f561c08de6b Initial load
duke
parents:
diff changeset
    70
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    71
     * How many bytes have been collected and still need to go to trace
7f561c08de6b Initial load
duke
parents:
diff changeset
    72
     * listener.
7f561c08de6b Initial load
duke
parents:
diff changeset
    73
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    74
    private int count;
7f561c08de6b Initial load
duke
parents:
diff changeset
    75
7f561c08de6b Initial load
duke
parents:
diff changeset
    76
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    77
     * Creates or replaces the internal buffer, and makes sure it has a few
7f561c08de6b Initial load
duke
parents:
diff changeset
    78
     * extra bytes slight overflow of the last UTF8 encoded character.
7f561c08de6b Initial load
duke
parents:
diff changeset
    79
     * @param size
7f561c08de6b Initial load
duke
parents:
diff changeset
    80
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    81
    private void setBufferSize(int size)
7f561c08de6b Initial load
duke
parents:
diff changeset
    82
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
    83
        buf = new byte[size + 3];
7f561c08de6b Initial load
duke
parents:
diff changeset
    84
        buf_length = size;
7f561c08de6b Initial load
duke
parents:
diff changeset
    85
        count = 0;
7f561c08de6b Initial load
duke
parents:
diff changeset
    86
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
    87
7f561c08de6b Initial load
duke
parents:
diff changeset
    88
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    89
     * Constructor.
7f561c08de6b Initial load
duke
parents:
diff changeset
    90
     * If the writer passed in is null, then this SerializerTraceWriter will
7f561c08de6b Initial load
duke
parents:
diff changeset
    91
     * only signal trace events of what would have been written to that writer.
7f561c08de6b Initial load
duke
parents:
diff changeset
    92
     * If the writer passed in is not null then the trace events will mirror
7f561c08de6b Initial load
duke
parents:
diff changeset
    93
     * what is going to that writer. In this way tools, such as a debugger, can
7f561c08de6b Initial load
duke
parents:
diff changeset
    94
     * gather information on what is being written out.
7f561c08de6b Initial load
duke
parents:
diff changeset
    95
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
    96
     * @param out the Writer to write to (possibly null)
7f561c08de6b Initial load
duke
parents:
diff changeset
    97
     * @param tracer the tracer to inform that characters are being written
7f561c08de6b Initial load
duke
parents:
diff changeset
    98
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    99
    public SerializerTraceWriter(Writer out, SerializerTrace tracer)
7f561c08de6b Initial load
duke
parents:
diff changeset
   100
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   101
        m_writer = out;
7f561c08de6b Initial load
duke
parents:
diff changeset
   102
        m_tracer = tracer;
7f561c08de6b Initial load
duke
parents:
diff changeset
   103
        setBufferSize(1024);
7f561c08de6b Initial load
duke
parents:
diff changeset
   104
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   105
7f561c08de6b Initial load
duke
parents:
diff changeset
   106
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   107
     * Flush out the collected characters by sending them to the trace
7f561c08de6b Initial load
duke
parents:
diff changeset
   108
     * listener.  These characters are never written to the real writer
7f561c08de6b Initial load
duke
parents:
diff changeset
   109
     * (m_writer) because that has already happened with every method
7f561c08de6b Initial load
duke
parents:
diff changeset
   110
     * call. This method simple informs the listener of what has already
7f561c08de6b Initial load
duke
parents:
diff changeset
   111
     * happened.
7f561c08de6b Initial load
duke
parents:
diff changeset
   112
     * @throws IOException
7f561c08de6b Initial load
duke
parents:
diff changeset
   113
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   114
    private void flushBuffer() throws IOException
7f561c08de6b Initial load
duke
parents:
diff changeset
   115
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   116
7f561c08de6b Initial load
duke
parents:
diff changeset
   117
        // Just for tracing purposes
7f561c08de6b Initial load
duke
parents:
diff changeset
   118
        if (count > 0)
7f561c08de6b Initial load
duke
parents:
diff changeset
   119
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
   120
            char[] chars = new char[count];
7f561c08de6b Initial load
duke
parents:
diff changeset
   121
            for(int i=0; i<count; i++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   122
                chars[i] = (char) buf[i];
7f561c08de6b Initial load
duke
parents:
diff changeset
   123
7f561c08de6b Initial load
duke
parents:
diff changeset
   124
            if (m_tracer != null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   125
                m_tracer.fireGenerateEvent(
7f561c08de6b Initial load
duke
parents:
diff changeset
   126
                    SerializerTrace.EVENTTYPE_OUTPUT_CHARACTERS,
7f561c08de6b Initial load
duke
parents:
diff changeset
   127
                    chars,
7f561c08de6b Initial load
duke
parents:
diff changeset
   128
                    0,
7f561c08de6b Initial load
duke
parents:
diff changeset
   129
                    chars.length);
7f561c08de6b Initial load
duke
parents:
diff changeset
   130
7f561c08de6b Initial load
duke
parents:
diff changeset
   131
            count = 0;
7f561c08de6b Initial load
duke
parents:
diff changeset
   132
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   133
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   134
7f561c08de6b Initial load
duke
parents:
diff changeset
   135
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   136
     * Flush the internal buffer and flush the Writer
7f561c08de6b Initial load
duke
parents:
diff changeset
   137
     * @see java.io.Writer#flush()
7f561c08de6b Initial load
duke
parents:
diff changeset
   138
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   139
    public void flush() throws java.io.IOException
7f561c08de6b Initial load
duke
parents:
diff changeset
   140
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   141
        // send to the real writer
7f561c08de6b Initial load
duke
parents:
diff changeset
   142
        if (m_writer != null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   143
            m_writer.flush();
7f561c08de6b Initial load
duke
parents:
diff changeset
   144
7f561c08de6b Initial load
duke
parents:
diff changeset
   145
        // from here on just for tracing purposes
7f561c08de6b Initial load
duke
parents:
diff changeset
   146
        flushBuffer();
7f561c08de6b Initial load
duke
parents:
diff changeset
   147
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   148
7f561c08de6b Initial load
duke
parents:
diff changeset
   149
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   150
     * Flush the internal buffer and close the Writer
7f561c08de6b Initial load
duke
parents:
diff changeset
   151
     * @see java.io.Writer#close()
7f561c08de6b Initial load
duke
parents:
diff changeset
   152
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   153
    public void close() throws java.io.IOException
7f561c08de6b Initial load
duke
parents:
diff changeset
   154
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   155
        // send to the real writer
7f561c08de6b Initial load
duke
parents:
diff changeset
   156
        if (m_writer != null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   157
            m_writer.close();
7f561c08de6b Initial load
duke
parents:
diff changeset
   158
7f561c08de6b Initial load
duke
parents:
diff changeset
   159
        // from here on just for tracing purposes
7f561c08de6b Initial load
duke
parents:
diff changeset
   160
        flushBuffer();
7f561c08de6b Initial load
duke
parents:
diff changeset
   161
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   162
7f561c08de6b Initial load
duke
parents:
diff changeset
   163
7f561c08de6b Initial load
duke
parents:
diff changeset
   164
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   165
     * Write a single character.  The character to be written is contained in
7f561c08de6b Initial load
duke
parents:
diff changeset
   166
     * the 16 low-order bits of the given integer value; the 16 high-order bits
7f561c08de6b Initial load
duke
parents:
diff changeset
   167
     * are ignored.
7f561c08de6b Initial load
duke
parents:
diff changeset
   168
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   169
     * <p> Subclasses that intend to support efficient single-character output
7f561c08de6b Initial load
duke
parents:
diff changeset
   170
     * should override this method.
7f561c08de6b Initial load
duke
parents:
diff changeset
   171
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   172
     * @param c  int specifying a character to be written.
7f561c08de6b Initial load
duke
parents:
diff changeset
   173
     * @exception  IOException  If an I/O error occurs
7f561c08de6b Initial load
duke
parents:
diff changeset
   174
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   175
    public void write(final int c) throws IOException
7f561c08de6b Initial load
duke
parents:
diff changeset
   176
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   177
        // send to the real writer
7f561c08de6b Initial load
duke
parents:
diff changeset
   178
        if (m_writer != null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   179
            m_writer.write(c);
7f561c08de6b Initial load
duke
parents:
diff changeset
   180
7f561c08de6b Initial load
duke
parents:
diff changeset
   181
        // ---------- from here on just collect for tracing purposes
7f561c08de6b Initial load
duke
parents:
diff changeset
   182
7f561c08de6b Initial load
duke
parents:
diff changeset
   183
        /* If we are close to the end of the buffer then flush it.
7f561c08de6b Initial load
duke
parents:
diff changeset
   184
         * Remember the buffer can hold a few more characters than buf_length
7f561c08de6b Initial load
duke
parents:
diff changeset
   185
         */
7f561c08de6b Initial load
duke
parents:
diff changeset
   186
        if (count >= buf_length)
7f561c08de6b Initial load
duke
parents:
diff changeset
   187
            flushBuffer();
7f561c08de6b Initial load
duke
parents:
diff changeset
   188
7f561c08de6b Initial load
duke
parents:
diff changeset
   189
        if (c < 0x80)
7f561c08de6b Initial load
duke
parents:
diff changeset
   190
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
   191
            buf[count++] = (byte) (c);
7f561c08de6b Initial load
duke
parents:
diff changeset
   192
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   193
        else if (c < 0x800)
7f561c08de6b Initial load
duke
parents:
diff changeset
   194
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
   195
            buf[count++] = (byte) (0xc0 + (c >> 6));
7f561c08de6b Initial load
duke
parents:
diff changeset
   196
            buf[count++] = (byte) (0x80 + (c & 0x3f));
7f561c08de6b Initial load
duke
parents:
diff changeset
   197
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   198
        else
7f561c08de6b Initial load
duke
parents:
diff changeset
   199
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
   200
            buf[count++] = (byte) (0xe0 + (c >> 12));
7f561c08de6b Initial load
duke
parents:
diff changeset
   201
            buf[count++] = (byte) (0x80 + ((c >> 6) & 0x3f));
7f561c08de6b Initial load
duke
parents:
diff changeset
   202
            buf[count++] = (byte) (0x80 + (c & 0x3f));
7f561c08de6b Initial load
duke
parents:
diff changeset
   203
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   204
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   205
7f561c08de6b Initial load
duke
parents:
diff changeset
   206
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   207
     * Write a portion of an array of characters.
7f561c08de6b Initial load
duke
parents:
diff changeset
   208
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   209
     * @param  chars  Array of characters
7f561c08de6b Initial load
duke
parents:
diff changeset
   210
     * @param  start   Offset from which to start writing characters
7f561c08de6b Initial load
duke
parents:
diff changeset
   211
     * @param  length   Number of characters to write
7f561c08de6b Initial load
duke
parents:
diff changeset
   212
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   213
     * @exception  IOException  If an I/O error occurs
7f561c08de6b Initial load
duke
parents:
diff changeset
   214
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   215
     * @throws java.io.IOException
7f561c08de6b Initial load
duke
parents:
diff changeset
   216
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   217
    public void write(final char chars[], final int start, final int length)
7f561c08de6b Initial load
duke
parents:
diff changeset
   218
        throws java.io.IOException
7f561c08de6b Initial load
duke
parents:
diff changeset
   219
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   220
        // send to the real writer
7f561c08de6b Initial load
duke
parents:
diff changeset
   221
        if (m_writer != null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   222
            m_writer.write(chars, start, length);
7f561c08de6b Initial load
duke
parents:
diff changeset
   223
7f561c08de6b Initial load
duke
parents:
diff changeset
   224
        // from here on just collect for tracing purposes
7f561c08de6b Initial load
duke
parents:
diff changeset
   225
        int lengthx3 = (length << 1) + length;
7f561c08de6b Initial load
duke
parents:
diff changeset
   226
7f561c08de6b Initial load
duke
parents:
diff changeset
   227
        if (lengthx3 >= buf_length)
7f561c08de6b Initial load
duke
parents:
diff changeset
   228
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
   229
7f561c08de6b Initial load
duke
parents:
diff changeset
   230
            /* If the request length exceeds the size of the output buffer,
7f561c08de6b Initial load
duke
parents:
diff changeset
   231
              * flush the output buffer and make the buffer bigger to handle.
7f561c08de6b Initial load
duke
parents:
diff changeset
   232
              */
7f561c08de6b Initial load
duke
parents:
diff changeset
   233
7f561c08de6b Initial load
duke
parents:
diff changeset
   234
            flushBuffer();
7f561c08de6b Initial load
duke
parents:
diff changeset
   235
            setBufferSize(2 * lengthx3);
7f561c08de6b Initial load
duke
parents:
diff changeset
   236
7f561c08de6b Initial load
duke
parents:
diff changeset
   237
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   238
7f561c08de6b Initial load
duke
parents:
diff changeset
   239
        if (lengthx3 > buf_length - count)
7f561c08de6b Initial load
duke
parents:
diff changeset
   240
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
   241
            flushBuffer();
7f561c08de6b Initial load
duke
parents:
diff changeset
   242
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   243
7f561c08de6b Initial load
duke
parents:
diff changeset
   244
        final int n = length + start;
7f561c08de6b Initial load
duke
parents:
diff changeset
   245
        for (int i = start; i < n; i++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   246
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
   247
            final char c = chars[i];
7f561c08de6b Initial load
duke
parents:
diff changeset
   248
7f561c08de6b Initial load
duke
parents:
diff changeset
   249
            if (c < 0x80)
7f561c08de6b Initial load
duke
parents:
diff changeset
   250
                buf[count++] = (byte) (c);
7f561c08de6b Initial load
duke
parents:
diff changeset
   251
            else if (c < 0x800)
7f561c08de6b Initial load
duke
parents:
diff changeset
   252
            {
7f561c08de6b Initial load
duke
parents:
diff changeset
   253
                buf[count++] = (byte) (0xc0 + (c >> 6));
7f561c08de6b Initial load
duke
parents:
diff changeset
   254
                buf[count++] = (byte) (0x80 + (c & 0x3f));
7f561c08de6b Initial load
duke
parents:
diff changeset
   255
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   256
            else
7f561c08de6b Initial load
duke
parents:
diff changeset
   257
            {
7f561c08de6b Initial load
duke
parents:
diff changeset
   258
                buf[count++] = (byte) (0xe0 + (c >> 12));
7f561c08de6b Initial load
duke
parents:
diff changeset
   259
                buf[count++] = (byte) (0x80 + ((c >> 6) & 0x3f));
7f561c08de6b Initial load
duke
parents:
diff changeset
   260
                buf[count++] = (byte) (0x80 + (c & 0x3f));
7f561c08de6b Initial load
duke
parents:
diff changeset
   261
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   262
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   263
7f561c08de6b Initial load
duke
parents:
diff changeset
   264
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   265
7f561c08de6b Initial load
duke
parents:
diff changeset
   266
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   267
     * Write a string.
7f561c08de6b Initial load
duke
parents:
diff changeset
   268
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   269
     * @param  s  String to be written
7f561c08de6b Initial load
duke
parents:
diff changeset
   270
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   271
     * @exception  IOException  If an I/O error occurs
7f561c08de6b Initial load
duke
parents:
diff changeset
   272
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   273
    public void write(final String s) throws IOException
7f561c08de6b Initial load
duke
parents:
diff changeset
   274
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   275
        // send to the real writer
7f561c08de6b Initial load
duke
parents:
diff changeset
   276
        if (m_writer != null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   277
            m_writer.write(s);
7f561c08de6b Initial load
duke
parents:
diff changeset
   278
7f561c08de6b Initial load
duke
parents:
diff changeset
   279
        // from here on just collect for tracing purposes
7f561c08de6b Initial load
duke
parents:
diff changeset
   280
        final int length = s.length();
7f561c08de6b Initial load
duke
parents:
diff changeset
   281
7f561c08de6b Initial load
duke
parents:
diff changeset
   282
        // We multiply the length by three since this is the maximum length
7f561c08de6b Initial load
duke
parents:
diff changeset
   283
        // of the characters that we can put into the buffer.  It is possible
7f561c08de6b Initial load
duke
parents:
diff changeset
   284
        // for each Unicode character to expand to three bytes.
7f561c08de6b Initial load
duke
parents:
diff changeset
   285
7f561c08de6b Initial load
duke
parents:
diff changeset
   286
        int lengthx3 = (length << 1) + length;
7f561c08de6b Initial load
duke
parents:
diff changeset
   287
7f561c08de6b Initial load
duke
parents:
diff changeset
   288
        if (lengthx3 >= buf_length)
7f561c08de6b Initial load
duke
parents:
diff changeset
   289
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
   290
7f561c08de6b Initial load
duke
parents:
diff changeset
   291
            /* If the request length exceeds the size of the output buffer,
7f561c08de6b Initial load
duke
parents:
diff changeset
   292
              * flush the output buffer and make the buffer bigger to handle.
7f561c08de6b Initial load
duke
parents:
diff changeset
   293
              */
7f561c08de6b Initial load
duke
parents:
diff changeset
   294
7f561c08de6b Initial load
duke
parents:
diff changeset
   295
            flushBuffer();
7f561c08de6b Initial load
duke
parents:
diff changeset
   296
            setBufferSize(2 * lengthx3);
7f561c08de6b Initial load
duke
parents:
diff changeset
   297
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   298
7f561c08de6b Initial load
duke
parents:
diff changeset
   299
        if (lengthx3 > buf_length - count)
7f561c08de6b Initial load
duke
parents:
diff changeset
   300
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
   301
            flushBuffer();
7f561c08de6b Initial load
duke
parents:
diff changeset
   302
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   303
7f561c08de6b Initial load
duke
parents:
diff changeset
   304
        for (int i = 0; i < length; i++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   305
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
   306
            final char c = s.charAt(i);
7f561c08de6b Initial load
duke
parents:
diff changeset
   307
7f561c08de6b Initial load
duke
parents:
diff changeset
   308
            if (c < 0x80)
7f561c08de6b Initial load
duke
parents:
diff changeset
   309
                buf[count++] = (byte) (c);
7f561c08de6b Initial load
duke
parents:
diff changeset
   310
            else if (c < 0x800)
7f561c08de6b Initial load
duke
parents:
diff changeset
   311
            {
7f561c08de6b Initial load
duke
parents:
diff changeset
   312
                buf[count++] = (byte) (0xc0 + (c >> 6));
7f561c08de6b Initial load
duke
parents:
diff changeset
   313
                buf[count++] = (byte) (0x80 + (c & 0x3f));
7f561c08de6b Initial load
duke
parents:
diff changeset
   314
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   315
            else
7f561c08de6b Initial load
duke
parents:
diff changeset
   316
            {
7f561c08de6b Initial load
duke
parents:
diff changeset
   317
                buf[count++] = (byte) (0xe0 + (c >> 12));
7f561c08de6b Initial load
duke
parents:
diff changeset
   318
                buf[count++] = (byte) (0x80 + ((c >> 6) & 0x3f));
7f561c08de6b Initial load
duke
parents:
diff changeset
   319
                buf[count++] = (byte) (0x80 + (c & 0x3f));
7f561c08de6b Initial load
duke
parents:
diff changeset
   320
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   321
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   322
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   323
7f561c08de6b Initial load
duke
parents:
diff changeset
   324
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   325
     * Get the writer that this one directly wraps.
7f561c08de6b Initial load
duke
parents:
diff changeset
   326
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   327
    public Writer getWriter()
7f561c08de6b Initial load
duke
parents:
diff changeset
   328
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   329
        return m_writer;
7f561c08de6b Initial load
duke
parents:
diff changeset
   330
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   331
7f561c08de6b Initial load
duke
parents:
diff changeset
   332
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   333
     * Get the OutputStream that is the at the end of the
7f561c08de6b Initial load
duke
parents:
diff changeset
   334
     * chain of writers.
7f561c08de6b Initial load
duke
parents:
diff changeset
   335
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   336
    public OutputStream getOutputStream()
7f561c08de6b Initial load
duke
parents:
diff changeset
   337
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   338
        OutputStream retval = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   339
        if (m_writer instanceof WriterChain)
7f561c08de6b Initial load
duke
parents:
diff changeset
   340
            retval = ((WriterChain) m_writer).getOutputStream();
7f561c08de6b Initial load
duke
parents:
diff changeset
   341
        return retval;
7f561c08de6b Initial load
duke
parents:
diff changeset
   342
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   343
}