/*
 * Copyright (c) 2001-2004 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 "Hessian", "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.hessian3.io;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Input stream for Hessian requests.
 * <p>
 * <p>HessianInput is unbuffered, so any client needs to provide
 * its own buffering.
 * <p>
 * <pre>
 * InputStream is = ...; // from http connection
 * HessianInput in = new HessianInput(is);
 * String value;
 *
 * in.startReply();         // read reply header
 * value = in.readString(); // read string value
 * in.completeReply();      // read reply footer
 * </pre>
 */
public class HessianInput extends AbstractHessianInput {
    private static int END_OF_DATA = -2;

    private static Field _detailMessageField;

    static {
        try {
            _detailMessageField = Throwable.class.getDeclaredField("detailMessage");
            _detailMessageField.setAccessible(true);
        } catch (Throwable e) {
        }
    }

    // factory for deserializing objects in the input stream
    protected SerializerFactory _serializerFactory;
    protected ArrayList _refs;
    // a peek character
    protected int _peek = -1;
    // the underlying input stream
    private InputStream _is;
    // the method for a call
    private String _method;
    private Reader _chunkReader;
    private InputStream _chunkInputStream;
    private Throwable _replyFault;
    private StringBuffer _sbuf = new StringBuffer();
    // true if this is the last chunk
    private boolean _isLastChunk;
    // the chunk length
    private int _chunkLength;

    /**
     * Creates an uninitialized Hessian input stream.
     */
    public HessianInput() {
    }

    /**
     * Creates a new Hessian input stream, initialized with an
     * underlying input stream.
     *
     * @param is the underlying input stream.
     */
    public HessianInput(InputStream is) {
        init(is);
    }

    /**
     * Gets the serializer factory.
     */
    public SerializerFactory getSerializerFactory() {
        return _serializerFactory;
    }

    /**
     * Sets the serializer factory.
     */
    @Override
    public void setSerializerFactory(SerializerFactory factory) {
        _serializerFactory = factory;
    }

    /**
     * Initialize the hessian stream with the underlying input stream.
     */
    @Override
    public void init(InputStream is) {
        _is = is;
        _method = null;
        _isLastChunk = true;
        _chunkLength = 0;
        _peek = -1;
        _refs = null;
        _replyFault = null;

        if (_serializerFactory == null)
            _serializerFactory = new SerializerFactory();
    }

    /**
     * Returns the calls method
     */
    @Override
    public String getMethod() {
        return _method;
    }

    /**
     * Returns any reply fault.
     */
    public Throwable getReplyFault() {
        return _replyFault;
    }

    @Override
    public boolean checkAndReadNull() {
        return _peek == 'N';
    }

    /**
     * Starts reading the call
     * <p>
     * <pre>
     * c major minor
     * </pre>
     */
    @Override
    public int readCall()
            throws IOException {
        int tag = read();

        if (tag != 'c')
            throw error("expected hessian call ('c') at " + codeName(tag));

        int major = read();
        int minor = read();

        return (major << 16) + minor;
    }

    /**
     * For backward compatibility with HessianSkeleton
     */
    @Override
    public void skipOptionalCall()
            throws IOException {
        int tag = read();

        if (tag == 'c') {
            read();
            read();
        } else
            _peek = tag;
    }

    /**
     * Starts reading the call
     * <p>
     * <p>A successful completion will have a single value:
     * <p>
     * <pre>
     * m b16 b8 method
     * </pre>
     */
    @Override
    public String readMethod()
            throws IOException {
        int tag = read();

        if (tag != 'm')
            throw error("expected hessian method ('m') at " + codeName(tag));
        int d1 = read();
        int d2 = read();

        _isLastChunk = true;
        _chunkLength = d1 * 256 + d2;
        _sbuf.setLength(0);
        int ch;
        while ((ch = parseChar()) >= 0)
            _sbuf.append((char) ch);

        _method = _sbuf.toString();

        return _method;
    }

