SerializerTraceWriterpublic class SerializerTraceWriter extends Writer This class wraps the real writer, it only purpose is to send
CHARACTERTOSTREAM events to the trace listener.
Each method immediately sends the call to the wrapped writer unchanged, but
in addition it collects characters to be issued to a trace listener.
In this way the trace
listener knows what characters have been written to the output Writer.
There may still be differences in what the trace events say is going to the
output writer and what is really going there. These differences will be due
to the fact that this class is UTF-8 encoding before emiting the trace event
and the underlying writer may not be UTF-8 encoding. There may also be
encoding differences. So the main pupose of this class is to provide a
resonable facsimile of the true output. |
Fields Summary |
---|
private final Writer | m_writerThe real writer to immediately write to.
This reference may be null, in which case nothing is written out, but
only the trace events are fired for output. | private final SerializerTrace | m_tracerThe tracer to send events to | private int | buf_lengthThe size of the internal buffer, just to keep too many
events from being sent to the tracer | private byte[] | bufInternal buffer to collect the characters to go to the trace listener. | private int | countHow many bytes have been collected and still need to go to trace
listener. |
Constructors Summary |
---|
public SerializerTraceWriter(Writer out, SerializerTrace tracer)Constructor.
If the writer passed in is null, then this SerializerTraceWriter will
only signal trace events of what would have been written to that writer.
If the writer passed in is not null then the trace events will mirror
what is going to that writer. In this way tools, such as a debugger, can
gather information on what is being written out.
m_writer = out;
m_tracer = tracer;
setBufferSize(1024);
|
Methods Summary |
---|
public void | close()Flush the internal buffer and close the Writer
// send to the real writer
if (m_writer != null)
m_writer.close();
// from here on just for tracing purposes
flushBuffer();
| public void | flush()Flush the internal buffer and flush the Writer
// send to the real writer
if (m_writer != null)
m_writer.flush();
// from here on just for tracing purposes
flushBuffer();
| private void | flushBuffer()Flush out the collected characters by sending them to the trace
listener. These characters are never written to the real writer
(m_writer) because that has already happened with every method
call. This method simple informs the listener of what has already
happened.
// Just for tracing purposes
if (count > 0)
{
char[] chars = new char[count];
for(int i=0; i<count; i++)
chars[i] = (char) buf[i];
if (m_tracer != null)
m_tracer.fireGenerateEvent(
SerializerTrace.EVENTTYPE_OUTPUT_CHARACTERS,
chars,
0,
chars.length);
count = 0;
}
| private void | setBufferSize(int size)Creates or replaces the internal buffer, and makes sure it has a few
extra bytes slight overflow of the last UTF8 encoded character.
buf = new byte[size + 3];
buf_length = size;
count = 0;
| public void | write(int c)Write a single character. The character to be written is contained in
the 16 low-order bits of the given integer value; the 16 high-order bits
are ignored.
Subclasses that intend to support efficient single-character output
should override this method.
// send to the real writer
if (m_writer != null)
m_writer.write(c);
// ---------- from here on just collect for tracing purposes
/* If we are close to the end of the buffer then flush it.
* Remember the buffer can hold a few more characters than buf_length
*/
if (count >= buf_length)
flushBuffer();
if (c < 0x80)
{
buf[count++] = (byte) (c);
}
else if (c < 0x800)
{
buf[count++] = (byte) (0xc0 + (c >> 6));
buf[count++] = (byte) (0x80 + (c & 0x3f));
}
else
{
buf[count++] = (byte) (0xe0 + (c >> 12));
buf[count++] = (byte) (0x80 + ((c >> 6) & 0x3f));
buf[count++] = (byte) (0x80 + (c & 0x3f));
}
| public void | write(char[] chars, int start, int length)Write a portion of an array of characters.
// send to the real writer
if (m_writer != null)
m_writer.write(chars, start, length);
// from here on just collect for tracing purposes
int lengthx3 = (length << 1) + length;
if (lengthx3 >= buf_length)
{
/* If the request length exceeds the size of the output buffer,
* flush the output buffer and make the buffer bigger to handle.
*/
flushBuffer();
setBufferSize(2 * lengthx3);
}
if (lengthx3 > buf_length - count)
{
flushBuffer();
}
final int n = length + start;
for (int i = start; i < n; i++)
{
final char c = chars[i];
if (c < 0x80)
buf[count++] = (byte) (c);
else if (c < 0x800)
{
buf[count++] = (byte) (0xc0 + (c >> 6));
buf[count++] = (byte) (0x80 + (c & 0x3f));
}
else
{
buf[count++] = (byte) (0xe0 + (c >> 12));
buf[count++] = (byte) (0x80 + ((c >> 6) & 0x3f));
buf[count++] = (byte) (0x80 + (c & 0x3f));
}
}
| public void | write(java.lang.String s)Write a string.
// send to the real writer
if (m_writer != null)
m_writer.write(s);
// from here on just collect for tracing purposes
final int length = s.length();
// We multiply the length by three since this is the maximum length
// of the characters that we can put into the buffer. It is possible
// for each Unicode character to expand to three bytes.
int lengthx3 = (length << 1) + length;
if (lengthx3 >= buf_length)
{
/* If the request length exceeds the size of the output buffer,
* flush the output buffer and make the buffer bigger to handle.
*/
flushBuffer();
setBufferSize(2 * lengthx3);
}
if (lengthx3 > buf_length - count)
{
flushBuffer();
}
for (int i = 0; i < length; i++)
{
final char c = s.charAt(i);
if (c < 0x80)
buf[count++] = (byte) (c);
else if (c < 0x800)
{
buf[count++] = (byte) (0xc0 + (c >> 6));
buf[count++] = (byte) (0x80 + (c & 0x3f));
}
else
{
buf[count++] = (byte) (0xe0 + (c >> 12));
buf[count++] = (byte) (0x80 + ((c >> 6) & 0x3f));
buf[count++] = (byte) (0x80 + (c & 0x3f));
}
}
|
|