// **********************************************************************
//
// 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
TestStubException(TestInterfaceEx_ptr ti, bool dyn)
{
    CORBA_ULong i, j, k, l;

    {
	try
	{
	    ti -> opVoidEx();
	    TEST(false);
	}
	catch(TestInterfaceEx::ExVoid&)
	{
	}
    }

    {
	CORBA_Short inOut, out;
	inOut = 20;

	try
	{
	    ti -> opShortEx(10, inOut, out);
	    TEST(false);
	}
	catch(TestInterfaceEx::ExShort& ex)
	{
	    TEST(ex.value == 30);
	}
    }

    {
	CORBA_Long inOut, out;
	inOut = 20;

	try
	{
	    ti -> opLongEx(10, inOut, out);
	    TEST(false);
	}
	catch(TestInterfaceEx::ExLong& ex)
	{
	    TEST(ex.value == 30);
	}
    }

    {
	CORBA_UShort inOut, out;
	inOut = 20;

	try
	{
	    ti -> opUShortEx(10, inOut, out);
	    TEST(false);
	}
	catch(TestInterfaceEx::ExUShort& ex)
	{
	    TEST(ex.value == 30);
	}
    }

    {
	CORBA_ULong inOut, out;
	inOut = 20;

	try
	{
	    ti -> opULongEx(10, inOut, out);
	    TEST(false);
	}
	catch(TestInterfaceEx::ExULong& ex)
	{
	    TEST(ex.value == 30);
	}
    }

    {
	CORBA_Float inOut, out;
	inOut = 20;

	try
	{
	    ti -> opFloatEx(10, inOut, out);
	    TEST(false);
	}
	catch(TestInterfaceEx::ExFloat& ex)
	{
	    TEST(ex.value == 30);
	}
    }

    {
	CORBA_Double inOut, out;
	inOut = 20;

	try
	{
	    ti -> opDoubleEx(10, inOut, out);
	    TEST(false);
	}
	catch(TestInterfaceEx::ExDouble& ex)
	{
	    TEST(ex.value == 30);
	}
    }

    {
	CORBA_Boolean inOut, out;
	inOut = true;

	try
	{
	    ti -> opBooleanEx(true, inOut, out);
	    TEST(false);
	}
	catch(TestInterfaceEx::ExBoolean& ex)
	{
	    TEST(ex.value == CORBA_TRUE);
	}
    }

    {
	CORBA_Char inOut, out;
	inOut = 1;

	try
	{
	    ti -> opCharEx('a', inOut, out);
	    TEST(false);
	}
	catch(TestInterfaceEx::ExChar& ex)
	{
	    TEST(ex.value == 'b');
	}
    }

    {
	CORBA_Octet inOut, out;
	inOut = 20;

	try
	{
	    ti -> opOctetEx(10, inOut, out);
	    TEST(false);
	}
	catch(TestInterfaceEx::ExOctet& ex)
	{
	    TEST(ex.value == 30);
	}
    }

    {
	CORBA_String_var inOut, out;
	inOut = CORBA_string_dup("world!");

	try
	{
	    ti -> opStringEx("Hello, ", inOut.inout(), out.out());
	    TEST(false);
	}
	catch(TestInterfaceEx::ExString& ex)
	{
	    TEST(strcmp(ex.value, "Hello, world!") == 0);
	}
    }

    {
	TestInterfaceEx::VariableStruct vStruct;
	vStruct.s = CORBA_string_dup("xyz");
	CORBA_Any any;
	any <<= vStruct;
	CORBA_Any inOut;
	CORBA_Any_var out;

	try
	{
	    ti -> opAnyEx(any, inOut, out);
	    TEST(false);
	}
	catch(TestInterfaceEx::ExAny& ex)
	{
	    TestInterfaceEx::VariableStruct* vStructRet;
	    TEST(ex.value >>= vStructRet);
	    TEST(strcmp(vStructRet -> s, "xyz") == 0);
	}
    }

    {
	TestInterfaceEx::TestEnum inOut, out;
	inOut = TestInterfaceEx::TestEnum2;

	try
	{
	    ti -> opTestEnumEx(TestInterfaceEx::TestEnum3, inOut, out);
	    TEST(false);
	}
	catch(TestInterfaceEx::ExTestEnum& ex)
	{
	    TEST(ex.value == TestInterfaceEx::TestEnum3);
	}
    }

    if(!dyn) // This does not (yet) work with the DSI
    {
	TestInterface_var inOut, out;
	inOut = TestInterface::_duplicate(ti);
	try
	{
	    ti -> opTestInterfaceEx(ti, inOut.inout(), out.out());
	    TEST(false);
	}
	catch(TestInterfaceEx::ExTestInterface& ex)
	{
	    TEST(ex.value -> _hash(1000) == ti -> _hash(1000));
	    TEST(ex.value -> _is_equivalent(ti));
	}
    }

    {
	TestInterfaceEx::FixedStruct st;
	st.s = 100;
	st.l = -100;
	TestInterfaceEx::FixedStruct inOut, out;
	inOut.s = 10000;
	inOut.l = 100000;
	    
	try
	{
	    ti -> opFixedStructEx(st, inOut, out);
	    TEST(false);
	}
	catch(TestInterfaceEx::ExFixedStruct& ex)
	{
	    TEST(ex.value.s == st.s);
	    TEST(ex.value.l == st.l);
	}

	{
	    TestInterfaceEx::VariableStruct st;
	    st.s = CORBA_string_dup("$$$");
	    TestInterfaceEx::VariableStruct inOut;
	    TestInterfaceEx::VariableStruct_var out;
	    inOut.s = CORBA_string_dup("bla");

	    try
	    {
		ti -> opVariableStructEx(st, inOut, out);
		TEST(false);
	    }
	    catch(TestInterfaceEx::ExVariableStruct& ex)
	    {
		TEST(strcmp(ex.value.s, st.s) == 0);
	    }
	}

	{
	    TestInterface::FixedUnion un;
	    un.b(true);
	    un._d(999);
	    TestInterface::FixedUnion inOut, out;
	    inOut.l(100);

	    try
	    {
		ti -> opFixedUnionEx(un, inOut, out);
		TEST(false);
	    }
	    catch(TestInterfaceEx::ExFixedUnion& ex)
	    {
		TEST(ex.value._d() == 999);
		TEST(ex.value.b() == CORBA_TRUE);
	    }
	}

	if(!dyn) // This does not (yet) work with the DSI
	{
	    TestInterface::VariableUnion un;
	    un.ti(ti);
	    TestInterface::VariableUnion inOut;
	    TestInterface::VariableUnion_var out;
	    TestInterface::VariableStruct st;
	    st.s = CORBA_string_dup("bla");
	    inOut.st(st);

	    try
	    {
		ti -> opVariableUnionEx(un, inOut, out);
		TEST(false);
	    }
	    catch(TestInterfaceEx::ExVariableUnion& ex)
	    {
		TEST(ex.value.ti() -> _hash(2000) == ti -> _hash(2000));
		TEST(ex.value.ti() -> _is_equivalent(ti));
	    }
	}
    }

    {
	TestInterfaceEx::StringSequence seq;
	seq.length(3);
	seq[0] = CORBA_string_dup("!!!");
	seq[1] = CORBA_string_dup("@@@");
	seq[2] = CORBA_string_dup("###");
	TestInterfaceEx::StringSequence inOut;
	TestInterfaceEx::StringSequence_var out;
	inOut.length(2);
	inOut[0] = CORBA_string_dup("%");
	inOut[1] = CORBA_string_dup("^^");

	try
	{
	    ti -> opStringSequenceEx(seq, inOut, out);
	    TEST(false);
	}
	catch(TestInterfaceEx::ExStringSequence& ex)
	{
	    TEST(ex.value.length() == 5);
	    TEST(strcmp(ex.value[0], "!!!") == 0);
	    TEST(strcmp(ex.value[1], "@@@") == 0);
	    TEST(strcmp(ex.value[2], "###") == 0);
	    TEST(strcmp(ex.value[3], "%") == 0);
	    TEST(strcmp(ex.value[4], "^^") == 0);
	}
    }

    {
	TestInterfaceEx::FixedArray ar =
	{
	    {
		{ 1, 2, 3, 4 },
		{ 10, -10, 11, -11 },
		{ -999, 0, 888, 123 }
	    },
	    {
		{ 17, 27, 37, 47 },
		{ 710, -710, 711, -711 },
		{ -99, 0, 88, 13 }
	    }
	};
	
	TestInterfaceEx::FixedArray_var ret;
	TestInterfaceEx::FixedArray inOut, out;
	for(i = 0 ; i < 2 ; i++)
	    for(j = 0 ; j < 3 ; j++)
		for(k = 0 ; k < 4 ; k++)
		    inOut[i][j][k] = (short)(i + j + k);

	try
	{
#ifdef HAVE_VCPLUSPLUS_BUGS
	    ti -> opFixedArrayEx((const TestInterface::FixedArray_slice*)ar,
				 inOut, out);
#else
	    ti -> opFixedArrayEx(ar, inOut, out);
#endif
	    TEST(false);
	}
	catch(TestInterfaceEx::ExFixedArray& ex)
	{
	    for(i = 0 ; i < 2 ; i++)
		for(j = 0 ; j < 3 ; j++)
		    for(k = 0 ; k < 4 ; k++)
		    {
			TEST(ar[i][j][k] == ex.value[i][j][k]);
		    }
	}
    }

    {
	TestInterfaceEx::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")
	    }
	};
	
	TestInterfaceEx::VariableArray_var ret;
	TestInterfaceEx::VariableArray inOut;
	for(i = 0 ; i < 2 ; i++)
	    for(j = 0 ; j < 3 ; j++)
		inOut[i][j] = CORBA_string_dup("abc");
	TestInterfaceEx::VariableArray_var out;

	try
	{
#ifdef HAVE_VCPLUSPLUS_BUGS
	    ti -> opVariableArrayEx((const TestInterface::VariableArray_slice*)
				    ar, inOut, out.out());
#else
	    ti -> opVariableArrayEx(ar, inOut, out.out());
#endif
	    TEST(false);
	}
	catch(TestInterfaceEx::ExVariableArray& ex)
	{
	    for(i = 0 ; i < 2 ; i++)
		for(j = 0 ; j < 3 ; j++)
		{
		    TEST(strcmp(ar[i][j], ex.value[i][j]) == 0);
		}
	}
    }

    {
	TestInterface::FixedArray ar0 =
	{
	    {
		{ 1, 2, 3, 4 },
		{ 10, -10, 11, -11 },
		{ -999, 0, 888, 123 }
	    },
	    {
		{ 17, 27, 37, 47 },
		{ 710, -710, 711, -711 },
		{ -99, 0, 88, 13 }
	    }
	};
	
	TestInterface::FixedArray ar1 =
	{
	    {
		{ 2, 3, 4, 1 },
		{ 10, 11, 11, -10 },
		{ -0, 239, 123, 888 }
	    },
	    {
		{ 17, 37, 47, 27 },
		{ 710, -710, 711, -711 },
		{ -0, -99, 13, 8338 }
	    }
	};
	
	TestInterface::FixedArray ar2 =
	{
	    {
		{ 1, 2, -3, -234 },
		{ 10, -11, 11, -10 },
		{ -999, 30, 1888, 123 }
	    },
	    {
		{ 27, 37, 117, 47 },
		{ 710, -7150, 711, -711 },
		{ -0, 13, 929, 88 }
	    }
	};
	
	TestInterface::FixedArraySequence seq;
	seq.length(3);
	TestInterface::FixedArray_copy(ar0, seq[0]);
	TestInterface::FixedArray_copy(ar1, seq[1]);
	TestInterface::FixedArray_copy(ar2, seq[2]);

	TestInterface::FixedArraySequence inOut;
	inOut.length(4);
	for(l = 0 ; l < 4 ; l++)
	    for(i = 0 ; i < 2 ; i++)
		for(j = 0 ; j < 3 ; j++)
		    for(k = 0 ; k < 4 ; k++)
			inOut[l][i][j][k] = (short)(i + j + k + l);

	TestInterface::FixedArraySequence_var ret;
	TestInterface::FixedArraySequence_var out;

	try
	{
	    ret = ti -> opFixedArraySequenceEx(seq, inOut, out.out());
	    TEST(false);
	}
	catch(TestInterfaceEx::ExFixedArraySequence& ex)
	{
	    TEST(ex.value.length() == 7);
	    
	    for(l = 0 ; l < 3 ; l++)
		for(i = 0 ; i < 2 ; i++)
		    for(j = 0 ; j < 3 ; j++)
			for(k = 0 ; k < 4 ; k++)
			{
			    TEST(seq[l][i][j][k] == ex.value[l][i][j][k]);
			}

	    for(l = 0 ; l < 4 ; l++)
		for(i = 0 ; i < 2 ; i++)
		    for(j = 0 ; j < 3 ; j++)
			for(k = 0 ; k < 4 ; k++)
			{
			    TEST(ex.value[3 + l][i][j][k] ==
				 (CORBA_Long)(i + j + k + l));
			}
	}
    }

    {
	TestInterface::VariableArray ar0 =
	{ 
	    {
		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 ar1 =
	{ 
	    {
		CORBA_string_dup("a~a"),
		CORBA_string_dup("b~b"),
		CORBA_string_dup("c~c")
	    },
	    {
		CORBA_string_dup("A~A"),
		CORBA_string_dup("B~B"),
		CORBA_string_dup("C~C")
	    }
	};

	TestInterface::VariableArraySequence seq;
	seq.length(2);
	TestInterface::VariableArray_copy(ar0, seq[0]);
	TestInterface::VariableArray_copy(ar1, seq[1]);

	TestInterface::VariableArraySequence inOut;
	inOut.length(4);
	for(l = 0 ; l < 4 ; l++)
	    for(i = 0 ; i < 2 ; i++)
		for(j = 0 ; j < 3 ; j++)
		    inOut[l][i][j] = CORBA_string_dup("***");

	TestInterface::VariableArraySequence_var ret;
	TestInterface::VariableArraySequence_var out;
	
	try
	{
	    ret = ti -> opVariableArraySequenceEx(seq, inOut, out);
	    TEST(false);
	}
	catch(TestInterfaceEx::ExVariableArraySequence& ex)
	{
	    TEST(ex.value.length() == 6);
	    
	    for(l = 0 ; l < 2 ; l++)
		for(i = 0 ; i < 2 ; i++)
		    for(j = 0 ; j < 3 ; j++)
		    {
			TEST(strcmp(seq[l][i][j],
				    ex.value[l][i][j]) == 0);
		    }
	    
	    for(l = 0 ; l < 4 ; l++)
		for(i = 0 ; i < 2 ; i++)
		    for(j = 0 ; j < 3 ; j++)
		    {
			TEST(strcmp(ex.value[2 + l][i][j], "***") == 0);
		    }
	}
    }

    {
	try
	{
	    ti -> op_UNKNOWN_Ex();
	    TEST(false);
	}
	catch(const CORBA_UNKNOWN& ex)
	{
	    TEST(ex.minor() == 1);
	    TEST(ex.completed() == CORBA_COMPLETED_YES);
	}

	try
	{
	    ti -> op_BAD_PARAM_Ex();
	    TEST(false);
	}
	catch(const CORBA_BAD_PARAM& ex)
	{
	    TEST(ex.minor() == 2);
	    TEST(ex.completed() == CORBA_COMPLETED_NO);
	}

	try
	{
	    ti -> op_NO_MEMORY_Ex();
	    TEST(false);
	}
	catch(const CORBA_NO_MEMORY& ex)
	{
	    TEST(ex.minor() == 3);
	    TEST(ex.completed() == CORBA_COMPLETED_MAYBE);
	}

	try
	{
	    ti -> op_IMP_LIMIT_Ex();
	    TEST(false);
	}
	catch(const CORBA_IMP_LIMIT& ex)
	{
	    TEST(ex.minor() == 4);
	    TEST(ex.completed() == CORBA_COMPLETED_YES);
	}

	try
	{
	    ti -> op_COMM_FAILURE_Ex();
	    TEST(false);
	}
	catch(const CORBA_COMM_FAILURE& ex)
	{
	    TEST(ex.minor() == 5);
	    TEST(ex.completed() == CORBA_COMPLETED_NO);
	}

	try
	{
	    ti -> op_INV_OBJREF_Ex();
	    TEST(false);
	}
	catch(const CORBA_INV_OBJREF& ex)
	{
	    TEST(ex.minor() == 6);
	    TEST(ex.completed() == CORBA_COMPLETED_MAYBE);
	}

	try
	{
	    ti -> op_NO_PERMISSION_Ex();
	    TEST(false);
	}
	catch(const CORBA_NO_PERMISSION& ex)
	{
	    TEST(ex.minor() == 7);
	    TEST(ex.completed() == CORBA_COMPLETED_YES);
	}

	try
	{
	    ti -> op_INTERNAL_Ex();
	    TEST(false);
	}
	catch(const CORBA_INTERNAL& ex)
	{
	    TEST(ex.minor() == 8);
	    TEST(ex.completed() == CORBA_COMPLETED_NO);
	}

	try
	{
	    ti -> op_MARSHAL_Ex();
	    TEST(false);
	}
	catch(const CORBA_MARSHAL& ex)
	{
	    TEST(ex.minor() == 9);
	    TEST(ex.completed() == CORBA_COMPLETED_MAYBE);
	}

	try
	{
	    ti -> op_INITIALIZE_Ex();
	    TEST(false);
	}
	catch(const CORBA_INITIALIZE& ex)
	{
	    TEST(ex.minor() == 10);
	    TEST(ex.completed() == CORBA_COMPLETED_YES);
	}

	try
	{
	    ti -> op_NO_IMPLEMENT_Ex();
	    TEST(false);
	}
	catch(const CORBA_NO_IMPLEMENT& ex)
	{
	    TEST(ex.minor() == 11);
	    TEST(ex.completed() == CORBA_COMPLETED_NO);
	}

	try
	{
	    ti -> op_BAD_TYPECODE_Ex();
	    TEST(false);
	}
	catch(const CORBA_BAD_TYPECODE& ex)
	{
	    TEST(ex.minor() == 12);
	    TEST(ex.completed() == CORBA_COMPLETED_MAYBE);
	}

	try
	{
	    ti -> op_BAD_OPERATION_Ex();
	    TEST(false);
	}
	catch(const CORBA_BAD_OPERATION& ex)
	{
	    TEST(ex.minor() == 13);
	    TEST(ex.completed() == CORBA_COMPLETED_YES);
	}

	try
	{
	    ti -> op_NO_RESOURCES_Ex();
	    TEST(false);
	}
	catch(const CORBA_NO_RESOURCES& ex)
	{
	    TEST(ex.minor() == 14);
	    TEST(ex.completed() == CORBA_COMPLETED_NO);
	}

	try
	{
	    ti -> op_NO_RESPONSE_Ex();
	    TEST(false);
	}
	catch(const CORBA_NO_RESPONSE& ex)
	{
	    TEST(ex.minor() == 15);
	    TEST(ex.completed() == CORBA_COMPLETED_MAYBE);
	}

	try
	{
	    ti -> op_PERSIST_STORE_Ex();
	    TEST(false);
	}
	catch(const CORBA_PERSIST_STORE& ex)
	{
	    TEST(ex.minor() == 16);
	    TEST(ex.completed() == CORBA_COMPLETED_YES);
	}

	try
	{
	    ti -> op_BAD_INV_ORDER_Ex();
	    TEST(false);
	}
	catch(const CORBA_BAD_INV_ORDER& ex)
	{
	    TEST(ex.minor() == 17);
	    TEST(ex.completed() == CORBA_COMPLETED_NO);
	}

	try
	{
	    ti -> op_TRANSIENT_Ex();
	    TEST(false);
	}
	catch(const CORBA_TRANSIENT& ex)
	{
	    TEST(ex.minor() == 18);
	    TEST(ex.completed() == CORBA_COMPLETED_MAYBE);
	}

	try
	{
	    ti -> op_FREE_MEM_Ex();
	    TEST(false);
	}
	catch(const CORBA_FREE_MEM& ex)
	{
	    TEST(ex.minor() == 19);
	    TEST(ex.completed() == CORBA_COMPLETED_YES);
	}

	try
	{
	    ti -> op_INV_IDENT_Ex();
	    TEST(false);
	}
	catch(const CORBA_INV_IDENT& ex)
	{
	    TEST(ex.minor() == 20);
	    TEST(ex.completed() == CORBA_COMPLETED_NO);
	}

	try
	{
	    ti -> op_INV_FLAG_Ex();
	    TEST(false);
	}
	catch(const CORBA_INV_FLAG& ex)
	{
	    TEST(ex.minor() == 21);
	    TEST(ex.completed() == CORBA_COMPLETED_MAYBE);
	}

	try
	{
	    ti -> op_INTF_REPOS_Ex();
	    TEST(false);
	}
	catch(const CORBA_INTF_REPOS& ex)
	{
	    TEST(ex.minor() == 22);
	    TEST(ex.completed() == CORBA_COMPLETED_YES);
	}

	try
	{
	    ti -> op_BAD_CONTEXT_Ex();
	    TEST(false);
	}
	catch(const CORBA_BAD_CONTEXT& ex)
	{
	    TEST(ex.minor() == 23);
	    TEST(ex.completed() == CORBA_COMPLETED_NO);
	}

	try
	{
	    ti -> op_OBJ_ADAPTER_Ex();
	    TEST(false);
	}
	catch(const CORBA_OBJ_ADAPTER& ex)
	{
	    TEST(ex.minor() == 24);
	    TEST(ex.completed() == CORBA_COMPLETED_MAYBE);
	}

	try
	{
	    ti -> op_DATA_CONVERSION_Ex();
	    TEST(false);
	}
	catch(const CORBA_DATA_CONVERSION& ex)
	{
	    TEST(ex.minor() == 25);
	    TEST(ex.completed() == CORBA_COMPLETED_YES);
	}

	try
	{
	    ti -> op_OBJECT_NOT_EXIST_Ex();
	    TEST(false);
	}
	catch(const CORBA_OBJECT_NOT_EXIST& ex)
	{
	    TEST(ex.minor() == 26);
	    TEST(ex.completed() == CORBA_COMPLETED_NO);
	}

	try
	{
	    ti -> op_TRANSACTION_REQUIRED_Ex();
	    TEST(false);
	}
	catch(const CORBA_TRANSACTION_REQUIRED& ex)
	{
	    TEST(ex.minor() == 27);
	    TEST(ex.completed() == CORBA_COMPLETED_NO);
	}

	try
	{
	    ti -> op_TRANSACTION_ROLLEDBACK_Ex();
	    TEST(false);
	}
	catch(const CORBA_TRANSACTION_ROLLEDBACK& ex)
	{
	    TEST(ex.minor() == 28);
	    TEST(ex.completed() == CORBA_COMPLETED_NO);
	}

	try
	{
	    ti -> op_INVALID_TRANSACTION_Ex();
	    TEST(false);
	}
	catch(const CORBA_INVALID_TRANSACTION& ex)
	{
	    TEST(ex.minor() == 29);
	    TEST(ex.completed() == CORBA_COMPLETED_NO);
	}

	try
	{
	    ti -> op_INV_POLICY_Ex();
	    TEST(false);
	}
	catch(const CORBA_INV_POLICY& ex)
	{
	    TEST(ex.minor() == 30);
	    TEST(ex.completed() == CORBA_COMPLETED_NO);
	}
    }
}