    /**
     * Starts reading the call, including the headers.
     * <p>
     * <p>The call expects the following protocol data
     * <p>
     * <pre>
     * c major minor
     * m b16 b8 method
     * </pre>
     */
    @Override
    public void startCall()
            throws IOException {
        readCall();

        while (readHeader() != null) {
            readObject();
        }

        readMethod();
    }

    /**
     * Completes reading the call
     * <p>
     * <p>A successful completion will have a single value:
     * <p>
     * <pre>
     * z
     * </pre>
     */
    @Override
    public void completeCall()
            throws IOException {
        int tag = read();

        if (tag == 'z') {
        } else
            throw error("expected end of call ('z') at " + codeName(tag) + ".  Check method arguments and ensure method overloading is enabled if necessary");
    }

    /**
     * Reads a reply as an object.
     * If the reply has a fault, throws the exception.
     */
    @Override
    public Object readReply(Class expectedClass)
            throws Throwable {
        int tag = read();

        if (tag != 'r')
            error("expected hessian reply at " + codeName(tag));

        int major = read();
        int minor = read();

        tag = read();
        if (tag == 'f')
            throw prepareFault();
        else {
            _peek = tag;

            Object value = readObject(expectedClass);

            completeValueReply();

            return value;
        }
    }

    /**
     * Starts reading the reply
     * <p>
     * <p>A successful completion will have a single value:
     * <p>
     * <pre>
     * r
     * </pre>
     */
    @Override
    public void startReply()
            throws Throwable {
        int tag = read();

        if (tag != 'r')
            error("expected hessian reply at " + codeName(tag));

        int major = read();
        int minor = read();

        tag = read();
        if (tag == 'f')
            throw prepareFault();
        else
            _peek = tag;
    }

    /**
     * Prepares the fault.
     */
    private Throwable prepareFault()
            throws IOException {
        HashMap fault = readFault();

        Object detail = fault.get("detail");
        String message = (String) fault.get("message");

        if (detail instanceof Throwable) {
            _replyFault = (Throwable) detail;

            if (message != null && _detailMessageField != null) {
                try {
                    _detailMessageField.set(_replyFault, message);
                } catch (Throwable e) {
                }
            }

            return _replyFault;
        } else {
            String code = (String) fault.get("code");

            _replyFault = new HessianServiceException(message, code, detail);

            return _replyFault;
        }
    }

    /**
     * Completes reading the call
     * <p>
     * <p>A successful completion will have a single value:
     * <p>
     * <pre>
     * z
     * </pre>
     */
    @Override
    public void completeReply()
            throws IOException {
        int tag = read();

        if (tag != 'z')
            error("expected end of reply at " + codeName(tag));
    }

    /**
     * Completes reading the call
     * <p>
     * <p>A successful completion will have a single value:
     * <p>
     * <pre>
     * z
     * </pre>
     */
    public void completeValueReply()
            throws IOException {
        int tag = read();

        if (tag != 'z')
            error("expected end of reply at " + codeName(tag));
    }

    /**
     * Reads a header, returning null if there are no headers.
     * <p>
     * <pre>
     * H b16 b8 value
     * </pre>
     */
    @Override
    public String readHeader()
            throws IOException {
        int tag = read();

        if (tag == 'H') {
            _isLastChunk = true;
            _chunkLength = (read() << 8) + read();

            _sbuf.setLength(0);
            int ch;
            while ((ch = parseChar()) >= 0)
                _sbuf.append((char) ch);

            return _sbuf.toString();
        }

        _peek = tag;

        return null;
    }

    /**
     * Reads a null
     * <p>
     * <pre>
     * N
     * </pre>
     */
    @Override
    public void readNull()
            throws IOException {
        int tag = read();

        switch (tag) {
            case 'N':
                return;

            default:
                throw expect("null", tag);
        }
    }

    /**
     * Reads a byte
     *
     * <pre>
     * I b32 b24 b16 b8
     * </pre>
     */
  /*
  public byte readByte()
    throws IOException
  {
    return (byte) readInt();
  }
  */

