/*
 * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
 *
 * The Apache Software License, Version 1.1
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Caucho Technology (http://www.caucho.com/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
 *    endorse or promote products derived from this software without prior
 *    written permission. For written permission, please contact
 *    info@caucho.com.
 *
 * 5. Products derived from this software may not be called "Resin"
 *    nor may "Resin" appear in their names without prior written
 *    permission of Caucho Technology.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @author Scott Ferguson
 */

package com.alibaba.com.caucho.hessian.io;

import com.alibaba.com.caucho.hessian.util.IdentityIntMap;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;

/**
 * Output stream for Hessian 2 requests.
 *
 * <p>Since HessianOutput does not depend on any classes other than
 * in the JDK, it can be extracted independently into a smaller package.
 *
 * <p>HessianOutput is unbuffered, so any client needs to provide
 * its own buffering.
 *
 * <pre>
 * OutputStream os = ...; // from http connection
 * Hessian2Output out = new Hessian2Output(os);
 * String value;
 *
 * out.startCall("hello", 1); // start hello call
 * out.writeString("arg1");   // write a string argument
 * out.completeCall();        // complete the call
 * </pre>
 */
public class Hessian2Output
        extends AbstractHessianOutput
        implements Hessian2Constants {
    // should match Resin buffer size for perf
    public final static int SIZE = 8 * 1024;
    // map of references
    private final IdentityIntMap _refs
            = new IdentityIntMap(256);
    // map of classes
    private final IdentityIntMap _classRefs
            = new IdentityIntMap(256);
    private final byte[] _buffer = new byte[SIZE];
    // the output stream/
    protected OutputStream _os;
    private int _refCount = 0;
    private boolean _isCloseStreamOnClose;
    // map of types
    private HashMap<String, Integer> _typeRefs;
    private int _offset;

    private boolean _isPacket;

    private boolean _isUnshared;

    /**
     * Creates a new Hessian output stream, initialized with an
     * underlying output stream.
     *
     * @param os the underlying output stream.
     */
    public Hessian2Output() {
    }

    /**
     * Creates a new Hessian output stream, initialized with an
     * underlying output stream.
     *
     * @param os the underlying output stream.
     */
    public Hessian2Output(OutputStream os) {
        init(os);
    }

    @Override
    public void init(OutputStream os) {
        reset();

        _os = os;
    }

    public void initPacket(OutputStream os) {
        resetReferences();

        _os = os;
    }

    public boolean isCloseStreamOnClose() {
        return _isCloseStreamOnClose;
    }

    public void setCloseStreamOnClose(boolean isClose) {
        _isCloseStreamOnClose = isClose;
    }

    /**
     * Sets hessian to be "unshared", meaning it will not detect
     * duplicate or circular references.
     */
    @Override
    public boolean setUnshared(boolean isUnshared) {
        boolean oldIsUnshared = _isUnshared;

        _isUnshared = isUnshared;

        return oldIsUnshared;
    }

    /**
     * Writes a complete method call.
     */
    @Override
    public void call(String method, Object[] args)
            throws IOException {
        writeVersion();

        int length = args != null ? args.length : 0;

        startCall(method, length);

        for (int i = 0; i < length; i++) {
            writeObject(args[i]);
        }

        completeCall();

        flush();
    }

    /**
     * Starts the method call.  Clients would use <code>startCall</code>
     * instead of <code>call</code> if they wanted finer control over
     * writing the arguments, or needed to write headers.
     *
     * <code><pre>
     * C
     * string # method name
     * int    # arg count
     * </pre></code>
     *
     * @param method the method name to call.
     */
    @Override
    public void startCall(String method, int length)
            throws IOException {
        int offset = _offset;

        if (SIZE < offset + 32) {
            flushBuffer();
            offset = _offset;
        }

        byte[] buffer = _buffer;

        buffer[_offset++] = (byte) 'C';

        writeString(method);
        writeInt(length);
    }

    /**
     * Writes the call tag.  This would be followed by the
     * method and the arguments
     *
     * <code><pre>
     * C
     * </pre></code>
     *
     * @param method the method name to call.
     */
    @Override
    public void startCall()
            throws IOException {
        flushIfFull();

        _buffer[_offset++] = (byte) 'C';
    }

    /**
     * Starts an envelope.
     *
     * <code><pre>
     * E major minor
     * m b16 b8 method-name
     * </pre></code>
     *
     * @param method the method name to call.
     */
    public void startEnvelope(String method)
            throws IOException {
        int offset = _offset;

        if (SIZE < offset + 32) {
            flushBuffer();
            offset = _offset;
        }

        _buffer[_offset++] = (byte) 'E';

        writeString(method);
    }

    /**
     * Completes an envelope.
     *
     * <p>A successful completion will have a single value:
     *
     * <pre>
     * Z
     * </pre>
     */
    public void completeEnvelope()
            throws IOException {
        flushIfFull();

        _buffer[_offset++] = (byte) 'Z';
    }

    /**
     * Writes the method tag.
     *
     * <code><pre>
     * string
     * </pre></code>
     *
     * @param method the method name to call.
     */
    public void writeMethod(String method)
            throws IOException {
        writeString(method);
    }

    /**
     * Completes.
     *
     * <code><pre>
     * z
     * </pre></code>
     */
    @Override
    public void completeCall()
            throws IOException {
    /*
    flushIfFull();

    _buffer[_offset++] = (byte) 'Z';
    */
    }

    /**
     * Starts the reply
     *
     * <p>A successful completion will have a single value:
     *
     * <pre>
     * R
     * </pre>
     */
    @Override
    public void startReply()
            throws IOException {
        writeVersion();

        flushIfFull();

        _buffer[_offset++] = (byte) 'R';
    }

    public void writeVersion()
            throws IOException {
        flushIfFull();

        _buffer[_offset++] = (byte) 'H';
        _buffer[_offset++] = (byte) 2;
        _buffer[_offset++] = (byte) 0;
    }

    /**
     * Completes reading the reply
     *
     * <p>A successful completion will have a single value:
     *
     * <pre>
     * z
     * </pre>
     */
    @Override
    public void completeReply()
            throws IOException {
    }

    /**
     * Starts a packet
     *
     * <p>A message contains several objects encapsulated by a length</p>
     *
     * <pre>
     * p x02 x00
     * </pre>
     */
    public void startMessage()
            throws IOException {
        flushIfFull();

        _buffer[_offset++] = (byte) 'p';
        _buffer[_offset++] = (byte) 2;
        _buffer[_offset++] = (byte) 0;
    }

    /**
     * Completes reading the message
     *
     * <p>A successful completion will have a single value:
     *
     * <pre>
     * z
     * </pre>
     */
    public void completeMessage()
            throws IOException {
        flushIfFull();

        _buffer[_offset++] = (byte) 'z';
    }

    /**
     * Writes a fault.  The fault will be written
     * as a descriptive string followed by an object:
     *
     * <code><pre>
     * F map
     * </pre></code>
     *
     * <code><pre>
     * F H
     * \x04code
     * \x10the fault code
     *
     * \x07message
     * \x11the fault message
     *
     * \x06detail
     * M\xnnjavax.ejb.FinderException
     *     ...
     * Z
     * Z
     * </pre></code>
     *
     * @param code the fault code, a three digit
     */
    public void writeFault(String code, String message, Object detail)
            throws IOException {
        flushIfFull();

        writeVersion();

        _buffer[_offset++] = (byte) 'F';
        _buffer[_offset++] = (byte) 'H';

        addRef(new Object(), _refCount++, false);

        writeString("code");
        writeString(code);

        writeString("message");
        writeString(message);

        if (detail != null) {
            writeString("detail");
            writeObject(detail);
        }

        flushIfFull();
        _buffer[_offset++] = (byte) 'Z';
    }

    /**
     * Writes any object to the output stream.
     */
    @Override
    public void writeObject(Object object)
            throws IOException {
        if (object == null) {
            writeNull();
            return;
        }

        Serializer serializer
                = findSerializerFactory().getObjectSerializer(object.getClass());

        serializer.writeObject(object, this);
    }

    /**
     * Writes the list header to the stream.  List writers will call
     * <code>writeListBegin</code> followed by the list contents and then
     * call <code>writeListEnd</code>.
     *
     * <code><pre>
     * list ::= V type value* Z
     *      ::= v type int value*
     * </pre></code>
     *
     * @return true for variable lists, false for fixed lists
     */
    public boolean writeListBegin(int length, String type)
            throws IOException {
        flushIfFull();

        if (length < 0) {
            if (type != null) {
                _buffer[_offset++] = (byte) BC_LIST_VARIABLE;
                writeType(type);
            } else
                _buffer[_offset++] = (byte) BC_LIST_VARIABLE_UNTYPED;

            return true;
        } else if (length <= LIST_DIRECT_MAX) {
            if (type != null) {
                _buffer[_offset++] = (byte) (BC_LIST_DIRECT + length);
                writeType(type);
            } else {
                _buffer[_offset++] = (byte) (BC_LIST_DIRECT_UNTYPED + length);
            }

            return false;
        } else {
            if (type != null) {
                _buffer[_offset++] = (byte) BC_LIST_FIXED;
                writeType(type);
            } else {
                _buffer[_offset++] = (byte) BC_LIST_FIXED_UNTYPED;
            }

            writeInt(length);

            return false;
        }
    }

    /**
     * Writes the tail of the list to the stream for a variable-length list.
     */
    public void writeListEnd()
            throws IOException {
        flushIfFull();

        _buffer[_offset++] = (byte) BC_END;
    }

    /**
     * Writes the map header to the stream.  Map writers will call
     * <code>writeMapBegin</code> followed by the map contents and then
     * call <code>writeMapEnd</code>.
     *
     * <code><pre>
     * map ::= M type (<value> <value>)* Z
     *     ::= H (<value> <value>)* Z
     * </pre></code>
     */
    public void writeMapBegin(String type)
            throws IOException {
        if (SIZE < _offset + 32)
            flushBuffer();

        if (type != null) {
            _buffer[_offset++] = BC_MAP;

            writeType(type);
        } else
            _buffer[_offset++] = BC_MAP_UNTYPED;
    }

    /**
     * Writes the tail of the map to the stream.
     */
    public void writeMapEnd()
            throws IOException {
        if (SIZE < _offset + 32)
            flushBuffer();

        _buffer[_offset++] = (byte) BC_END;
    }

    /**
     * Writes the object definition
     *
     * <code><pre>
     * C &lt;string> &lt;int> &lt;string>*
     * </pre></code>
     */
    @Override
    public int writeObjectBegin(String type)
            throws IOException {
        int newRef = _classRefs.size();
        int ref = _classRefs.put(type, newRef, false);

        if (newRef != ref) {
            if (SIZE < _offset + 32)
                flushBuffer();

            if (ref <= OBJECT_DIRECT_MAX) {
                _buffer[_offset++] = (byte) (BC_OBJECT_DIRECT + ref);
            } else {
                _buffer[_offset++] = (byte) 'O';
                writeInt(ref);
            }

            return ref;
        } else {
            if (SIZE < _offset + 32)
                flushBuffer();

            _buffer[_offset++] = (byte) 'C';

            writeString(type);

            return -1;
        }
    }

    /**
     * Writes the tail of the class definition to the stream.
     */
    @Override
    public void writeClassFieldLength(int len)
            throws IOException {
        writeInt(len);
    }

    /**
     * Writes the tail of the object definition to the stream.
     */
    @Override
    public void writeObjectEnd()
            throws IOException {
    }

    /**
     * <code><pre>
     * type ::= string
     *      ::= int
     * </code></pre>
     */
    private void writeType(String type)
            throws IOException {
        flushIfFull();

        int len = type.length();
        if (len == 0) {
            throw new IllegalArgumentException("empty type is not allowed");
        }

        if (_typeRefs == null)
            _typeRefs = new HashMap<String, Integer>();

        Integer typeRefV = (Integer) _typeRefs.get(type);

        if (typeRefV != null) {
            int typeRef = typeRefV.intValue();

            writeInt(typeRef);
        } else {
            _typeRefs.put(type, Integer.valueOf(_typeRefs.size()));

            writeString(type);
        }
    }

    /**
     * Writes a boolean value to the stream.  The boolean will be written
     * with the following syntax:
     *
     * <code><pre>
     * T
     * F
     * </pre></code>
     *
     * @param value the boolean value to write.
     */
    @Override
    public void writeBoolean(boolean value)
            throws IOException {
        if (SIZE < _offset + 16)
            flushBuffer();

        if (value)
            _buffer[_offset++] = (byte) 'T';
        else
            _buffer[_offset++] = (byte) 'F';
    }

    /**
     * Writes an integer value to the stream.  The integer will be written
     * with the following syntax:
     *
     * <code><pre>
     * I b32 b24 b16 b8
     * </pre></code>
     *
     * @param value the integer value to write.
     */
    @Override
    public void writeInt(int value)
            throws IOException {
        int offset = _offset;
        byte[] buffer = _buffer;

        if (SIZE <= offset + 16) {
            flushBuffer();
            offset = _offset;
        }

        if (INT_DIRECT_MIN <= value && value <= INT_DIRECT_MAX)
            buffer[offset++] = (byte) (value + BC_INT_ZERO);
        else if (INT_BYTE_MIN <= value && value <= INT_BYTE_MAX) {
            buffer[offset++] = (byte) (BC_INT_BYTE_ZERO + (value >> 8));
            buffer[offset++] = (byte) (value);
        } else if (INT_SHORT_MIN <= value && value <= INT_SHORT_MAX) {
            buffer[offset++] = (byte) (BC_INT_SHORT_ZERO + (value >> 16));
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) (value);
        } else {
            buffer[offset++] = (byte) ('I');
            buffer[offset++] = (byte) (value >> 24);
            buffer[offset++] = (byte) (value >> 16);
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) (value);
        }

        _offset = offset;
    }

    /**
     * Writes a long value to the stream.  The long will be written
     * with the following syntax:
     *
     * <code><pre>
     * L b64 b56 b48 b40 b32 b24 b16 b8
     * </pre></code>
     *
     * @param value the long value to write.
     */
    public void writeLong(long value)
            throws IOException {
        int offset = _offset;
        byte[] buffer = _buffer;

        if (SIZE <= offset + 16) {
            flushBuffer();
            offset = _offset;
        }

        if (LONG_DIRECT_MIN <= value && value <= LONG_DIRECT_MAX) {
            buffer[offset++] = (byte) (value + BC_LONG_ZERO);
        } else if (LONG_BYTE_MIN <= value && value <= LONG_BYTE_MAX) {
            buffer[offset++] = (byte) (BC_LONG_BYTE_ZERO + (value >> 8));
            buffer[offset++] = (byte) (value);
        } else if (LONG_SHORT_MIN <= value && value <= LONG_SHORT_MAX) {
            buffer[offset++] = (byte) (BC_LONG_SHORT_ZERO + (value >> 16));
            buffer[offset++] = (byte) (value >> 8);
            buffer[offset++] = (byte) (value);
        } else if (-0x80000000L <= value && value <= 0x7fffffffL) {
            buffer[offset + 0] = (byte) BC_LONG_INT;
            buffer[offset + 1] = (byte) (value >> 24);
            buffer[offset + 2] = (byte) (value >> 16);
            buffer[offset + 3] = (byte) (value >> 8);
            buffer[offset + 4] = (byte) (value);

            offset += 5;
        } else {
            buffer[offset + 0] = (byte) 'L';
            buffer[offset + 1] = (byte) (value >> 56);
            buffer[offset + 2] = (byte) (value >> 48);
            buffer[offset + 3] = (byte) (value >> 40);
            buffer[offset + 4] = (byte) (value >> 32);
            buffer[offset + 5] = (byte) (value >> 24);
            buffer[offset + 6] = (byte) (value >> 16);
            buffer[offset + 7] = (byte) (value >> 8);
            buffer[offset + 8] = (byte) (value);

            offset += 9;
        }

        _offset = offset;
    }

    /**
     * Writes a double value to the stream.  The double will be written
     * with the following syntax:
     *
     * <code><pre>
     * D b64 b56 b48 b40 b32 b24 b16 b8
     * </pre></code>
     *
     * @param value the double value to write.
     */
    public void writeDouble(double value)
            throws IOException {
        int offset = _offset;
        byte[] buffer = _buffer;

        if (SIZE <= offset + 16) {
            flushBuffer();
            offset = _offset;
        }

        int intValue = (int) value;

        if (intValue == value) {
            if (intValue == 0) {
                buffer[offset++] = (byte) BC_DOUBLE_ZERO;

                _offset = offset;

                return;
            } else if (intValue == 1) {
                buffer[offset++] = (byte) BC_DOUBLE_ONE;

                _offset = offset;

                return;
            } else if (-0x80 <= intValue && intValue < 0x80) {
                buffer[offset++] = (byte) BC_DOUBLE_BYTE;
                buffer[offset++] = (byte) intValue;

                _offset = offset;

                return;
            } else if (-0x8000 <= intValue && intValue < 0x8000) {
                buffer[offset + 0] = (byte) BC_DOUBLE_SHORT;
                buffer[offset + 1] = (byte) (intValue >> 8);
                buffer[offset + 2] = (byte) intValue;

                _offset = offset + 3;

                return;
            }
        }

        int mills = (int) (value * 1000);

        if (0.001 * mills == value) {
            buffer[offset + 0] = (byte) (BC_DOUBLE_MILL);
            buffer[offset + 1] = (byte) (mills >> 24);
            buffer[offset + 2] = (byte) (mills >> 16);
            buffer[offset + 3] = (byte) (mills >> 8);
            buffer[offset + 4] = (byte) (mills);

            _offset = offset + 5;

            return;
        }

        long bits = Double.doubleToLongBits(value);

        buffer[offset + 0] = (byte) 'D';
        buffer[offset + 1] = (byte) (bits >> 56);
        buffer[offset + 2] = (byte) (bits >> 48);
        buffer[offset + 3] = (byte) (bits >> 40);
        buffer[offset + 4] = (byte) (bits >> 32);
        buffer[offset + 5] = (byte) (bits >> 24);
        buffer[offset + 6] = (byte) (bits >> 16);
        buffer[offset + 7] = (byte) (bits >> 8);
        buffer[offset + 8] = (byte) (bits);

        _offset = offset + 9;
    }

    /**
     * Writes a date to the stream.
     *
     * <code><pre>
     * date ::= d   b7 b6 b5 b4 b3 b2 b1 b0
     *      ::= x65 b3 b2 b1 b0
     * </pre></code>
     *
     * @param time the date in milliseconds from the epoch in UTC
     */
    public void writeUTCDate(long time)
            throws IOException {
        if (SIZE < _offset + 32)
            flushBuffer();

        int offset = _offset;
        byte[] buffer = _buffer;

        if (time % 60000L == 0) {
            // compact date ::= x65 b3 b2 b1 b0

            long minutes = time / 60000L;

            if ((minutes >> 31) == 0 || (minutes >> 31) == -1) {
                buffer[offset++] = (byte) BC_DATE_MINUTE;
                buffer[offset++] = ((byte) (minutes >> 24));
                buffer[offset++] = ((byte) (minutes >> 16));
                buffer[offset++] = ((byte) (minutes >> 8));
                buffer[offset++] = ((byte) (minutes >> 0));

                _offset = offset;
                return;
            }
        }

        buffer[offset++] = (byte) BC_DATE;
        buffer[offset++] = ((byte) (time >> 56));
        buffer[offset++] = ((byte) (time >> 48));
        buffer[offset++] = ((byte) (time >> 40));
        buffer[offset++] = ((byte) (time >> 32));
        buffer[offset++] = ((byte) (time >> 24));
        buffer[offset++] = ((byte) (time >> 16));
        buffer[offset++] = ((byte) (time >> 8));
        buffer[offset++] = ((byte) (time));

        _offset = offset;
    }

    /**
     * Writes a null value to the stream.
     * The null will be written with the following syntax
     *
     * <code><pre>
     * N
     * </pre></code>
     *
     * @param value the string value to write.
     */
    public void writeNull()
            throws IOException {
        int offset = _offset;
        byte[] buffer = _buffer;

        if (SIZE <= offset + 16) {
            flushBuffer();
            offset = _offset;
        }

        buffer[offset++] = 'N';

        _offset = offset;
    }

    /**
     * Writes a string value to the stream using UTF-8 encoding.
     * The string will be written with the following syntax:
     *
     * <code><pre>
     * S b16 b8 string-value
     * </pre></code>
     * <p>
     * If the value is null, it will be written as
     *
     * <code><pre>
     * N
     * </pre></code>
     *
     * @param value the string value to write.
     */
    public void writeString(String value)
            throws IOException {
        int offset = _offset;
        byte[] buffer = _buffer;

        if (SIZE <= offset + 16) {
            flushBuffer();
            offset = _offset;
        }

        if (value == null) {
            buffer[offset++] = (byte) 'N';

            _offset = offset;
        } else {
            int length = value.length();
            int strOffset = 0;

            while (length > 0x8000) {
                int sublen = 0x8000;

                offset = _offset;

                if (SIZE <= offset + 16) {
                    flushBuffer();
                    offset = _offset;
                }

                // chunk can't end in high surrogate
                char tail = value.charAt(strOffset + sublen - 1);

                if (0xd800 <= tail && tail <= 0xdbff)
                    sublen--;

                buffer[offset + 0] = (byte) BC_STRING_CHUNK;
                buffer[offset + 1] = (byte) (sublen >> 8);
                buffer[offset + 2] = (byte) (sublen);

                _offset = offset + 3;

                printString(value, strOffset, sublen);

                length -= sublen;
                strOffset += sublen;
            }

            offset = _offset;

            if (SIZE <= offset + 16) {
                flushBuffer();
                offset = _offset;
            }

            if (length <= STRING_DIRECT_MAX) {
                buffer[offset++] = (byte) (BC_STRING_DIRECT + length);
            } else if (length <= STRING_SHORT_MAX) {
                buffer[offset++] = (byte) (BC_STRING_SHORT + (length >> 8));
                buffer[offset++] = (byte) (length);
            } else {
                buffer[offset++] = (byte) ('S');
                buffer[offset++] = (byte) (length >> 8);
                buffer[offset++] = (byte) (length);
            }

            _offset = offset;

            printString(value, strOffset, length);
        }
    }

    /**
     * Writes a string value to the stream using UTF-8 encoding.
     * The string will be written with the following syntax:
     *
     * <code><pre>
     * S b16 b8 string-value
     * </pre></code>
     * <p>
     * If the value is null, it will be written as
     *
     * <code><pre>
     * N
     * </pre></code>
     *
     * @param value the string value to write.
     */
    public void writeString(char[] buffer, int offset, int length)
            throws IOException {
        if (buffer == null) {
            if (SIZE < _offset + 16)
                flushBuffer();

            _buffer[_offset++] = (byte) ('N');
        } else {
            while (length > 0x8000) {
                int sublen = 0x8000;

                if (SIZE < _offset + 16)
                    flushBuffer();

                // chunk can't end in high surrogate
                char tail = buffer[offset + sublen - 1];

                if (0xd800 <= tail && tail <= 0xdbff)
                    sublen--;

                _buffer[_offset++] = (byte) BC_STRING_CHUNK;
                _buffer[_offset++] = (byte) (sublen >> 8);
                _buffer[_offset++] = (byte) (sublen);

                printString(buffer, offset, sublen);

                length -= sublen;
                offset += sublen;
            }

            if (SIZE < _offset + 16)
                flushBuffer();

            if (length <= STRING_DIRECT_MAX) {
                _buffer[_offset++] = (byte) (BC_STRING_DIRECT + length);
            } else if (length <= STRING_SHORT_MAX) {
                _buffer[_offset++] = (byte) (BC_STRING_SHORT + (length >> 8));
                _buffer[_offset++] = (byte) length;
            } else {
                _buffer[_offset++] = (byte) ('S');
                _buffer[_offset++] = (byte) (length >> 8);
                _buffer[_offset++] = (byte) (length);
            }

            printString(buffer, offset, length);
        }
    }

    /**
     * Writes a byte array to the stream.
     * The array will be written with the following syntax:
     *
     * <code><pre>
     * B b16 b18 bytes
     * </pre></code>
     * <p>
     * If the value is null, it will be written as
     *
     * <code><pre>
     * N
     * </pre></code>
     *
     * @param value the string value to write.
     */
    public void writeBytes(byte[] buffer)
            throws IOException {
        if (buffer == null) {
            if (SIZE < _offset + 16)
                flushBuffer();

            _buffer[_offset++] = 'N';
        } else
            writeBytes(buffer, 0, buffer.length);
    }

    /**
     * Writes a byte array to the stream.
     * The array will be written with the following syntax:
     *
     * <code><pre>
     * B b16 b18 bytes
     * </pre></code>
     * <p>
     * If the value is null, it will be written as
     *
     * <code><pre>
     * N
     * </pre></code>
     *
     * @param value the string value to write.
     */
    public void writeBytes(byte[] buffer, int offset, int length)
            throws IOException {
        if (buffer == null) {
            if (SIZE < _offset + 16)
                flushBuffer();

            _buffer[_offset++] = (byte) 'N';
        } else {
            while (SIZE - _offset - 3 < length) {
                int sublen = SIZE - _offset - 3;

                if (sublen < 16) {
                    flushBuffer();

                    sublen = SIZE - _offset - 3;

                    if (length < sublen)
                        sublen = length;
                }

                _buffer[_offset++] = (byte) BC_BINARY_CHUNK;
                _buffer[_offset++] = (byte) (sublen >> 8);
                _buffer[_offset++] = (byte) sublen;

                System.arraycopy(buffer, offset, _buffer, _offset, sublen);
                _offset += sublen;

                length -= sublen;
                offset += sublen;

                flushBuffer();
            }

            if (SIZE < _offset + 16)
                flushBuffer();

            if (length <= BINARY_DIRECT_MAX) {
                _buffer[_offset++] = (byte) (BC_BINARY_DIRECT + length);
            } else if (length <= BINARY_SHORT_MAX) {
                _buffer[_offset++] = (byte) (BC_BINARY_SHORT + (length >> 8));
                _buffer[_offset++] = (byte) (length);
            } else {
                _buffer[_offset++] = (byte) 'B';
                _buffer[_offset++] = (byte) (length >> 8);
                _buffer[_offset++] = (byte) (length);
            }

            System.arraycopy(buffer, offset, _buffer, _offset, length);

            _offset += length;
        }
    }

    /**
     * Writes a byte buffer to the stream.
     *
     * <code><pre>
     * </pre></code>
     */
    public void writeByteBufferStart()
            throws IOException {
    }

    /**
     * Writes a byte buffer to the stream.
     *
     * <code><pre>
     * b b16 b18 bytes
     * </pre></code>
     */
    public void writeByteBufferPart(byte[] buffer, int offset, int length)
            throws IOException {
        while (length > 0) {
            flushIfFull();

            int sublen = _buffer.length - _offset;

            if (length < sublen)
                sublen = length;

            _buffer[_offset++] = BC_BINARY_CHUNK;
            _buffer[_offset++] = (byte) (sublen >> 8);
            _buffer[_offset++] = (byte) sublen;

            System.arraycopy(buffer, offset, _buffer, _offset, sublen);

            _offset += sublen;
            length -= sublen;
            offset += sublen;
        }
    }

    /**
     * Writes a byte buffer to the stream.
     *
     * <code><pre>
     * b b16 b18 bytes
     * </pre></code>
     */
    public void writeByteBufferEnd(byte[] buffer, int offset, int length)
            throws IOException {
        writeBytes(buffer, offset, length);
    }

    /**
     * Returns an output stream to write binary data.
     */
    public OutputStream getBytesOutputStream()
            throws IOException {
        return new BytesOutputStream();
    }

    /**
     * Writes a full output stream.
     */
    @Override
    public void writeByteStream(InputStream is)
            throws IOException {
        while (true) {
            int len = SIZE - _offset - 3;

            if (len < 16) {
                flushBuffer();
                len = SIZE - _offset - 3;
            }

            len = is.read(_buffer, _offset + 3, len);

            if (len <= 0) {
                _buffer[_offset++] = BC_BINARY_DIRECT;
                return;
            }

            _buffer[_offset + 0] = (byte) BC_BINARY_CHUNK;
            _buffer[_offset + 1] = (byte) (len >> 8);
            _buffer[_offset + 2] = (byte) (len);

            _offset += len + 3;
        }
    }

    /**
     * Writes a reference.
     *
     * <code><pre>
     * x51 &lt;int>
     * </pre></code>
     *
     * @param value the integer value to write.
     */
    @Override
    protected void writeRef(int value)
            throws IOException {
        if (SIZE < _offset + 16)
            flushBuffer();

        _buffer[_offset++] = (byte) BC_REF;

        writeInt(value);
    }

    /**
     * If the object has already been written, just write its ref.
     *
     * @return true if we're writing a ref.
     */
    @Override
    public boolean addRef(Object object)
            throws IOException {
        if (_isUnshared) {
            _refCount++;
            return false;
        }

        int newRef = _refCount;

        int ref = addRef(object, newRef, false);

        if (ref != newRef) {
            writeRef(ref);

            return true;
        } else {
            _refCount++;

            return false;
        }
    }

    @Override
    public int getRef(Object obj) {
        if (_isUnshared)
            return -1;

        return _refs.get(obj);
    }

    /**
     * Removes a reference.
     */
    @Override
    public boolean removeRef(Object obj)
            throws IOException {
        if (_isUnshared) {
            return false;
        } else if (_refs != null) {
            _refs.remove(obj);

            return true;
        } else
            return false;
    }

    /**
     * Replaces a reference from one object to another.
     */
    @Override
    public boolean replaceRef(Object oldRef, Object newRef)
            throws IOException {
        if (_isUnshared) {
            return false;
        }

        int value = _refs.get(oldRef);

        if (value >= 0) {
            addRef(newRef, value, true);

            _refs.remove(oldRef);

            return true;
        } else
            return false;
    }

    private int addRef(Object value, int newRef, boolean isReplace) {
        int prevRef = _refs.put(value, newRef, isReplace);

        return prevRef;
    }

    /**
     * Starts the streaming message
     *
     * <p>A streaming message starts with 'P'</p>
     *
     * <pre>
     * P x02 x00
     * </pre>
     */
    public void writeStreamingObject(Object obj)
            throws IOException {
        startPacket();

        writeObject(obj);

        endPacket();
    }

    /**
     * Starts a streaming packet
     *
     * <p>A streaming contains a set of chunks, ending with a zero chunk.
     * Each chunk is a length followed by data where the length is
     * encoded by (b1xxxxxxxx)* b0xxxxxxxx</p>
     */
    public void startPacket()
            throws IOException {
        if (_refs != null) {
            _refs.clear();
            _refCount = 0;
        }

        flushBuffer();

        _isPacket = true;
        _offset = 4;
        _buffer[0] = (byte) 0x05; // 0x05 = binary
        _buffer[1] = (byte) 0x55;
        _buffer[2] = (byte) 0x55;
        _buffer[3] = (byte) 0x55;
    }

    public void endPacket()
            throws IOException {
        int offset = _offset;

        OutputStream os = _os;

        if (os == null) {
            _offset = 0;
            return;
        }

        int len = offset - 4;

        if (len < 0x7e) {
            _buffer[2] = _buffer[0];
            _buffer[3] = (byte) (len);
        } else {
            _buffer[1] = (byte) (0x7e);
            _buffer[2] = (byte) (len >> 8);
            _buffer[3] = (byte) (len);
        }

        _isPacket = false;
        _offset = 0;

        if (os == null) {
        } else if (len < 0x7e) {
            os.write(_buffer, 2, offset - 2);
        } else {
            os.write(_buffer, 0, offset);
        }
    }

    /**
     * Prints a string to the stream, encoded as UTF-8 with preceeding length
     *
     * @param v the string to print.
     */
    public void printLenString(String v)
            throws IOException {
        if (SIZE < _offset + 16)
            flushBuffer();

        if (v == null) {
            _buffer[_offset++] = (byte) (0);
            _buffer[_offset++] = (byte) (0);
        } else {
            int len = v.length();
            _buffer[_offset++] = (byte) (len >> 8);
            _buffer[_offset++] = (byte) (len);

            printString(v, 0, len);
        }
    }

    /**
     * Prints a string to the stream, encoded as UTF-8
     *
     * @param v the string to print.
     */
    public void printString(String v)
            throws IOException {
        printString(v, 0, v.length());
    }

    /**
     * Prints a string to the stream, encoded as UTF-8
     *
     * @param v the string to print.
     */
    public void printString(String v, int strOffset, int length)
            throws IOException {
        int offset = _offset;
        byte[] buffer = _buffer;

        for (int i = 0; i < length; i++) {
            if (SIZE <= offset + 16) {
                _offset = offset;
                flushBuffer();
                offset = _offset;
            }

            char ch = v.charAt(i + strOffset);

            if (ch < 0x80)
                buffer[offset++] = (byte) (ch);
            else if (ch < 0x800) {
                buffer[offset++] = (byte) (0xc0 + ((ch >> 6) & 0x1f));
                buffer[offset++] = (byte) (0x80 + (ch & 0x3f));
            } else {
                buffer[offset++] = (byte) (0xe0 + ((ch >> 12) & 0xf));
                buffer[offset++] = (byte) (0x80 + ((ch >> 6) & 0x3f));
                buffer[offset++] = (byte) (0x80 + (ch & 0x3f));
            }
        }

        _offset = offset;
    }

    /**
     * Prints a string to the stream, encoded as UTF-8
     *
     * @param v the string to print.
     */
    public void printString(char[] v, int strOffset, int length)
            throws IOException {
        int offset = _offset;
        byte[] buffer = _buffer;

        for (int i = 0; i < length; i++) {
            if (SIZE <= offset + 16) {
                _offset = offset;
                flushBuffer();
                offset = _offset;
            }

            char ch = v[i + strOffset];

            if (ch < 0x80)
                buffer[offset++] = (byte) (ch);
            else if (ch < 0x800) {
                buffer[offset++] = (byte) (0xc0 + ((ch >> 6) & 0x1f));
                buffer[offset++] = (byte) (0x80 + (ch & 0x3f));
            } else {
                buffer[offset++] = (byte) (0xe0 + ((ch >> 12) & 0xf));
                buffer[offset++] = (byte) (0x80 + ((ch >> 6) & 0x3f));
                buffer[offset++] = (byte) (0x80 + (ch & 0x3f));
            }
        }

        _offset = offset;
    }

    private final void flushIfFull()
            throws IOException {
        int offset = _offset;

        if (SIZE < offset + 32) {
            flushBuffer();
        }
    }

    public final void flush()
            throws IOException {
        flushBuffer();

        if (_os != null)
            _os.flush();
    }

    public final void flushBuffer()
            throws IOException {
        int offset = _offset;

        OutputStream os = _os;

        if (!_isPacket && offset > 0) {
            _offset = 0;
            if (os != null)
                os.write(_buffer, 0, offset);
        } else if (_isPacket && offset > 4) {
            int len = offset - 4;

            _buffer[0] |= (byte) 0x80;
            _buffer[1] = (byte) (0x7e);
            _buffer[2] = (byte) (len >> 8);
            _buffer[3] = (byte) (len);
            _offset = 4;

            if (os != null)
                os.write(_buffer, 0, offset);

            _buffer[0] = (byte) 0x00;
            _buffer[1] = (byte) 0x56;
            _buffer[2] = (byte) 0x56;
            _buffer[3] = (byte) 0x56;
        }
    }

    @Override
    public void close()
            throws IOException {
        // hessian/3a8c
        flush();

        OutputStream os = _os;
        _os = null;

        if (os != null) {
            if (_isCloseStreamOnClose)
                os.close();
        }
    }

    public void free() {
        reset();

        _os = null;
        _isCloseStreamOnClose = false;
    }

    /**
     * Resets the references for streaming.
     */
    @Override
    public void resetReferences() {
        if (_refs != null) {
            _refs.clear();
            _refCount = 0;
        }
    }

    /**
     * Resets all counters and references
     */
    public void reset() {
        if (_refs != null) {
            _refs.clear();
            _refCount = 0;
        }

        _classRefs.clear();
        _typeRefs = null;
        _offset = 0;
        _isPacket = false;
        _isUnshared = false;
    }

    class BytesOutputStream extends OutputStream {
        private int _startOffset;

        BytesOutputStream()
                throws IOException {
            if (SIZE < _offset + 16) {
                Hessian2Output.this.flushBuffer();
            }

            _startOffset = _offset;
            _offset += 3; // skip 'b' xNN xNN
        }

        @Override
        public void write(int ch)
                throws IOException {
            if (SIZE <= _offset) {
                int length = (_offset - _startOffset) - 3;

                _buffer[_startOffset] = (byte) BC_BINARY_CHUNK;
                _buffer[_startOffset + 1] = (byte) (length >> 8);
                _buffer[_startOffset + 2] = (byte) (length);

                Hessian2Output.this.flushBuffer();

                _startOffset = _offset;
                _offset += 3;
            }

            _buffer[_offset++] = (byte) ch;
        }

        @Override
        public void write(byte[] buffer, int offset, int length)
                throws IOException {
            while (length > 0) {
                int sublen = SIZE - _offset;

                if (length < sublen)
                    sublen = length;

                if (sublen > 0) {
                    System.arraycopy(buffer, offset, _buffer, _offset, sublen);
                    _offset += sublen;
                }

                length -= sublen;
                offset += sublen;

                if (SIZE <= _offset) {
                    int chunkLength = (_offset - _startOffset) - 3;

                    _buffer[_startOffset] = (byte) BC_BINARY_CHUNK;
                    _buffer[_startOffset + 1] = (byte) (chunkLength >> 8);
                    _buffer[_startOffset + 2] = (byte) (chunkLength);

                    Hessian2Output.this.flushBuffer();

                    _startOffset = _offset;
                    _offset += 3;
                }
            }
        }

        @Override
        public void close()
                throws IOException {
            int startOffset = _startOffset;
            _startOffset = -1;

            if (startOffset < 0)
                return;

            int length = (_offset - startOffset) - 3;

            _buffer[startOffset] = (byte) 'B';
            _buffer[startOffset + 1] = (byte) (length >> 8);
            _buffer[startOffset + 2] = (byte) (length);

            Hessian2Output.this.flushBuffer();
        }
    }
}
