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

#include <OB/Basic.h>
#include <OB/Except.h>

// ----------------------------------------------------------------------
// Exception classes member implementation
// ----------------------------------------------------------------------

CORBA_SystemException*
CORBA_SystemException::_narrow(CORBA_Exception* p)
{
#ifdef HAVE_NO_RTTI
    if(!p)
	return 0;
    else
	return (CORBA_SystemException*)
	    (p -> _OB_narrowHelp("IDL:omg.org/CORBA/SystemException:1.0"));
#else
    return dynamic_cast<CORBA_SystemException*>(p);
#endif
}

const char*
CORBA_SystemException::_type_id() const
{
    return "IDL:omg.org/CORBA/SystemException:1.0";
}

#ifdef HAVE_NO_RTTI
void*
CORBA_SystemException::_OB_narrowHelp(const char* id) const
{
    if(strcmp("IDL:omg.org/CORBA/SystemException:1.0", id) == 0)
        return (void*)this;
    else
        return 0;
}
#endif

CORBA_UserException*
CORBA_UserException::_narrow(CORBA_Exception* p)
{
#ifdef HAVE_NO_RTTI
    if(!p)
	return 0;
    else
	return (CORBA_UserException*)
	    (p -> _OB_narrowHelp("IDL:omg.org/CORBA/UserException:1.0"));
#else
    return dynamic_cast<CORBA_UserException*>(p);
#endif
}

const char*
CORBA_UserException::_type_id() const
{
    return "IDL:omg.org/CORBA/UserException:1.0";
}

#ifdef HAVE_NO_RTTI
void*
CORBA_UserException::_OB_narrowHelp(const char* id) const
{
    if(strcmp("IDL:omg.org/CORBA/UserException:1.0", id) == 0)
        return (void*)this;
    else
        return 0;
}
#endif

#ifdef HAVE_NO_RTTI