    /**
     * Reads a boolean
     * <p>
     * <pre>
     * T
     * F
     * </pre>
     */
    @Override
    public boolean readBoolean()
            throws IOException {
        int tag = read();

        switch (tag) {
            case 'T':
                return true;
            case 'F':
                return false;
            case 'I':
                return parseInt() == 0;
            case 'L':
                return parseLong() == 0;
            case 'D':
                return parseDouble() == 0.0;
            case 'N':
                return false;

            default:
                throw expect("boolean", tag);
        }
    }

    /**
     * Reads a short
     * <p>
     * <pre>
     * I b32 b24 b16 b8
     * </pre>
     */
    public short readShort()
            throws IOException {
        return (short) readInt();
    }

    /**
     * Reads an integer
     * <p>
     * <pre>
     * I b32 b24 b16 b8
     * </pre>
     */
    @Override
    public int readInt()
            throws IOException {
        int tag = read();

        switch (tag) {
            case 'T':
                return 1;
            case 'F':
                return 0;
            case 'I':
                return parseInt();
            case 'L':
                return (int) parseLong();
            case 'D':
                return (int) parseDouble();

            default:
                throw expect("int", tag);
        }
    }

    /**
     * Reads a long
     * <p>
     * <pre>
     * L b64 b56 b48 b40 b32 b24 b16 b8
     * </pre>
     */
    @Override
    public long readLong()
            throws IOException {
        int tag = read();

        switch (tag) {
            case 'T':
                return 1;
            case 'F':
                return 0;
            case 'I':
                return parseInt();
            case 'L':
                return parseLong();
            case 'D':
                return (long) parseDouble();

            default:
                throw expect("long", tag);
        }
    }

    /**
     * Reads a float
     * <p>
     * <pre>
     * D b64 b56 b48 b40 b32 b24 b16 b8
     * </pre>
     */
    public float readFloat()
            throws IOException {
        return (float) readDouble();
    }

    /**
     * Reads a double
     * <p>
     * <pre>
     * D b64 b56 b48 b40 b32 b24 b16 b8
     * </pre>
     */
    @Override
    public double readDouble()
            throws IOException {
        int tag = read();

        switch (tag) {
            case 'T':
                return 1;
            case 'F':
                return 0;
            case 'I':
                return parseInt();
            case 'L':
                return (double) parseLong();
            case 'D':
                return parseDouble();

            default:
                throw expect("long", tag);
        }
    }

    /**
     * Reads a date.
     * <p>
     * <pre>
     * T b64 b56 b48 b40 b32 b24 b16 b8
     * </pre>
     */
    @Override
    public long readUTCDate()
            throws IOException {
        int tag = read();

        if (tag != 'd')
            throw error("expected date at " + codeName(tag));

        long b64 = read();
        long b56 = read();
        long b48 = read();
        long b40 = read();
        long b32 = read();
        long b24 = read();
        long b16 = read();
        long b8 = read();

        return ((b64 << 56) +
                (b56 << 48) +
                (b48 << 40) +
                (b40 << 32) +
                (b32 << 24) +
                (b24 << 16) +
                (b16 << 8) +
                b8);
    }

    /**
     * Reads a byte from the stream.
     */
    public int readChar()
            throws IOException {
        if (_chunkLength > 0) {
            _chunkLength--;
            if (_chunkLength == 0 && _isLastChunk)
                _chunkLength = END_OF_DATA;

            int ch = parseUTF8Char();
            return ch;
        } else if (_chunkLength == END_OF_DATA) {
            _chunkLength = 0;
            return -1;
        }

        int tag = read();

        switch (tag) {
            case 'N':
                return -1;

            case 'S':
            case 's':
            case 'X':
            case 'x':
                _isLastChunk = tag == 'S' || tag == 'X';
                _chunkLength = (read() << 8) + read();

                _chunkLength--;
                int value = parseUTF8Char();

                // special code so successive read byte won't
                // be read as a single object.
                if (_chunkLength == 0 && _isLastChunk)
                    _chunkLength = END_OF_DATA;

                return value;

            default:
                throw new IOException("expected 'S' at " + (char) tag);
        }
    }

