// **********************************************************************
//
// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
//
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************

final class Transceiver implements IceInternal.Transceiver
{
    public java.nio.channels.SelectableChannel
    fd()
    {
        return _transceiver.fd();
    }

    public IceInternal.SocketStatus
    initialize()
    {
        IceInternal.SocketStatus status = _configuration.initializeSocketStatus();
        if(status == IceInternal.SocketStatus.NeedConnect || status == IceInternal.SocketStatus.NeedWrite)
        {
            if(!_initialized)
            {
                status = _transceiver.initialize();
                if(status != IceInternal.SocketStatus.Finished)
                {
                    return status;
                }
                _initialized = true;
            }
            return IceInternal.SocketStatus.NeedWrite;
        }
        else if(status == IceInternal.SocketStatus.NeedRead)
        {
            return status;
        }

        _configuration.checkInitializeException();
        if(!_initialized)
        {
            status = _transceiver.initialize();
            if(status != IceInternal.SocketStatus.Finished)
            {
                return status;
            }
            _initialized = true;
        }
        return IceInternal.SocketStatus.Finished;
    }

    public void
    close()
    {
        _transceiver.close();
    }

    public boolean
    write(IceInternal.Buffer buf)
    {
        if(!_initialized)
        {
            throw new Ice.SocketException();
        }

        if(!_configuration.writeReady())
        {
                return false;
        }
        _configuration.checkWriteException();
        return _transceiver.write(buf);
    }

    public boolean
    read(IceInternal.Buffer buf, Ice.BooleanHolder moreData)
    {
        if(!_initialized)
        {
            throw new Ice.SocketException();
        }

        if(!moreData.value)
        {
            if(!_configuration.readReady())
            {
                return false;
            }
        }
        _configuration.checkReadException();
        return _transceiver.read(buf, moreData);
    }

    public String
    type()
    {
        return "test-" + _transceiver.type();
    }

    public String
    toString()
    {
        return _transceiver.toString();
    }

    public void
    checkSendSize(IceInternal.Buffer buf, int messageSizeMax)
    {
        _transceiver.checkSendSize(buf, messageSizeMax);
    }

    //
    // Only for use by Connector, Acceptor
    //
    Transceiver(IceInternal.Transceiver transceiver)
    {
        _transceiver = transceiver;
        _configuration = Configuration.getInstance();
    }

    protected synchronized void
    finalize()
        throws Throwable
    {
        super.finalize();
    }

    final private IceInternal.Transceiver _transceiver;
    final private Configuration _configuration;
    private boolean _initialized = false;
}
