// **********************************************************************
//
// Copyright (c) 1999
// Object Oriented Concepts, Inc.
// Billerica, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#ifndef OCI_IIOP_IMPL_H
#define OCI_IIOP_IMPL_H

//
// Declare classes
//
class OCI_IIOP_Transport_impl;
class OCI_IIOP_TransportInfo_impl;
class OCI_IIOP_Acceptor_impl;
class OCI_IIOP_AcceptorInfo_impl;
class OCI_IIOP_Connector_impl;
class OCI_IIOP_ConnectorInfo_impl;
class OCI_IIOP_ConFactory_impl;
class OCI_IIOP_ConFactoryInfo_impl;

//
// The OCI_IIOP_Transport_impl class
//
class OCI_IIOP_Transport_impl : public OCI_Transport
{
    //
    // Hide copy-constructor and assignment operator
    //
    OCI_IIOP_Transport_impl(const OCI_IIOP_Transport_impl&);
    void operator=(const OCI_IIOP_Transport_impl&);

protected:

    OCI_Handle fd_; // The handle
    CORBA_Boolean shutdown_; // Set to true if shutdown(fd_, 1) was called
    CORBA_Boolean block_; // Set to true if blocking IO is selected
    OCI_IIOP_TransportInfo_impl* info_; // Transport information
    
    void setBlock(CORBA_Boolean); // Set blocking/non-blocking behavior

    //
    // The corresponding info class is a friend
    //
    friend class OCI_IIOP_TransportInfo_impl;

public:

    OCI_IIOP_Transport_impl(OCI_IIOP_Connector_impl*,
			    OCI_Handle, CORBA_Boolean);
    OCI_IIOP_Transport_impl(OCI_IIOP_Acceptor_impl*,
			    OCI_Handle, CORBA_Boolean);
    virtual ~OCI_IIOP_Transport_impl();

    //
    // Standard IDL to C++ Mapping
    //
    virtual OCI_ProfileId tag() { return IOP_TAG_INTERNET_IOP; }
    virtual OCI_Handle handle() { return fd_; }
    virtual CORBA_ULong fragmentation() { return 0; }
    virtual void close(CORBA_Boolean);
    virtual void unblock_threads(CORBA_Boolean);
    virtual void receive(OCI_Buffer_ptr, CORBA_Boolean);
    virtual CORBA_Boolean receive_detect(OCI_Buffer_ptr, CORBA_Boolean);
    virtual void receive_timeout(OCI_Buffer_ptr, CORBA_ULong);
    virtual void send(OCI_Buffer_ptr, CORBA_Boolean);
    virtual CORBA_Boolean send_detect(OCI_Buffer_ptr, CORBA_Boolean);
    virtual void send_timeout(OCI_Buffer_ptr, CORBA_ULong);
    virtual OCI_TransportInfo_ptr get_info();
};

//
// The OCI_IIOP_Connector_impl class
//
class OCI_IIOP_Connector_impl : public OCI_Connector
{
    //
    // Hide copy-constructor and assignment operator
    //
    OCI_IIOP_Connector_impl(const OCI_IIOP_Connector_impl&);
    void operator=(const OCI_IIOP_Connector_impl&);

protected:

    CORBA_String_var host_; // The host
    CORBA_UShort port_; // The port
    struct sockaddr_in addr_; // The socket address
    OCI_Handle fd_; // The handle
    OCI_IIOP_ConnectorInfo_impl* info_; // Connector information

    void close(); // Close the connector

    //
    // The corresponding info class is a friend
    //
    friend class OCI_IIOP_ConnectorInfo_impl;

public:

    OCI_IIOP_Connector_impl(const char*, CORBA_UShort,
                            const OCI_ConnectCBSeq& cb);
    virtual ~OCI_IIOP_Connector_impl();

    //
    // Standard IDL to C++ Mapping
    //
    virtual OCI_ProfileId tag() { return IOP_TAG_INTERNET_IOP; }
    virtual OCI_Handle handle() { return fd_; }
    virtual OCI_Transport_ptr connect();
    virtual OCI_Transport_ptr connect_timeout(CORBA_ULong);
    virtual OCI_ObjectKey* is_usable(const OCI_IOR&);
    virtual OCI_ObjectKey* is_usable_with_policies(const OCI_IOR&,
						   const CORBA_PolicyList&);
    virtual OCI_ConnectorInfo_ptr get_info();
};