    /**
     * Reads a byte array from the stream.
     */
    public int readString(char[] buffer, int offset, int length)
            throws IOException {
        int readLength = 0;

        if (_chunkLength == END_OF_DATA) {
            _chunkLength = 0;
            return -1;
        } else if (_chunkLength == 0) {
            int tag = read();

            switch (tag) {
                case 'N':
                    return -1;

                case 'S':
                case 's':
                case 'X':
                case 'x':
                    _isLastChunk = tag == 'S' || tag == 'X';
                    _chunkLength = (read() << 8) + read();
                    break;

                default:
                    throw new IOException("expected 'S' at " + (char) tag);
            }
        }

        while (length > 0) {
            if (_chunkLength > 0) {
                buffer[offset++] = (char) parseUTF8Char();
                _chunkLength--;
                length--;
                readLength++;
            } else if (_isLastChunk) {
                if (readLength == 0)
                    return -1;
                else {
                    _chunkLength = END_OF_DATA;
                    return readLength;
                }
            } else {
                int tag = read();

                switch (tag) {
                    case 'S':
                    case 's':
                    case 'X':
                    case 'x':
                        _isLastChunk = tag == 'S' || tag == 'X';
                        _chunkLength = (read() << 8) + read();
                        break;

                    default:
                        throw new IOException("expected 'S' at " + (char) tag);
                }
            }
        }

        if (readLength == 0)
            return -1;
        else if (_chunkLength > 0 || !_isLastChunk)
            return readLength;
        else {
            _chunkLength = END_OF_DATA;
            return readLength;
        }
    }

    /**
     * Reads a string
     * <p>
     * <pre>
     * S b16 b8 string value
     * </pre>
     */
    @Override
    public String readString()
            throws IOException {
        int tag = read();

        switch (tag) {
            case 'N':
                return null;

            case 'I':
                return String.valueOf(parseInt());
            case 'L':
                return String.valueOf(parseLong());
            case 'D':
                return String.valueOf(parseDouble());

            case 'S':
            case 's':
            case 'X':
            case 'x':
                _isLastChunk = tag == 'S' || tag == 'X';
                _chunkLength = (read() << 8) + read();

                _sbuf.setLength(0);
                int ch;

                while ((ch = parseChar()) >= 0)
                    _sbuf.append((char) ch);

                return _sbuf.toString();

            default:
                throw expect("string", tag);
        }
    }

    /**
     * Reads an XML node.
     * <p>
     * <pre>
     * S b16 b8 string value
     * </pre>
     */
    @Override
    public org.w3c.dom.Node readNode()
            throws IOException {
        int tag = read();

        switch (tag) {
            case 'N':
                return null;

            case 'S':
            case 's':
            case 'X':
            case 'x':
                _isLastChunk = tag == 'S' || tag == 'X';
                _chunkLength = (read() << 8) + read();

                throw error("Can't handle string in this context");

            default:
                throw expect("string", tag);
        }
    }

    /**
     * Reads a byte array
     * <p>
     * <pre>
     * B b16 b8 data value
     * </pre>
     */
    @Override
    public byte[] readBytes()
            throws IOException {
        int tag = read();

        switch (tag) {
            case 'N':
                return null;

            case 'B':
            case 'b':
                _isLastChunk = tag == 'B';
                _chunkLength = (read() << 8) + read();

                ByteArrayOutputStream bos = new ByteArrayOutputStream();

                int data;
                while ((data = parseByte()) >= 0)
                    bos.write(data);

                return bos.toByteArray();

            default:
                throw expect("bytes", tag);
        }
    }

    /**
     * Reads a byte from the stream.
     */
    public int readByte()
            throws IOException {
        if (_chunkLength > 0) {
            _chunkLength--;
            if (_chunkLength == 0 && _isLastChunk)
                _chunkLength = END_OF_DATA;

            return read();
        } else if (_chunkLength == END_OF_DATA) {
            _chunkLength = 0;
            return -1;
        }

        int tag = read();

        switch (tag) {
            case 'N':
                return -1;

            case 'B':
            case 'b':
                _isLastChunk = tag == 'B';
                _chunkLength = (read() << 8) + read();

                int value = parseByte();

                // special code so successive read byte won't
                // be read as a single object.
                if (_chunkLength == 0 && _isLastChunk)
                    _chunkLength = END_OF_DATA;

                return value;

            default:
                throw new IOException("expected 'B' at " + (char) tag);
        }
    }

