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

#include <OB/CORBA.h>
#include <Test1.h>
#include <Test2.h>
#include <TestMacro.h>

void
TestDII(CORBA_Object_ptr ti, CORBA_ORB_ptr orb)
{
    CORBA_ULong i, j;

    {
	CORBA_Request_var request;

	request = ti -> _request("opVoid");
	request -> invoke();
    }

    {
	CORBA_Request_var request;

	CORBA_Short ret;
	CORBA_Short inOut;
	CORBA_Short out;

	request = ti -> _request("_set_attrShort");
	request -> add_in_arg() <<= (CORBA_Short)-32768;
	request -> invoke();
	request = ti -> _request("_get_attrShort");
	request -> set_return_type(CORBA__tc_short);
	request -> invoke();
	TEST(request -> return_value() >>= ret);
	TEST(ret == -32768);

	request = ti -> _request("_set_attrShort");
	request -> add_in_arg() <<= (CORBA_Short)32767;
	request -> invoke();
	request = ti -> _request("_get_attrShort");
	request -> set_return_type(CORBA__tc_short);
	request -> invoke();
	TEST(request -> return_value() >>= ret);
	TEST(ret == 32767);

	request = ti -> _request("opShort");
	request -> add_in_arg() <<= (CORBA_Short)10;
	CORBA_Any& inOutAny = request -> add_inout_arg();
	inOutAny <<= (CORBA_Short)20;
	CORBA_Any& outAny = request -> add_out_arg();
	outAny.replace(CORBA__tc_short, 0);
	request -> set_return_type(CORBA__tc_short);
	request -> invoke();
	TEST(inOutAny >>= inOut);
	TEST(outAny >>= out);
	TEST(request -> return_value() >>= ret);
	TEST(ret == 30);
        TEST(inOut == 30);
        TEST(out == 30);
    }

    {
	CORBA_Request_var request;

	CORBA_Double ret;
	CORBA_Double inOut;
	CORBA_Double out;
	    
	request = ti -> _request("_set_attrDouble");
	request -> add_in_arg() <<= 1.7976931348623157E+308;
	request -> invoke();
	request = ti -> _request("_get_attrDouble");
	request -> set_return_type(CORBA__tc_double);
	request -> invoke();
	TEST(request -> return_value() >>= ret);
	TEST(ret == 1.7976931348623157E+308);

	request = ti -> _request("_set_attrDouble");
	request -> add_in_arg() <<= 2.2250738585072014E-308;
	request -> invoke();
	request = ti -> _request("_get_attrDouble");
	request -> set_return_type(CORBA__tc_double);
	request -> invoke();
	TEST(request -> return_value() >>= ret);
#if !( defined(__alpha) && defined(__linux) )
	TEST(ret == 2.2250738585072014E-308);
#endif

	request = ti -> _request("opDouble");
	request -> add_in_arg() <<= 10.0;
	CORBA_Any& inOutAny = request -> add_inout_arg();
	inOutAny <<= 20.0;
	CORBA_Any& outAny = request -> add_out_arg();
	outAny.replace(CORBA__tc_double, 0);
	request -> set_return_type(CORBA__tc_double);
	request -> invoke();
	TEST(inOutAny >>= inOut);
	TEST(outAny >>= out);
	TEST(request -> return_value() >>= ret);
	TEST(ret == 30);
        TEST(inOut == 30);
        TEST(out == 30);
    }

    {
	CORBA_Request_var request;

	char* ret;
	char* inOut;
	char* out;

	request = ti -> _request("_set_attrString");
	request -> add_in_arg() <<= (const char*)"Hello";
	request -> invoke();
	request = ti -> _request("_get_attrString");
	request -> set_return_type(CORBA__tc_string);
	request -> invoke();
	TEST(request -> return_value() >>= ret);
	TEST(strcmp(ret, "Hello") == 0);

	request = ti -> _request("opString");
	request -> add_in_arg() <<= (const char*)"Hello, ";
	CORBA_Any& inOutAny = request -> add_inout_arg();
	inOutAny <<= (const char*)"world!";
	CORBA_Any& outAny = request -> add_out_arg();
	outAny.replace(CORBA__tc_string, 0);
	request -> set_return_type(CORBA__tc_string);
	request -> invoke();
	TEST(inOutAny >>= inOut);
	TEST(outAny >>= out);
	TEST(request -> return_value() >>= ret);
	TEST(strcmp(ret, "Hello, world!") == 0);
	TEST(strcmp(out, "Hello, world!") == 0);
    }

    {
	CORBA_Request_var request;

	TestInterface::StringSequence seq;
	seq.length(3);
	seq[0] = CORBA_string_dup("!!!");
	seq[1] = CORBA_string_dup("@@@");
	seq[2] = CORBA_string_dup("###");

	TestInterface::StringSequence* ret;
	TestInterface::StringSequence* inOut;
	TestInterface::StringSequence* out;

	request = ti -> _request("_set_attrStringSequence");
	request -> add_in_arg() <<= seq;
	request -> invoke();
	request = ti -> _request("_get_attrStringSequence");
	request -> set_return_type(TestInterface::_tc_StringSequence);
	request -> invoke();
	TEST(request -> return_value() >>= ret);
	TEST(ret -> length() == 3);
	TEST(strcmp((*ret)[0], "!!!") == 0);
	TEST(strcmp((*ret)[1], "@@@") == 0);
	TEST(strcmp((*ret)[2], "###") == 0);

	inOut = new TestInterface::StringSequence;
	inOut -> length(2);
	(*inOut)[0] = CORBA_string_dup("%");
	(*inOut)[1] = CORBA_string_dup("^^");
	request = ti -> _request("opStringSequence");
	request -> add_in_arg() <<= seq;
	CORBA_Any& inOutAny = request -> add_inout_arg();
	inOutAny <<= inOut;
	CORBA_Any& outAny = request -> add_out_arg();
	outAny.replace(TestInterface::_tc_StringSequence, 0);
	request -> set_return_type(TestInterface::_tc_StringSequence);
	request -> invoke();
	TEST(request -> return_value() >>= ret);
	TEST(inOutAny >>= inOut);
	TEST(outAny >>= out);
	TEST(ret -> length() == 5);
	TEST(strcmp((*ret)[0], "!!!") == 0);
	TEST(strcmp((*ret)[1], "@@@") == 0);
	TEST(strcmp((*ret)[2], "###") == 0);
	TEST(strcmp((*ret)[3], "%") == 0);
	TEST(strcmp((*ret)[4], "^^") == 0);
	TEST(inOut -> length() == 5);
	TEST(strcmp((*inOut)[0], "!!!") == 0);
	TEST(strcmp((*inOut)[1], "@@@") == 0);
	TEST(strcmp((*inOut)[2], "###") == 0);
	TEST(strcmp((*inOut)[3], "%") == 0);
	TEST(strcmp((*inOut)[4], "^^") == 0);
	TEST(out -> length() == 5);
	TEST(strcmp((*out)[0], "!!!") == 0);
	TEST(strcmp((*out)[1], "@@@") == 0);
	TEST(strcmp((*out)[2], "###") == 0);
	TEST(strcmp((*out)[3], "%") == 0);
	TEST(strcmp((*out)[4], "^^") == 0);
    }

    {
	CORBA_Request_var request;

	CORBA_Char ret;
	CORBA_Char inOut;
	CORBA_Char out;
	    
	request = ti -> _request("_set_attrChar");
	request -> add_in_arg() <<= CORBA_Any::from_char('a');
	request -> invoke();
	request = ti -> _request("_get_attrChar");
	request -> set_return_type(CORBA__tc_char);
	request -> send_deferred();
	request -> get_response();
	TEST(request -> return_value() >>= CORBA_Any::to_char(ret));
	TEST(ret == 'a');

	request = ti -> _request("opChar");
	request -> add_in_arg() <<= CORBA_Any::from_char('a');
	CORBA_Any& inOutAny = request -> add_inout_arg();
	inOutAny <<= CORBA_Any::from_char(1);
	CORBA_Any& outAny = request -> add_out_arg();
	outAny.replace(CORBA__tc_char, 0);
	request -> set_return_type(CORBA__tc_char);
	request -> send_deferred();
	request -> get_response();
	TEST(inOutAny >>= CORBA_Any::to_char(inOut));
	TEST(outAny >>= CORBA_Any::to_char(out));
	TEST(request -> return_value() >>= CORBA_Any::to_char(ret));
	TEST(ret == 'b');
        TEST(inOut == 'b');
        TEST(out == 'b');
    }

    {
	CORBA_Request_var request;

	TestInterface::VariableArray ar =
	{ 
	    {
		CORBA_string_dup("aa"),
		CORBA_string_dup("bb"),
		CORBA_string_dup("cc")
	    },
	    {
		CORBA_string_dup("AA"),
		CORBA_string_dup("BB"),
		CORBA_string_dup("CC")
	    }
	};
	
	TestInterface::VariableArray_forany ret;
	TestInterface::VariableArray_forany inOut;
	TestInterface::VariableArray_forany out;

	request = ti -> _request("_set_attrVariableArray");
	request -> add_in_arg() <<= TestInterface::VariableArray_forany(ar);
	request -> invoke();
	request = ti -> _request("_get_attrVariableArray");
	request -> set_return_type(TestInterface::_tc_VariableArray);
	request -> send_deferred();
	while(!request -> poll_response())
	    ;
	TEST(request -> return_value() >>= ret);
	for(i = 0 ; i < 2 ; i++)
	    for(j = 0 ; j < 3 ; j++)
	    {
		TEST(strcmp(ar[i][j], ret[i][j]) == 0);
	    }

	TestInterface::VariableArray_slice* ar2 =
	    TestInterface::VariableArray_alloc();
	for(i = 0 ; i < 2 ; i++)
	    for(j = 0 ; j < 3 ; j++)
		ar2[i][j] = CORBA_string_dup("abc");
	request = ti -> _request("opVariableArray");
	request -> add_in_arg() <<= TestInterface::VariableArray_forany(ar);
	CORBA_Any& inOutAny = request -> add_inout_arg();
	inOutAny <<= TestInterface::VariableArray_forany(ar2, true);
	CORBA_Any& outAny = request -> add_out_arg();
	outAny.replace(TestInterface::_tc_VariableArray, 0);
	request -> set_return_type(TestInterface::_tc_VariableArray);
	request -> send_deferred();
	while(!request -> poll_response())
	    ;
	TEST(request -> return_value() >>= ret);
	TEST(inOutAny >>= inOut);
	TEST(outAny >>= out);
	for(i = 0 ; i < 2 ; i++)
	    for(j = 0 ; j < 3 ; j++)
	    {
		TEST(strcmp(ar[i][j], ret[i][j]) == 0);
		TEST(strcmp(ar[i][j], inOut[i][j]) == 0);
		TEST(strcmp(ar[i][j], out[i][j]) == 0);
	    }
    }

    {
	CORBA_Request_var request;

	request = ti -> _request("_set_attrUShort");
	request -> add_in_arg() <<= (CORBA_UShort)1234;
	request -> invoke();
	
	CORBA_ORB::RequestSeq requests;
	requests.length(5);
	
	for(i = 0 ; i < requests.length() ; i++)
	{
	    requests[i] = ti -> _request("_get_attrUShort");
	    requests[i] -> set_return_type(CORBA__tc_ushort);
	}
	
	orb -> send_multiple_requests_deferred(requests);
	
	for(i = 0 ; i < requests.length() ; i++)
	{
	    while(!orb -> poll_next_response())
		;
	    
	    orb -> get_next_response(request.out());

	    CORBA_UShort ret;
	    TEST(request -> return_value() >>= ret);
	    TEST(ret == 1234);
	}
    }

    {
	CORBA_Float ret;
	CORBA_Float inOut;
	CORBA_Float out;

	CORBA_Request_var request1;
	request1 = ti -> _request("_set_attrFloat");
	request1 -> add_in_arg() <<= (CORBA_Float)1;
	request1 -> send_deferred();

	CORBA_Request_var request2;
	request2 = ti -> _request("_get_attrFloat");
	request2 -> set_return_type(CORBA__tc_float);
	request2 -> send_deferred();

	CORBA_Request_var request3;
	request3 = ti -> _request("_set_attrFloat");
	request3 -> add_in_arg() <<= (CORBA_Float)-1;
	request3 -> send_deferred();

	CORBA_Request_var request4;
	request4 = ti -> _request("_get_attrFloat");
	request4 -> set_return_type(CORBA__tc_float);
	request4 -> send_deferred();

	CORBA_Request_var request5;
	request5 = ti -> _request("opFloat");
	request5 -> add_in_arg() <<= (CORBA_Float)10;
	CORBA_Any& inOutAny = request5 -> add_inout_arg();
	inOutAny <<= (CORBA_Float)20;
	CORBA_Any& outAny = request5 -> add_out_arg();
	outAny.replace(CORBA__tc_float, 0);
	request5 -> set_return_type(CORBA__tc_float);
	request5 -> send_deferred();

	request5 -> get_response();
	TEST(inOutAny >>= inOut);
	TEST(outAny >>= out);
	TEST(request5 -> return_value() >>= ret);
	TEST(ret == 30);
        TEST(inOut == 30);
        TEST(out == 30);

	request2 -> get_response();
	TEST(request2 -> return_value() >>= ret);
	TEST(ret == 1);

	request4 -> get_response();
	TEST(request4 -> return_value() >>= ret);
	TEST(ret == -1);

	request1 -> get_response();
	request3 -> get_response();
    }
}