//
// The OCI_IIOP_Acceptor_impl class
//
class OCI_IIOP_Acceptor_impl : public OCI_Acceptor
{
    //
    // Hide copy-constructor and assignment operator
    //
    OCI_IIOP_Acceptor_impl(const OCI_IIOP_Acceptor_impl&);
    void operator=(const OCI_IIOP_Acceptor_impl&);

protected:

    CORBA_String_var host_; // The host
    CORBA_UShort port_; // The port
    struct sockaddr_in addr_; // The socket address
    OCI_Handle fd_; // The handle
    OCI_IIOP_AcceptorInfo_impl* info_; // Acceptor info

    //
    // The corresponding info class is a friend
    //
    friend class OCI_IIOP_AcceptorInfo_impl;

public:

    OCI_IIOP_Acceptor_impl(const char*, CORBA_UShort);
    virtual ~OCI_IIOP_Acceptor_impl();

    //
    // Standard IDL to C++ Mapping
    //
    virtual OCI_ProfileId tag() { return IOP_TAG_INTERNET_IOP; }
    virtual OCI_Handle handle() { return fd_; }
    virtual void close();
    virtual void unblock_threads();
    virtual void listen();
    virtual OCI_Transport_ptr accept();
    virtual void add_profile(const OCI_ObjectKey&, OCI_IOR&);
    virtual OCI_ObjectKey* is_local(const OCI_IOR&);
    virtual OCI_AcceptorInfo_ptr get_info();
};

//
// The OCI_IIOP_ConFactory_impl class
//
class OCI_IIOP_ConFactory_impl : public OCI_ConFactory
{
    //
    // Hide copy-constructor and assignment operator
    //
    OCI_IIOP_ConFactory_impl(const OCI_IIOP_ConFactory_impl&);
    void operator=(const OCI_IIOP_ConFactory_impl&);

    OCI_IIOP_ConFactoryInfo_impl* info_; // ConFactory info

public:

    OCI_IIOP_ConFactory_impl();
    virtual ~OCI_IIOP_ConFactory_impl();

    //
    // Standard IDL to C++ Mapping
    //
    virtual OCI_ProfileId tag() { return IOP_TAG_INTERNET_IOP; }
    virtual OCI_Connector_ptr create(const OCI_IOR&);
    virtual OCI_Connector_ptr create_with_policies(const OCI_IOR&,
                                                   const CORBA_PolicyList&);
    virtual CORBA_Boolean consider_with_policies(const OCI_IOR&,
						 const CORBA_PolicyList&);
    virtual CORBA_Boolean equivalent(const OCI_IOR&, const OCI_IOR&);
    virtual CORBA_ULong hash(const OCI_IOR&, CORBA_ULong);
    virtual OCI_ConFactoryInfo_ptr get_info();
};

//
// The OCI_IIOP_TransportInfo_impl class
//
class OCI_IIOP_TransportInfo_impl
    : public OCI_IIOP_TransportInfo OB_COMMA_MONITOR
{
    //
    // Hide copy-constructor and assignment operator
    //
    OCI_IIOP_TransportInfo_impl(const OCI_IIOP_TransportInfo_impl&);
    void operator=(const OCI_IIOP_TransportInfo_impl&);

    OCI_ConnectorInfo_var connectorInfo_; // The connector info
    OCI_AcceptorInfo_var acceptorInfo_; // The acceptor info
    OCI_CloseCBSeq closeCBSeq_; // All close callback objects
    OCI_IIOP_Transport_impl* transport_; // The associated transport
    struct sockaddr_in addr_; // Local address and port
    struct sockaddr_in remoteAddr_; // Remote address and port

    //
    // Initialize data members
    //
    void init();

public:

    OCI_IIOP_TransportInfo_impl(OCI_IIOP_Transport_impl* transport,
				OCI_IIOP_Connector_impl* connector);
    OCI_IIOP_TransportInfo_impl(OCI_IIOP_Transport_impl* transport,
				OCI_IIOP_Acceptor_impl* acceptor);
    virtual ~OCI_IIOP_TransportInfo_impl();

    //
    // Standard IDL to C++ Mapping
    //
    virtual OCI_ProfileId tag() { return IOP_TAG_INTERNET_IOP; }
    virtual OCI_ConnectorInfo_ptr connector_info();
    virtual OCI_AcceptorInfo_ptr acceptor_info();
    virtual void add_close_cb(OCI_CloseCB_ptr cb);
    virtual void remove_close_cb(OCI_CloseCB_ptr cb);
    virtual OCI_IIOP_InetAddr_slice* addr();
    virtual CORBA_UShort port();
    virtual OCI_IIOP_InetAddr_slice* remote_addr();
    virtual CORBA_UShort remote_port();

    //
    // ORBacus internal functions
    // Application programs must not use these functions directly
    //
    void _OB_callCloseCB(OCI_TransportInfo_ptr);
    void _OB_destroy();
};