    /**
     * Reads a byte array from the stream.
     */
    public int readBytes(byte[] buffer, int offset, int length)
            throws IOException {
        int readLength = 0;

        if (_chunkLength == END_OF_DATA) {
            _chunkLength = 0;
            return -1;
        } else if (_chunkLength == 0) {
            int tag = read();

            switch (tag) {
                case 'N':
                    return -1;

                case 'B':
                case 'b':
                    _isLastChunk = tag == 'B';
                    _chunkLength = (read() << 8) + read();
                    break;

                default:
                    throw new IOException("expected 'B' at " + (char) tag);
            }
        }

        while (length > 0) {
            if (_chunkLength > 0) {
                buffer[offset++] = (byte) read();
                _chunkLength--;
                length--;
                readLength++;
            } else if (_isLastChunk) {
                if (readLength == 0)
                    return -1;
                else {
                    _chunkLength = END_OF_DATA;
                    return readLength;
                }
            } else {
                int tag = read();

                switch (tag) {
                    case 'B':
                    case 'b':
                        _isLastChunk = tag == 'B';
                        _chunkLength = (read() << 8) + read();
                        break;

                    default:
                        throw new IOException("expected 'B' at " + (char) tag);
                }
            }
        }

        if (readLength == 0)
            return -1;
        else if (_chunkLength > 0 || !_isLastChunk)
            return readLength;
        else {
            _chunkLength = END_OF_DATA;
            return readLength;
        }
    }

    /**
     * Reads a fault.
     */
    private HashMap readFault()
            throws IOException {
        HashMap map = new HashMap();

        int code = read();
        for (; code > 0 && code != 'z'; code = read()) {
            _peek = code;

            Object key = readObject();
            Object value = readObject();

            if (key != null && value != null)
                map.put(key, value);
        }

        if (code != 'z')
            throw expect("fault", code);

        return map;
    }

    /**
     * Reads an object from the input stream with an expected type.
     */
    @Override
    public Object readObject(Class cl)
            throws IOException {
        return readObject(cl, null, null);
    }

    /**
     * Reads an object from the input stream with an expected type.
     */
    public Object readObject(Class expectedClass, Class<?>... expectedTypes)
            throws IOException {
        if (expectedClass == null || expectedClass == Object.class)
            return readObject();

        int tag = read();

        switch (tag) {
            case 'N':
                return null;

            case 'M': {
                String type = readType();

                boolean keyValuePair = expectedTypes != null && expectedTypes.length == 2;

                // hessian/3386
                if ("".equals(type)) {
                    Deserializer reader;
                    reader = _serializerFactory.getDeserializer(expectedClass);

                    return reader.readMap(this
                            , keyValuePair ? expectedTypes[0] : null
                            , keyValuePair ? expectedTypes[1] : null);
                } else {
                    Deserializer reader;
                    reader = _serializerFactory.getObjectDeserializer(type, expectedClass);

                    return reader.readMap(this
                            , keyValuePair ? expectedTypes[0] : null
                            , keyValuePair ? expectedTypes[1] : null);
                }
            }

            case 'V': {
                String type = readType();
                int length = readLength();

                Deserializer reader;
                reader = _serializerFactory.getObjectDeserializer(type);

                boolean valueType = expectedTypes != null && expectedTypes.length == 1;

                if (expectedClass != reader.getType() && expectedClass.isAssignableFrom(reader.getType()))
                    return reader.readList(this, length, valueType ? expectedTypes[0] : null);

                reader = _serializerFactory.getDeserializer(expectedClass);

                Object v = reader.readList(this, length, valueType ? expectedTypes[0] : null);

                return v;
            }

            case 'R': {
                int ref = parseInt();

                return _refs.get(ref);
            }

            case 'r': {
                String type = readType();
                String url = readString();

                return resolveRemote(type, url);
            }
        }

        _peek = tag;

        // hessian/332i vs hessian/3406
        //return readObject();

        Object value = _serializerFactory.getDeserializer(expectedClass).readObject(this);

        return value;
    }