#define OB_MAKE_STANDARD_EXCEPTION_I(T) \
CORBA_##T* \
CORBA_##T::_narrow(CORBA_Exception* p) \
{ \
    if(!p) \
	return 0; \
    else \
	return (CORBA_##T*) \
	     (p -> _OB_narrowHelp("IDL:omg.org/CORBA/" #T ":1.0")); \
} \
\
const char* \
CORBA_##T::_type_id() const \
{ \
    return "IDL:omg.org/CORBA/" #T ":1.0"; \
} \
\
void* \
CORBA_##T::_OB_narrowHelp(const char* id) const \
{ \
    if(strcmp("IDL:omg.org/CORBA/" #T ":1.0", id) == 0) \
        return (void*)this; \
    else \
        return CORBA_SystemException::_OB_narrowHelp(id); \
} \
\
CORBA_Exception* \
CORBA_##T::_OB_clone() const \
{ \
    return new CORBA_##T(*this); \
}

#else

#define OB_MAKE_STANDARD_EXCEPTION_I(T) \
CORBA_##T* \
CORBA_##T::_narrow(CORBA_Exception* p) \
{ \
    return dynamic_cast<CORBA_##T*>(p); \
} \
\
const char* \
CORBA_##T::_type_id() const \
{ \
    return "IDL:omg.org/CORBA/" #T ":1.0"; \
} \
\
CORBA_Exception* \
CORBA_##T::_OB_clone() const \
{ \
    return new CORBA_##T(*this); \
}

#endif

OB_MAKE_STANDARD_EXCEPTION_I(UNKNOWN)
OB_MAKE_STANDARD_EXCEPTION_I(BAD_PARAM)
OB_MAKE_STANDARD_EXCEPTION_I(NO_MEMORY)
OB_MAKE_STANDARD_EXCEPTION_I(IMP_LIMIT)
OB_MAKE_STANDARD_EXCEPTION_I(COMM_FAILURE)
OB_MAKE_STANDARD_EXCEPTION_I(INV_OBJREF)
OB_MAKE_STANDARD_EXCEPTION_I(NO_PERMISSION)
OB_MAKE_STANDARD_EXCEPTION_I(INTERNAL)
OB_MAKE_STANDARD_EXCEPTION_I(MARSHAL)
OB_MAKE_STANDARD_EXCEPTION_I(INITIALIZE)
OB_MAKE_STANDARD_EXCEPTION_I(NO_IMPLEMENT)
OB_MAKE_STANDARD_EXCEPTION_I(BAD_TYPECODE)
OB_MAKE_STANDARD_EXCEPTION_I(BAD_OPERATION)
OB_MAKE_STANDARD_EXCEPTION_I(NO_RESOURCES)
OB_MAKE_STANDARD_EXCEPTION_I(NO_RESPONSE)
OB_MAKE_STANDARD_EXCEPTION_I(PERSIST_STORE)
OB_MAKE_STANDARD_EXCEPTION_I(BAD_INV_ORDER)
OB_MAKE_STANDARD_EXCEPTION_I(TRANSIENT)
OB_MAKE_STANDARD_EXCEPTION_I(FREE_MEM)
OB_MAKE_STANDARD_EXCEPTION_I(INV_IDENT)
OB_MAKE_STANDARD_EXCEPTION_I(INV_FLAG)
OB_MAKE_STANDARD_EXCEPTION_I(INTF_REPOS)
OB_MAKE_STANDARD_EXCEPTION_I(BAD_CONTEXT)
OB_MAKE_STANDARD_EXCEPTION_I(OBJ_ADAPTER)
OB_MAKE_STANDARD_EXCEPTION_I(DATA_CONVERSION)
OB_MAKE_STANDARD_EXCEPTION_I(OBJECT_NOT_EXIST)
OB_MAKE_STANDARD_EXCEPTION_I(TRANSACTION_REQUIRED)
OB_MAKE_STANDARD_EXCEPTION_I(TRANSACTION_ROLLEDBACK)
OB_MAKE_STANDARD_EXCEPTION_I(INVALID_TRANSACTION)
OB_MAKE_STANDARD_EXCEPTION_I(INV_POLICY)

void
OBMarshal(const CORBA_SystemException& val, CORBA_Octet*& oct)
{
    OBMarshal(val._type_id(), oct);
    OBMarshal(val.minor(), oct);
    OBMarshal((CORBA_ULong)val.completed(), oct);
}

void
OBMarshalCount(const CORBA_SystemException& val, CORBA_ULong& count)
{
    OBMarshalCount(val._type_id(), count);
    OBMarshalCount(val.minor(), count);
    OBMarshalCount((CORBA_ULong)val.completed(), count);
}

CORBA_SystemException*
OBUnmarshalSystemException(const CORBA_Octet*& oct, bool swap)
{
    CORBA_String_var id;
    CORBA_ULong minor;
    CORBA_CompletionStatus status;

    OBUnmarshal(id.inout(), oct, swap);
    OBUnmarshal(minor, oct, swap);
    CORBA_ULong st;
    OBUnmarshal(st, oct, swap);
    status = (CORBA_CompletionStatus)st;

    if(strcmp(id, "IDL:omg.org/CORBA/BAD_PARAM:1.0") == 0)
    {
	return new CORBA_BAD_PARAM(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/NO_MEMORY:1.0") == 0)
    {
	return new CORBA_NO_MEMORY(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/IMP_LIMIT:1.0") == 0)
    {
	return new CORBA_IMP_LIMIT(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/COMM_FAILURE:1.0") == 0)
    {
	return new CORBA_COMM_FAILURE(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INV_OBJREF:1.0") == 0)
    {
	return new CORBA_INV_OBJREF(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/NO_PERMISSION:1.0") == 0)
    {
	return new CORBA_NO_PERMISSION(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INTERNAL:1.0") == 0)
    {
	return new CORBA_INTERNAL(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/MARSHAL:1.0") == 0)
    {
	return new CORBA_MARSHAL(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INITIALIZE:1.0") == 0)
    {
	return new CORBA_INITIALIZE(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/NO_IMPLEMENT:1.0") == 0)
    {
	return new CORBA_NO_IMPLEMENT(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/BAD_TYPECODE:1.0") == 0)
    {
	return new CORBA_BAD_TYPECODE(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/BAD_OPERATION:1.0") == 0)
    {
	return new CORBA_BAD_OPERATION(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/NO_RESOURCES:1.0") == 0)
    {
	return new CORBA_NO_RESOURCES(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/NO_RESPONSE:1.0") == 0)
    {
	return new CORBA_NO_RESPONSE(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/PERSIST_STORE:1.0") == 0)
    {
	return new CORBA_PERSIST_STORE(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/BAD_INV_ORDER:1.0") == 0)
    {
	return new CORBA_BAD_INV_ORDER(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/TRANSIENT:1.0") == 0)
    {
	return new CORBA_TRANSIENT(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/FREE_MEM:1.0") == 0)
    {
	return new CORBA_FREE_MEM(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INV_IDENT:1.0") == 0)
    {
	return new CORBA_INV_IDENT(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INV_FLAG:1.0") == 0)
    {
	return new CORBA_INV_FLAG(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INTF_REPOS:1.0") == 0)
    {
	return new CORBA_INTF_REPOS(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/BAD_CONTEXT:1.0") == 0)
    {
	return new CORBA_BAD_CONTEXT(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/OBJ_ADAPTER:1.0") == 0)
    {
	return new CORBA_OBJ_ADAPTER(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/DATA_CONVERSION:1.0") == 0)
    {
	return new CORBA_DATA_CONVERSION(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0") == 0)
    {
	return new CORBA_OBJECT_NOT_EXIST(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/TRANSACTION_REQUIRED:1.0") == 0)
    {
	return new CORBA_TRANSACTION_REQUIRED(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/TRANSACTION_ROLLEDBACK:1.0") == 0)
    {
	return new CORBA_TRANSACTION_ROLLEDBACK(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INVALID_TRANSACTION:1.0") == 0)
    {
	return new CORBA_INVALID_TRANSACTION(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INV_POLICY:1.0") == 0)
    {
	return new CORBA_INV_POLICY(minor, status);
    }

    //
    // Unknown exception
    //
    return new CORBA_UNKNOWN(minor, status);
}

void
OBUnmarshalSystemExceptionThrow(const CORBA_Octet*& oct, bool swap)
{
    CORBA_String_var id;
    CORBA_ULong minor;
    CORBA_CompletionStatus status;

    OBUnmarshal(id.inout(), oct, swap);
    OBUnmarshal(minor, oct, swap);
    CORBA_ULong st;
    OBUnmarshal(st, oct, swap);
    status = (CORBA_CompletionStatus)st;

    //
    // XXX - candidate for optimization. Use lookup table, or
    // something similar.
    //
    if(strcmp(id, "IDL:omg.org/CORBA/BAD_PARAM:1.0") == 0)
    {
	throw CORBA_BAD_PARAM(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/NO_MEMORY:1.0") == 0)
    {
	throw CORBA_NO_MEMORY(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/IMP_LIMIT:1.0") == 0)
    {
	throw CORBA_IMP_LIMIT(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/COMM_FAILURE:1.0") == 0)
    {
	throw CORBA_COMM_FAILURE(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INV_OBJREF:1.0") == 0)
    {
	throw CORBA_INV_OBJREF(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/NO_PERMISSION:1.0") == 0)
    {
	throw CORBA_NO_PERMISSION(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INTERNAL:1.0") == 0)
    {
	throw CORBA_INTERNAL(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/MARSHAL:1.0") == 0)
    {
	throw CORBA_MARSHAL(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INITIALIZE:1.0") == 0)
    {
	throw CORBA_INITIALIZE(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/NO_IMPLEMENT:1.0") == 0)
    {
	throw CORBA_NO_IMPLEMENT(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/BAD_TYPECODE:1.0") == 0)
    {
	throw CORBA_BAD_TYPECODE(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/BAD_OPERATION:1.0") == 0)
    {
	throw CORBA_BAD_OPERATION(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/NO_RESOURCES:1.0") == 0)
    {
	throw CORBA_NO_RESOURCES(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/NO_RESPONSE:1.0") == 0)
    {
	throw CORBA_NO_RESPONSE(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/PERSIST_STORE:1.0") == 0)
    {
	throw CORBA_PERSIST_STORE(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/BAD_INV_ORDER:1.0") == 0)
    {
	throw CORBA_BAD_INV_ORDER(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/TRANSIENT:1.0") == 0)
    {
	throw CORBA_TRANSIENT(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/FREE_MEM:1.0") == 0)
    {
	throw CORBA_FREE_MEM(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INV_IDENT:1.0") == 0)
    {
	throw CORBA_INV_IDENT(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INV_FLAG:1.0") == 0)
    {
	throw CORBA_INV_FLAG(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INTF_REPOS:1.0") == 0)
    {
	throw CORBA_INTF_REPOS(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/BAD_CONTEXT:1.0") == 0)
    {
	throw CORBA_BAD_CONTEXT(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/OBJ_ADAPTER:1.0") == 0)
    {
	throw CORBA_OBJ_ADAPTER(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/DATA_CONVERSION:1.0") == 0)
    {
	throw CORBA_DATA_CONVERSION(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0") == 0)
    {
	throw CORBA_OBJECT_NOT_EXIST(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/TRANSACTION_REQUIRED:1.0") == 0)
    {
	throw CORBA_TRANSACTION_REQUIRED(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/TRANSACTION_ROLLEDBACK:1.0") == 0)
    {
	throw CORBA_TRANSACTION_ROLLEDBACK(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INVALID_TRANSACTION:1.0") == 0)
    {
	throw CORBA_INVALID_TRANSACTION(minor, status);
    }
    else if(strcmp(id, "IDL:omg.org/CORBA/INV_POLICY:1.0") == 0)
    {
	throw CORBA_INV_POLICY(minor, status);
    }

    //
    // Unknown exception
    //
    throw CORBA_UNKNOWN(minor, status);
}