//
// The OCI_IIOP_ConnectorInfo_impl class
//
class OCI_IIOP_ConnectorInfo_impl
    : public OCI_IIOP_ConnectorInfo OB_COMMA_MONITOR
{
    //
    // Hide copy-constructor and assignment operator
    //
    OCI_IIOP_ConnectorInfo_impl(const OCI_IIOP_ConnectorInfo_impl&);
    void operator=(const OCI_IIOP_ConnectorInfo_impl&);

    OCI_ConnectCBSeq connectCBSeq_; // All connect callback objects
    OCI_IIOP_Connector_impl* connector_; // The associated connector

public:

    OCI_IIOP_ConnectorInfo_impl(OCI_IIOP_Connector_impl* connector,
                                const OCI_ConnectCBSeq& cb)
	: connectCBSeq_(cb), connector_(connector) { }
    virtual ~OCI_IIOP_ConnectorInfo_impl() { }

    //
    // Standard IDL to C++ Mapping
    //
    virtual OCI_ProfileId tag() { return IOP_TAG_INTERNET_IOP; }
    virtual void add_connect_cb(OCI_ConnectCB_ptr cb);
    virtual void remove_connect_cb(OCI_ConnectCB_ptr cb);
    virtual OCI_IIOP_InetAddr_slice* remote_addr();
    virtual CORBA_UShort remote_port();

    //
    // ORBacus internal functions
    // Application programs must not use these functions directly
    //
    void _OB_callConnectCB(OCI_TransportInfo_ptr);
    void _OB_destroy();
};

//
// The OCI_IIOP_AcceptorInfo_impl class
//
class OCI_IIOP_AcceptorInfo_impl
    : public OCI_IIOP_AcceptorInfo OB_COMMA_MONITOR
{
    //
    // Hide copy-constructor and assignment operator
    //
    OCI_IIOP_AcceptorInfo_impl(const OCI_IIOP_AcceptorInfo_impl&);
    void operator=(const OCI_IIOP_AcceptorInfo_impl&);

    OCI_AcceptCBSeq acceptCBSeq_; // All accept callback objects
    OCI_IIOP_Acceptor_impl* acceptor_; // The associated acceptor

public:
    
    OCI_IIOP_AcceptorInfo_impl(OCI_IIOP_Acceptor_impl* acceptor)
	: acceptor_(acceptor) { }
    virtual ~OCI_IIOP_AcceptorInfo_impl() { }

    //
    // Standard IDL to C++ Mapping
    //
    virtual OCI_ProfileId tag() { return IOP_TAG_INTERNET_IOP; }
    virtual void add_accept_cb(OCI_AcceptCB_ptr cb);
    virtual void remove_accept_cb(OCI_AcceptCB_ptr cb);
    virtual char* host();
    virtual OCI_IIOP_InetAddr_slice* addr();
    virtual CORBA_UShort port();

    //
    // ORBacus internal functions
    // Application programs must not use these functions directly
    //
    void _OB_callAcceptCB(OCI_TransportInfo_ptr);
    void _OB_destroy();
};

//
// The OCI_IIOP_ConFactoryInfo_impl class
//
class OCI_IIOP_ConFactoryInfo_impl :
    public OCI_IIOP_ConFactoryInfo OB_COMMA_MONITOR
{
    //
    // Hide copy-constructor and assignment operator
    //
    OCI_IIOP_ConFactoryInfo_impl(const OCI_IIOP_ConFactoryInfo_impl&);
    void operator=(const OCI_IIOP_ConFactoryInfo_impl&);

    OCI_ConnectCBSeq connectCBSeq_; // All connect callback objects

public:

    OCI_IIOP_ConFactoryInfo_impl() { }

    //
    // Standard IDL to C++ Mapping
    //
    virtual OCI_ProfileId tag() { return IOP_TAG_INTERNET_IOP; }
    virtual void add_connect_cb(OCI_ConnectCB_ptr cb);
    virtual void remove_connect_cb(OCI_ConnectCB_ptr cb);

    //
    // ORBacus internal functions
    // Application programs must not use these functions directly
    //
    OCI_ConnectCBSeq* _OB_getConnectCBSeq();
};

#endif