    /**
     * Reads an arbitrary object from the input stream when the type
     * is unknown.
     */
    @Override
    public Object readObject()
            throws IOException {
        return readObject((List<Class<?>>) null);
    }

    /**
     * Reads an arbitrary object from the input stream when the type
     * is unknown.
     */
    public Object readObject(List<Class<?>> expectedTypes)
            throws IOException {
        int tag = read();

        switch (tag) {
            case 'N':
                return null;

            case 'T':
                return Boolean.valueOf(true);

            case 'F':
                return Boolean.valueOf(false);

            case 'I':
                return Integer.valueOf(parseInt());

            case 'L':
                return Long.valueOf(parseLong());

            case 'D':
                return Double.valueOf(parseDouble());

            case 'd':
                return new Date(parseLong());

            case 'x':
            case 'X': {
                _isLastChunk = tag == 'X';
                _chunkLength = (read() << 8) + read();

                return parseXML();
            }

            case 's':
            case 'S': {
                _isLastChunk = tag == 'S';
                _chunkLength = (read() << 8) + read();

                int data;
                _sbuf.setLength(0);

                while ((data = parseChar()) >= 0)
                    _sbuf.append((char) data);

                return _sbuf.toString();
            }

            case 'b':
            case 'B': {
                _isLastChunk = tag == 'B';
                _chunkLength = (read() << 8) + read();

                int data;
                ByteArrayOutputStream bos = new ByteArrayOutputStream();

                while ((data = parseByte()) >= 0)
                    bos.write(data);

                return bos.toByteArray();
            }

            case 'V': {
                String type = readType();
                int length = readLength();

                Deserializer reader;
                reader = _serializerFactory.getObjectDeserializer(type);

                boolean valueType = expectedTypes != null && expectedTypes.size() == 1;

                if (List.class != reader.getType() && List.class.isAssignableFrom(reader.getType()))
                    return reader.readList(this, length, valueType ? expectedTypes.get(0) : null);
                Class clazz = type.equals(HashSet.class.getName()) ? Set.class : List.class;
                reader = _serializerFactory.getDeserializer(clazz);

                Object v = reader.readList(this, length, valueType ? expectedTypes.get(0) : null);

                return v;
            }

            case 'M': {
                String type = readType();

                boolean keyValuePair = expectedTypes != null && expectedTypes.size() == 2;

                return _serializerFactory.readMap(this, type
                        , keyValuePair ? expectedTypes.get(0) : null
                        , keyValuePair ? expectedTypes.get(1) : null);
            }

            case 'R': {
                int ref = parseInt();

                return _refs.get(ref);
            }

            case 'r': {
                String type = readType();
                String url = readString();

                return resolveRemote(type, url);
            }

            default:
                throw error("unknown code for readObject at " + codeName(tag));
        }
    }

    /**
     * Reads a remote object.
     */
    @Override
    public Object readRemote()
            throws IOException {
        String type = readType();
        String url = readString();

        return resolveRemote(type, url);
    }

    /**
     * Reads a reference.
     */
    @Override
    public Object readRef()
            throws IOException {
        return _refs.get(parseInt());
    }

    /**
     * Reads the start of a list.
     */
    @Override
    public int readListStart()
            throws IOException {
        return read();
    }

    /**
     * Reads the start of a list.
     */
    @Override
    public int readMapStart()
            throws IOException {
        return read();
    }

    /**
     * Returns true if this is the end of a list or a map.
     */
    @Override
    public boolean isEnd()
            throws IOException {
        int code = read();

        _peek = code;

        return (code < 0 || code == 'z');
    }

    /**
     * Reads the end byte.
     */
    @Override
    public void readEnd()
            throws IOException {
        int code = read();

        if (code != 'z')
            throw error("unknown code at " + codeName(code));
    }

    /**
     * Reads the end byte.
     */
    @Override
    public void readMapEnd()
            throws IOException {
        int code = read();

        if (code != 'z')
            throw error("expected end of map ('z') at " + codeName(code));
    }

