// **********************************************************************
//
// Copyright (c) 2002
// IONA Technologies, Inc.
// Waltham, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#ifndef OB_DSI_H
#define OB_DSI_H

#include <OB/DSI_fwd.h>
#include <OB/Upcall_fwd.h>
#include <OB/NamedValue_fwd.h>
#include <OB/Context_fwd.h>
#include <OB/Stream_fwd.h>

#include <OB/Any.h>
#include <OB/TypeCodeConst.h>
#include <OB/Types.h>
#include <OB/POAServantBase.h>

namespace PortableServer
{

class DynamicImplementation;

} // End of namespace PortableServer


namespace CORBA
{

//
// The ServerRequest class
//
class ServerRequest : public OB::RefCount
{
    PortableServer::DynamicImplementation* dynImpl_;
    OB::Upcall_var up_;
    OB::InputStreamImpl* in_;
    CORBA::NVList_ptr arguments_;
    CORBA::Context_var ctx_;
    CORBA::Any* result_;
    CORBA::Any* exception_;

    ServerRequest(PortableServer::DynamicImplementation*, OB::Upcall_ptr);

    //
    // Only PortableServer::DynamicImplementation may create
    // ServerRequests
    //
    friend class ::PortableServer::DynamicImplementation;

public:

    virtual ~ServerRequest();

    static inline ServerRequest_ptr _duplicate(ServerRequest_ptr p)
    { if(p) p -> _OB_incRef(); return p; }
    static inline ServerRequest_ptr _nil()
    { return 0; }

    //
    // Standard IDL-to-C++ mapping
    //
    virtual const char* operation() const;
    virtual void arguments(NVList_ptr&);
    virtual Context_ptr ctx();
    virtual void set_result(const Any&);
    virtual void set_exception(const Any&);

    //
    // ORBacus internal functions
    // Application programs must not use these functions directly
    //
    virtual void _OB_finishUnmarshal();
    virtual void _OB_postinvoke();
    virtual void _OB_doMarshal();
};

inline void
release(ServerRequest_ptr p)
{
    if(p)
	p -> _OB_decRef();
}

inline Boolean
is_nil(ServerRequest_ptr p)
{
    return p == 0;
}

} // End of namespace CORBA


namespace PortableServer
{

//
// The PortableServer::DynamicImplementation class
//
class DynamicImplementation : public virtual ServantBase
{
    //
    // Hide copy-constructor and assignment operator
    //
    DynamicImplementation(const DynamicImplementation&);
    void operator=(const DynamicImplementation&);

protected:

    DynamicImplementation() { }

public:

    //
    // Standard IDL to C++ Mapping
    //
    CORBA::Object_ptr _this();
    
    virtual void invoke(CORBA::ServerRequest_ptr request) = 0;
    
    virtual CORBA::RepositoryId
    _primary_interface(const ObjectId&, POA_ptr) = 0;

    virtual CORBA::Boolean _is_a(const char* logical_type_id)
        throw(CORBA::SystemException);

    //
    // ORBacus internal functions
    // Application programs must not use these functions directly
    //
    virtual void _OB_dispatch(OB::Upcall_ptr);
};

} // End of namespace PortableServer

#endif