    /**
     * Reads the end byte.
     */
    @Override
    public void readListEnd()
            throws IOException {
        int code = read();

        if (code != 'z')
            throw error("expected end of list ('z') at " + codeName(code));
    }

    /**
     * Adds a list/map reference.
     */
    @Override
    public int addRef(Object ref) {
        if (_refs == null)
            _refs = new ArrayList();

        _refs.add(ref);

        return _refs.size() - 1;
    }

    /**
     * Adds a list/map reference.
     */
    @Override
    public void setRef(int i, Object ref) {
        _refs.set(i, ref);
    }

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

    /**
     * Resolves a remote object.
     */
    public Object resolveRemote(String type, String url)
            throws IOException {
        HessianRemoteResolver resolver = getRemoteResolver();

        if (resolver != null)
            return resolver.lookup(type, url);
        else
            return new HessianRemote(type, url);
    }

    /**
     * Parses a type from the stream.
     * <p>
     * <pre>
     * t b16 b8
     * </pre>
     */
    @Override
    public String readType()
            throws IOException {
        int code = read();

        if (code != 't') {
            _peek = code;
            return "";
        }

        _isLastChunk = true;
        _chunkLength = (read() << 8) + read();

        _sbuf.setLength(0);
        int ch;
        while ((ch = parseChar()) >= 0)
            _sbuf.append((char) ch);

        return _sbuf.toString();
    }

    /**
     * Parses the length for an array
     * <p>
     * <pre>
     * l b32 b24 b16 b8
     * </pre>
     */
    @Override
    public int readLength()
            throws IOException {
        int code = read();

        if (code != 'l') {
            _peek = code;
            return -1;
        }

        return parseInt();
    }

    /**
     * Parses a 32-bit integer value from the stream.
     * <p>
     * <pre>
     * b32 b24 b16 b8
     * </pre>
     */
    private int parseInt()
            throws IOException {
        int b32 = read();
        int b24 = read();
        int b16 = read();
        int b8 = read();

        return (b32 << 24) + (b24 << 16) + (b16 << 8) + b8;
    }

    /**
     * Parses a 64-bit long value from the stream.
     * <p>
     * <pre>
     * b64 b56 b48 b40 b32 b24 b16 b8
     * </pre>
     */
    private long parseLong()
            throws IOException {
        long b64 = read();
        long b56 = read();
        long b48 = read();
        long b40 = read();
        long b32 = read();
        long b24 = read();
        long b16 = read();
        long b8 = read();

        return ((b64 << 56) +
                (b56 << 48) +
                (b48 << 40) +
                (b40 << 32) +
                (b32 << 24) +
                (b24 << 16) +
                (b16 << 8) +
                b8);
    }

    /**
     * Parses a 64-bit double value from the stream.
     * <p>
     * <pre>
     * b64 b56 b48 b40 b32 b24 b16 b8
     * </pre>
     */
    private double parseDouble()
            throws IOException {
        long b64 = read();
        long b56 = read();
        long b48 = read();
        long b40 = read();
        long b32 = read();
        long b24 = read();
        long b16 = read();
        long b8 = read();

        long bits = ((b64 << 56) +
                (b56 << 48) +
                (b48 << 40) +
                (b40 << 32) +
                (b32 << 24) +
                (b24 << 16) +
                (b16 << 8) +
                b8);

        return Double.longBitsToDouble(bits);
    }

    org.w3c.dom.Node parseXML()
            throws IOException {
        throw new UnsupportedOperationException();
    }

    /**
     * Reads a character from the underlying stream.
     */
    private int parseChar()
            throws IOException {
        while (_chunkLength <= 0) {
            if (_isLastChunk)
                return -1;

            int code = read();

            switch (code) {
                case 's':
                case 'x':
                    _isLastChunk = false;

                    _chunkLength = (read() << 8) + read();
                    break;

                case 'S':
                case 'X':
                    _isLastChunk = true;

                    _chunkLength = (read() << 8) + read();
                    break;

                default:
                    throw expect("string", code);
            }

        }

        _chunkLength--;

        return parseUTF8Char();
    }

    /**
     * Parses a single UTF8 character.
     */
    private int parseUTF8Char()
            throws IOException {
        int ch = read();

        if (ch < 0x80)
            return ch;
        else if ((ch & 0xe0) == 0xc0) {
            int ch1 = read();
            int v = ((ch & 0x1f) << 6) + (ch1 & 0x3f);

            return v;
        } else if ((ch & 0xf0) == 0xe0) {
            int ch1 = read();
            int ch2 = read();
            int v = ((ch & 0x0f) << 12) + ((ch1 & 0x3f) << 6) + (ch2 & 0x3f);

            return v;
        } else
            throw error("bad utf-8 encoding at " + codeName(ch));
    }

    /**
     * Reads a byte from the underlying stream.
     */
    private int parseByte()
            throws IOException {
        while (_chunkLength <= 0) {
            if (_isLastChunk) {
                return -1;
            }

            int code = read();

            switch (code) {
                case 'b':
                    _isLastChunk = false;

                    _chunkLength = (read() << 8) + read();
                    break;

                case 'B':
                    _isLastChunk = true;

                    _chunkLength = (read() << 8) + read();
                    break;

                default:
                    throw expect("byte[]", code);
            }
        }

        _chunkLength--;

        return read();
    }

    /**
     * Reads bytes based on an input stream.
     */
    @Override
    public InputStream readInputStream()
            throws IOException {
        int tag = read();

        switch (tag) {
            case 'N':
                return null;

            case 'B':
            case 'b':
                _isLastChunk = tag == 'B';
                _chunkLength = (read() << 8) + read();
                break;

            default:
                throw expect("inputStream", tag);
        }

        return new InputStream() {
            boolean _isClosed = false;

            @Override
            public int read()
                    throws IOException {
                if (_isClosed || _is == null)
                    return -1;

                int ch = parseByte();
                if (ch < 0)
                    _isClosed = true;

                return ch;
            }

            @Override
            public int read(byte[] buffer, int offset, int length)
                    throws IOException {
                if (_isClosed || _is == null)
                    return -1;

                int len = HessianInput.this.read(buffer, offset, length);
                if (len < 0)
                    _isClosed = true;

                return len;
            }

            @Override
            public void close()
                    throws IOException {
                while (read() >= 0) {
                }

                _isClosed = true;
            }
        };
    }

    /**
     * Reads bytes from the underlying stream.
     */
    int read(byte[] buffer, int offset, int length)
            throws IOException {
        int readLength = 0;

        while (length > 0) {
            while (_chunkLength <= 0) {
                if (_isLastChunk)
                    return readLength == 0 ? -1 : readLength;

                int code = read();

                switch (code) {
                    case 'b':
                        _isLastChunk = false;

                        _chunkLength = (read() << 8) + read();
                        break;

                    case 'B':
                        _isLastChunk = true;

                        _chunkLength = (read() << 8) + read();
                        break;

                    default:
                        throw expect("byte[]", code);
                }
            }

            int sublen = _chunkLength;
            if (length < sublen)
                sublen = length;

            sublen = _is.read(buffer, offset, sublen);
            offset += sublen;
            readLength += sublen;
            length -= sublen;
            _chunkLength -= sublen;
        }

        return readLength;
    }

    final int read()
            throws IOException {
        if (_peek >= 0) {
            int value = _peek;
            _peek = -1;
            return value;
        }

        int ch = _is.read();

        return ch;
    }

    @Override
    public void close() {
        _is = null;
    }

    @Override
    public Reader getReader() {
        return null;
    }

    protected IOException expect(String expect, int ch) {
        return error("expected " + expect + " at " + codeName(ch));
    }

    protected String codeName(int ch) {
        if (ch < 0)
            return "end of file";
        else
            return "0x" + Integer.toHexString(ch & 0xff) + " (" + (char) +ch + ")";
    }

    protected IOException error(String message) {
        if (_method != null)
            return new HessianProtocolException(_method + ": " + message);
        else
            return new HessianProtocolException(message);
    }
}
