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

//
// Author: Philippe Merle
//
// From the Laboratoire d'Informatique Fondamentale de Lille in France
// (it is a computer science laboratory of the Lille french university)
//

#include <OB/Basic.h>
#include <OB/Except.h>
#include <OB/Template.h>
#include <OB/Declarations.h>
#include <OB/Any.h>
#include <OB/TCKind.h>
#include <OB/TypeCode.h>
#include <OB/IOP.h>
#include <OB/Object.h>
#include <OB/IntRepMember.h>
#include <OB/ORB.h>
#include <OB/DynAny.h>

#include <DynAny_impl.h>

// ----------------------------------------------------------------------
// Macro to read an Any containing an enum value
// ----------------------------------------------------------------------

#define READ_ENUM_VALUE(ANY) (* ( (CORBA_ULong*) (ANY).value () ) )

// ----------------------------------------------------------------------
// Narrow CORBA_DynAny to implementation classes
// ----------------------------------------------------------------------

OB_MAKE_NARROW_IMPL_1 (CORBA_DynAny_impl,      CORBA_DynAny)

OB_MAKE_NARROW_IMPL_1 (CORBA_DynBasic_impl,    CORBA_DynAny_impl)

OB_MAKE_NARROW_IMPL_2 (CORBA_DynEnum_impl,     CORBA_DynEnum,
                                               CORBA_DynAny_impl)

OB_MAKE_NARROW_IMPL_1 (CORBA_DynComplex_impl,  CORBA_DynAny_impl)

OB_MAKE_NARROW_IMPL_2 (CORBA_DynStruct_impl,   CORBA_DynStruct,
                                               CORBA_DynComplex_impl)

OB_MAKE_NARROW_IMPL_1 (CORBA_DynException_impl,CORBA_DynStruct_impl)

OB_MAKE_NARROW_IMPL_2 (CORBA_DynUnion_impl,    CORBA_DynUnion,
                                               CORBA_DynComplex_impl)

OB_MAKE_NARROW_IMPL_2 (CORBA_DynSequence_impl, CORBA_DynSequence,
                                               CORBA_DynComplex_impl)

OB_MAKE_NARROW_IMPL_2 (CORBA_DynArray_impl,    CORBA_DynArray,
                                               CORBA_DynComplex_impl)

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
//
// CORBA_DynAny_impl class
//
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
// CORBA_DynAny_impl constructor and destructor
// ----------------------------------------------------------------------

CORBA_DynAny_impl::CORBA_DynAny_impl (CORBA_TypeCode_ptr type)
    : type_(CORBA_TypeCode::_duplicate(type))
{
}

CORBA_DynAny_impl::~CORBA_DynAny_impl()
{
}

// ----------------------------------------------------------------------
// operation to create a CORBA_DynAny_impl from a TypeCode
// ----------------------------------------------------------------------

CORBA_DynAny_impl*
CORBA_DynAny_impl::create (CORBA_TypeCode_ptr typecode)
{
    CORBA_TypeCode_var tc = OBGetOrigType(typecode);

    switch(tc -> kind())
    {
    case CORBA_tk_null:
    case CORBA_tk_void:
    case CORBA_tk_short:
    case CORBA_tk_long:
    case CORBA_tk_ushort:
    case CORBA_tk_ulong:
    case CORBA_tk_float:
    case CORBA_tk_double:
    case CORBA_tk_boolean:
    case CORBA_tk_char:
    case CORBA_tk_octet:
    case CORBA_tk_any:
    case CORBA_tk_TypeCode:
    case CORBA_tk_Principal:
    case CORBA_tk_objref:
    case CORBA_tk_string:
	return new CORBA_DynBasic_impl(typecode);

    case CORBA_tk_struct:
	return new CORBA_DynStruct_impl(typecode);

    case CORBA_tk_except:
	return new CORBA_DynException_impl(typecode);

    case CORBA_tk_union:
	return new CORBA_DynUnion_impl(typecode);

    case CORBA_tk_enum:
	return new CORBA_DynEnum_impl(typecode);

    case CORBA_tk_sequence:
	return new CORBA_DynSequence_impl(typecode);

    case CORBA_tk_array:
	return new CORBA_DynArray_impl(typecode);

    case CORBA_tk_alias:
	assert(false);
	break;
    }

    assert(false);
    return 0;
}

// ----------------------------------------------------------------------
// CORBA_DynAny_impl public IDL member implementation
// from CORBA_DynAny interface
// ----------------------------------------------------------------------

CORBA_TypeCode_ptr
CORBA_DynAny_impl::type()
{
    return CORBA_TypeCode::_duplicate(type_);
}

// ----------------------------------------------------------------------

#define CONTROL_INSERT(ANY,TC)                        \
    if ( ANY == 0 )                                   \
        throw InvalidValue ();                        \
    CORBA_TypeCode_var type = ANY->type();            \
    if ( ! type->equal(TC) )                     \
        throw InvalidValue ();

void
CORBA_DynAny_impl::insert_boolean(CORBA_Boolean value)
{
    CORBA_Any* any = current_any ();

    CONTROL_INSERT (any,CORBA__tc_boolean);

    // this allows to reuse the current TypeCode of the any.
    any->replace (type, new CORBA_Boolean(value), CORBA_TRUE);

    next ();
}

void
CORBA_DynAny_impl::insert_octet(CORBA_Octet value)
{
    CORBA_Any* any = current_any ();

    CONTROL_INSERT (any,CORBA__tc_octet);

    // this allows to reuse the current TypeCode of the any.
    any->replace (type, new CORBA_Octet(value), CORBA_TRUE);

    next ();
}

void
CORBA_DynAny_impl::insert_char(CORBA_Char value)
{
    CORBA_Any* any = current_any ();

    CONTROL_INSERT (any,CORBA__tc_char);

    // this allows to reuse the current TypeCode of the any.
    any->replace (type, new CORBA_Char(value), CORBA_TRUE);

    next ();
}

void
CORBA_DynAny_impl::insert_short(CORBA_Short value)
{
    CORBA_Any* any = current_any ();

    CONTROL_INSERT (any,CORBA__tc_short);

    // this allows to reuse the current TypeCode of the any.
    any->replace (type, new CORBA_Short(value), CORBA_TRUE);

    next ();
}

void
CORBA_DynAny_impl::insert_ushort(CORBA_UShort value)
{
    CORBA_Any* any = current_any ();

    CONTROL_INSERT (any,CORBA__tc_ushort);

    // this allows to reuse the current TypeCode of the any.
    any->replace (type, new CORBA_UShort(value), CORBA_TRUE);

    next ();
}

void
CORBA_DynAny_impl::insert_long(CORBA_Long value)
{
    CORBA_Any* any = current_any ();

    CONTROL_INSERT (any,CORBA__tc_long);

    // this allows to reuse the current TypeCode of the any.
    any->replace (type, new CORBA_Long(value), CORBA_TRUE);

    next ();
}

void
CORBA_DynAny_impl::insert_ulong(CORBA_ULong value)
{
    CORBA_Any* any = current_any ();

    CONTROL_INSERT (any,CORBA__tc_ulong);

    // this allows to reuse the current TypeCode of the any.
    any->replace (type, new CORBA_ULong(value), CORBA_TRUE);

    next ();
}

void
CORBA_DynAny_impl::insert_float(CORBA_Float value)
{
    CORBA_Any* any = current_any ();

    CONTROL_INSERT (any,CORBA__tc_float);

    // this allows to reuse the current TypeCode of the any.
    any->replace (type, new CORBA_Float(value), CORBA_TRUE);

    next ();
}

void
CORBA_DynAny_impl::insert_double(CORBA_Double value)
{
    CORBA_Any* any = current_any ();

    CONTROL_INSERT (any,CORBA__tc_double);

    // this allows to reuse the current TypeCode of the any.
    any->replace (type, new CORBA_Double(value), CORBA_TRUE);

    next ();
}

void
CORBA_DynAny_impl::insert_string(const char* value)
{
    CORBA_Any* any = current_any ();

    // Can't use CONTROL_INSERT, as it then wouldn't be possible to
    // insert bounded strings.
    //CONTROL_INSERT (any,CORBA__tc_string);
    if(any == 0)
        throw InvalidValue ();
    CORBA_TypeCode_var type = any -> type();
    CORBA_TypeCode_var origType = OBGetOrigType(type);
    if(origType -> kind() != CORBA_tk_string)
        throw InvalidValue ();

    // this allows to reuse the current TypeCode of the any.
    any->replace (type, CORBA_string_dup(value), CORBA_TRUE);

    next ();
}

void
CORBA_DynAny_impl::insert_reference(CORBA_Object_ptr value)
{
    CORBA_Any* any = current_any ();

    if ( any == 0 )
        throw InvalidValue ();

    CORBA_TypeCode_var type = any->type();

    CORBA_TypeCode_var tc = OBGetOrigType(type);

    if ( tc->kind() != CORBA_tk_objref )
        throw InvalidValue ();

    //
    // Note of Philippe Merle
    //
    // I don't want to this test because it could send an IIOP request.
    // I think the DynAny API must only execute local tasks.
    // This test must be done in applications which use the DynAny API.
    // For instance, in CorbaScript, this test is done by the interpreter.
    //
    // Moreover, OMG don't currently define the semantic of the operation.
    // Then, I think we don't add any network overheads.
    //
    //  if ( !value -> _is_a(tc->id()) )
    //        throw InvalidValue ();
    //

    OBObjAny* objAny = new OBObjAny;
    objAny -> b = CORBA_Object::_duplicate(value);
    objAny -> d = CORBA_Object::_duplicate(value);

    any->replace (type, objAny, CORBA_TRUE);

    next ();
}

void
CORBA_DynAny_impl::insert_typecode(CORBA_TypeCode_ptr value)
{
    CORBA_Any* any = current_any ();

    CONTROL_INSERT (any,CORBA__tc_TypeCode);

    // this allows to reuse the current TypeCode of the any.
    any->replace (type, CORBA_TypeCode::_duplicate(value), CORBA_TRUE);

    next ();
}

void
CORBA_DynAny_impl::insert_any(const CORBA_Any& value)
{
    CORBA_Any* any = current_any ();

    CONTROL_INSERT (any,CORBA__tc_any);

    // this allows to reuse the current TypeCode of the any.
    any->replace (type, new CORBA_Any(value), CORBA_TRUE);

    next ();
}

// ----------------------------------------------------------------------

#define GET_CHECK_ANY(ANY) ( ( ANY != 0 ) && ( ANY->value() != 0 ) )

CORBA_Boolean
CORBA_DynAny_impl::get_boolean()
{
    CORBA_Any* any = current_any ();

    CORBA_Boolean result;
    CORBA_Any::to_boolean val (result);

    if ( ! GET_CHECK_ANY(any) || ! ( *any >>= val ) )
        throw TypeMismatch ();
 
    return result;
}

CORBA_Octet
CORBA_DynAny_impl::get_octet()
{
    CORBA_Any* any = current_any ();

    CORBA_Octet result;
    CORBA_Any::to_octet val (result);

    if ( ! GET_CHECK_ANY(any) || ! ( *any >>= val ) )
        throw TypeMismatch ();
 
    return result;
}

CORBA_Char
CORBA_DynAny_impl::get_char()
{
    CORBA_Any* any = current_any ();

    CORBA_Char result;
    CORBA_Any::to_char val (result);

    if ( ! GET_CHECK_ANY (any) || ! ( *any >>= val ) )
        throw TypeMismatch ();
 
    return result;
}

CORBA_Short
CORBA_DynAny_impl::get_short()
{
    CORBA_Any* any = current_any ();

    CORBA_Short result;

    if ( ! GET_CHECK_ANY(any) || ! ( *any >>= result ) )
        throw TypeMismatch ();
 
    return result;
}

CORBA_UShort
CORBA_DynAny_impl::get_ushort()
{
    CORBA_Any* any = current_any ();

    CORBA_UShort result;

    if ( ! GET_CHECK_ANY(any) || ! ( *any >>= result ) )
        throw TypeMismatch ();
 
    return result;
}

CORBA_Long
CORBA_DynAny_impl::get_long()
{
    CORBA_Any* any = current_any ();

    CORBA_Long result;

    if ( ! GET_CHECK_ANY (any) || ! ( *any >>= result ) )
        throw TypeMismatch ();
 
    return result;
}

CORBA_ULong
CORBA_DynAny_impl::get_ulong()
{
    CORBA_Any* any = current_any ();

    CORBA_ULong result;

    if ( ! GET_CHECK_ANY(any) || ! ( *any >>= result ) )
        throw TypeMismatch ();
 
    return result;
}

CORBA_Float
CORBA_DynAny_impl::get_float()
{
    CORBA_Any* any = current_any ();

    CORBA_Float result;

    if ( ! GET_CHECK_ANY(any) || ! ( *any >>= result ) )
        throw TypeMismatch ();
 
    return result;
}

CORBA_Double
CORBA_DynAny_impl::get_double()
{
    CORBA_Any* any = current_any ();

    CORBA_Double result;

    if ( ! GET_CHECK_ANY(any) || ! ( *any >>= result ) )
        throw TypeMismatch ();
 
    return result;
}

char*
CORBA_DynAny_impl::get_string()
{
    CORBA_Any* any = current_any ();

    if ( ! GET_CHECK_ANY(any) )
        throw TypeMismatch ();

    CORBA_TypeCode_var type = any->type();

    CORBA_TypeCode_var tc = OBGetOrigType (type);

    if(tc -> kind() != CORBA_tk_string )
        throw TypeMismatch ();

    char* result = (char*)any->value();

    return CORBA_string_dup(result);
}

CORBA_Object_ptr
CORBA_DynAny_impl::get_reference()
{
    CORBA_Any* any = current_any ();

    CORBA_Object_ptr result;
    CORBA_Any::to_object v(result);

    if (any == 0 || ! ( *any >>= v ) )
        throw TypeMismatch ();

    return CORBA_Object::_duplicate(result);
}

CORBA_TypeCode_ptr
CORBA_DynAny_impl::get_typecode()
{
    CORBA_Any* any = current_any ();

    CORBA_TypeCode_ptr result;

    if ( ! GET_CHECK_ANY(any) || ! ( *any >>= result ) )
        throw TypeMismatch ();
 
    return CORBA_TypeCode::_duplicate(result);
}

CORBA_Any*
CORBA_DynAny_impl::get_any()
{
    CORBA_Any* any = current_any ();

    CORBA_Any* result;

    if ( ! GET_CHECK_ANY(any) || ! ( *any >>= result ) )
        throw TypeMismatch ();
 
    return new CORBA_Any(*result);
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
//
// CORBA_DynBasic_impl implementation
//
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
// CORBA_DynBasic_impl constructor and destructor
// ----------------------------------------------------------------------

CORBA_DynBasic_impl::CORBA_DynBasic_impl(CORBA_TypeCode_ptr type)
    : CORBA_DynAny_impl(type)
    , any_ (new CORBA_Any (type, 0, CORBA_FALSE))
{
}

CORBA_DynBasic_impl::~CORBA_DynBasic_impl()
{
}

// ----------------------------------------------------------------------
// CORBA_DynBasic_impl operations to access components
// ----------------------------------------------------------------------

CORBA_Any*
CORBA_DynBasic_impl::current_any ()
{
    return any_;
}

CORBA_Any*
CORBA_DynBasic_impl::current_any_value ()
{
    return any_;
}

// ----------------------------------------------------------------------
// CORBA_DynBasic_impl operations
// to marshal and unmarshal components into a complex any value
// ----------------------------------------------------------------------

void
CORBA_DynBasic_impl::MarshalCount(CORBA_ULong& count)
{
    // Use specific OB function
    OBMarshalCountNoTypeCode(any_, count);
}

void
CORBA_DynBasic_impl::Marshal (CORBA_Octet*& oct)
{
    // Use specific OB function
    OBMarshalNoTypeCode(any_,oct);
}

void
CORBA_DynBasic_impl::Unmarshal (const CORBA_Octet*& coct)
{
    // Use specific OB function
    OBUnmarshalNoTypeCode(any_.inout(), coct, CORBA_FALSE, type_);
}

// ----------------------------------------------------------------------
// CORBA_DynBasic_impl public IDL member implementation
// from CORBA_DynAny interface
// ----------------------------------------------------------------------

void
CORBA_DynBasic_impl::assign(CORBA_DynAny_ptr dyn_any)
{
   CORBA_TypeCode_var tc = dyn_any->type();

    if ( ! tc->equal(type_) )
        throw Invalid ();

    any_ = dyn_any->to_any ();
}

void
CORBA_DynBasic_impl::from_any(const CORBA_Any& value)
{
    CORBA_TypeCode_var tc = value.type();

    if ( ! tc->equal(type_) )
        throw Invalid ();
    
    any_ = new CORBA_Any (value);
    any_ -> type(type_);
}

CORBA_Any*
CORBA_DynBasic_impl::to_any()
{
    return new CORBA_Any(any_);
}

void
CORBA_DynBasic_impl::destroy()
{
  // nothing to do
}

CORBA_DynAny_ptr
CORBA_DynBasic_impl::copy()
{
    CORBA_TypeCode_var tc = any_->type();

    CORBA_DynAny_ptr result = new CORBA_DynBasic_impl (tc);
    result->from_any(any_);
    return result;
}

CORBA_DynAny_ptr
CORBA_DynBasic_impl::current_component()
{
    return CORBA_DynAny::_duplicate(this);
}

CORBA_Boolean
CORBA_DynBasic_impl::next()
{
    return CORBA_FALSE;
}

CORBA_Boolean
CORBA_DynBasic_impl::seek(CORBA_Long index)
{
    if ( index == 0 )
        return CORBA_TRUE;
    return CORBA_FALSE;
}

void
CORBA_DynBasic_impl::rewind()
{
    // nothing to do
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
//
// CORBA_DynEnum_impl implementation
//
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
// CORBA_DynEnum_impl constructor and destructor
// ----------------------------------------------------------------------

CORBA_DynEnum_impl::CORBA_DynEnum_impl(CORBA_TypeCode_ptr type,
                                       CORBA_ULong value)
    : CORBA_DynAny_impl(type)
    , value_ (value)
{
}

CORBA_DynEnum_impl::~CORBA_DynEnum_impl()
{
}

// ----------------------------------------------------------------------
// CORBA_DynEnum_impl  operations to access components
// ----------------------------------------------------------------------

CORBA_Any*
CORBA_DynEnum_impl::current_any ()
{
    return 0;
}

CORBA_Any*
CORBA_DynEnum_impl::current_any_value ()
{
    return 0;
}

// ----------------------------------------------------------------------
// CORBA_DynEnum_impl operations
// to marshal and unmarshal components into a complex any value
// ----------------------------------------------------------------------

void
CORBA_DynEnum_impl::MarshalCount(CORBA_ULong& count)
{
    // Use specific OB function
    OBMarshalCount (value_, count);
}

void
CORBA_DynEnum_impl::Marshal (CORBA_Octet*& oct)
{
    // Use specific OB function
    OBMarshal (value_,oct);
}

void
CORBA_DynEnum_impl::Unmarshal (const CORBA_Octet*& coct)
{
    // Use specific OB function
    OBUnmarshal (value_, coct, CORBA_FALSE);
}

// ----------------------------------------------------------------------
// CORBA_DynEnum_impl public IDL member implementation
// from CORBA_DynAny interface
// ----------------------------------------------------------------------

void
CORBA_DynEnum_impl::assign(CORBA_DynAny_ptr dyn_any)
{
    CORBA_DynEnum_var dyn_enum = CORBA_DynEnum::_narrow (dyn_any);
    if ( CORBA_is_nil(dyn_enum) )
        throw Invalid ();

    CORBA_TypeCode_var dyn_enum_type = dyn_enum->type();
    if ( ! dyn_enum_type->equal(type_) )
        throw Invalid ();

    value_ = dyn_enum->value_as_ulong ();
}

void
CORBA_DynEnum_impl::from_any(const CORBA_Any& value)
{
    CORBA_TypeCode_var tc = value.type();

    if ( ! tc->equal(type_) )
        throw Invalid ();

    if ( value.value () == 0 )
        throw Invalid ();

    value_ = READ_ENUM_VALUE (value);
}

CORBA_Any*
CORBA_DynEnum_impl::to_any()
{
    return new CORBA_Any (type_, new CORBA_ULong(value_), CORBA_TRUE);
}

void
CORBA_DynEnum_impl::destroy()
{
    // nothing to do
}

CORBA_DynAny_ptr
CORBA_DynEnum_impl::copy()
{
    return new CORBA_DynEnum_impl (type_, value_);
}

CORBA_DynAny_ptr
CORBA_DynEnum_impl::current_component()
{
    return CORBA_DynAny::_duplicate(this);
}

CORBA_Boolean
CORBA_DynEnum_impl::next()
{
    return CORBA_FALSE;
}

CORBA_Boolean
CORBA_DynEnum_impl::seek(CORBA_Long index)
{
    if ( index == 0 )
        return CORBA_TRUE;
    return CORBA_FALSE;
}

void
CORBA_DynEnum_impl::rewind()
{
    // nothing to do
}

// ----------------------------------------------------------------------
// CORBA_DynEnum_impl public IDL member implementation
// from CORBA_DynEnum interface
// ----------------------------------------------------------------------

char*
CORBA_DynEnum_impl::value_as_string()
{
    CORBA_TypeCode_var tc = OBGetOrigType(type_);

    return CORBA_string_dup ( tc->member_name (value_) );
}

void
CORBA_DynEnum_impl::value_as_string(const char* name)
{
    CORBA_TypeCode_var tc = OBGetOrigType(type_);

    CORBA_ULong i=0;
    CORBA_ULong mi = tc->member_count ();

    for (i=0; i<mi; i++)
        if ( strcmp(tc->member_name(i), name) == 0 ) {
            value_ = i;
            break;
        }

    if ( i == mi )
     ; // throw exception ??? this is not specified into the CORBA spec
   
}

CORBA_ULong
CORBA_DynEnum_impl::value_as_ulong()
{
    return value_;
}

void
CORBA_DynEnum_impl::value_as_ulong(CORBA_ULong value)
{
    CORBA_TypeCode_var tc = OBGetOrigType(type_);

    if ( value < tc->member_count () )
        value_ = value;
    else
       ; // throw exception ??? this is not specified into the CORBA spec
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
//
// CORBA_DynComplex_impl implementation
//
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
// CORBA_DynComplex_impl constructor and destructor
// ----------------------------------------------------------------------

CORBA_DynComplex_impl::CORBA_DynComplex_impl(CORBA_TypeCode_ptr type)
    : CORBA_DynAny_impl(type)
    , components_ ()
    , index_ (0)
{
}

CORBA_DynComplex_impl::~CORBA_DynComplex_impl()
{
}

// ----------------------------------------------------------------------
// CORBA_DynComplex_impl operation to init components
// ----------------------------------------------------------------------

void
CORBA_DynComplex_impl::init_components (CORBA_ULong count)
{
    components_.length (count);
}

// ----------------------------------------------------------------------
// CORBA_DynComplex_impl operations to access components
// ----------------------------------------------------------------------

CORBA_Any*
CORBA_DynComplex_impl::current_any ()
{
    if ( ( index_ < components_.length() )
      && !CORBA_is_nil(components_[index_]) )
        return CORBA_DynAny_impl::_narrow_impl (components_[index_])
                                     -> current_any_value();
    return 0;
}

CORBA_Any*
CORBA_DynComplex_impl::current_any_value ()
{
    return 0;
}

// ----------------------------------------------------------------------
// CORBA_DynComplex_impl operations
// to marshal and unmarshal components into a complex any value
// ----------------------------------------------------------------------

void
CORBA_DynComplex_impl::MarshalCount(CORBA_ULong& count)
{
    for (CORBA_ULong i=0; i<components_.length(); i++) {
        if ( CORBA_is_nil(components_[i]) )
            throw Invalid();

        CORBA_DynAny_impl::_narrow_impl (components_[i])
                                                  -> MarshalCount (count);
    }
}

void
CORBA_DynComplex_impl::Marshal (CORBA_Octet*& oct)
{
    for (CORBA_ULong i=0; i<components_.length(); i++) {
        if ( CORBA_is_nil(components_[i]) )
            throw Invalid();

        CORBA_DynAny_impl::_narrow_impl (components_[i])
                                                        -> Marshal (oct);
    }
}

void
CORBA_DynComplex_impl::Unmarshal (const CORBA_Octet*& coct)
{
    for (CORBA_ULong i=0; i<components_.length(); i++) {
        if ( CORBA_is_nil(components_[i]) )
            throw Invalid();

        CORBA_DynAny_impl::_narrow_impl (components_[i])
                                                     -> Unmarshal (coct);
    }
}

// ----------------------------------------------------------------------
// CORBA_DynComplex_impl public IDL member implementation
// from CORBA_DynAny interface
// ----------------------------------------------------------------------

void
CORBA_DynComplex_impl::from_any(const CORBA_Any& value)
{
    CORBA_TypeCode_var tc = value.type();

    if ( ! tc->equal(type_) )
        throw Invalid ();

    const OBConstructedInfo* info = value.info();

    if ( !info ) {

	const OBBuffer* bufp = (const OBBuffer*)value.value();
	const CORBA_Octet* coct = bufp -> data;
	
	Unmarshal(coct);

    } else {

       CORBA_ULong count = 0;

       info -> marshalCount (value.value(),count);

       CORBA_Octet* buffer = new CORBA_Octet[count];
#ifdef OB_CLEAR_MEM
       memset(buffer, 0, count);
#endif

       CORBA_Octet* oct = buffer;

       info->marshal (value.value(),oct);

       const CORBA_Octet* coct = buffer;

       Unmarshal(coct);

       delete [] buffer;

    } 

}

CORBA_Any*
CORBA_DynComplex_impl::to_any()
{
    CORBA_ULong count = 0;
    MarshalCount(count);

    OBBuffer* bufp = new OBBuffer(count);
    CORBA_Octet* oct = bufp -> data;
    try
    {
	OB_DEC_TRY_FIX
        Marshal(oct);
    }
    catch (Invalid& ex)
    {
        delete [] bufp;
        throw ex;
    }

    return new CORBA_Any(type_, bufp, CORBA_TRUE);
}

void
CORBA_DynComplex_impl::assign(CORBA_DynAny_ptr dyn_any)
{
    CORBA_TypeCode_var tc = dyn_any->type();

    if ( ! tc->equal(type_) )
        throw Invalid ();

    CORBA_DynComplex_impl* dyn_complex =
                 CORBA_DynComplex_impl::_narrow_impl(dyn_any);

    if ( CORBA_is_nil(dyn_complex) )
        throw Invalid ();

    for (CORBA_ULong i=0; i<components_.length(); i++) {
        CORBA_DynAny_ptr component = dyn_complex->components_[i];
        if ( CORBA_is_nil(component) )
            components_[i] = CORBA_DynAny::_nil();
        else
            components_[i] = component -> copy ();
    }
}
  
void
CORBA_DynComplex_impl::destroy()
{
    // TO WRITE but currently, I don't know what to do, perhaps nothing :-)
}

CORBA_DynAny_ptr
CORBA_DynComplex_impl::current_component()
{
    if ( index_ < components_.length() ) {
        return CORBA_DynAny::_duplicate(components_[index_]);
	}

   return CORBA_DynAny::_nil();
}

CORBA_Boolean
CORBA_DynComplex_impl::next()
{
    index_ ++;
    if ( index_ < components_.length() )
        return CORBA_TRUE;
    return CORBA_FALSE;
}

CORBA_Boolean
CORBA_DynComplex_impl::seek(CORBA_Long index)
{
    if ( ( index >= 0 ) && ( index < CORBA_Long(components_.length()) ) ) {
        index_ = index;
        return CORBA_TRUE;
    }
    return CORBA_FALSE;
}

void
CORBA_DynComplex_impl::rewind()
{
    index_ = 0;
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
//
// CORBA_DynStruct_impl implementation
//
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
// CORBA_DynStruct_impl constructor and destructor
// ----------------------------------------------------------------------

CORBA_DynStruct_impl::CORBA_DynStruct_impl(CORBA_TypeCode_ptr type,
                                           CORBA_Boolean init)
    : CORBA_DynComplex_impl(type)
    , CORBA_DynAny_impl (type)
{
    CORBA_TypeCode_var tc = OBGetOrigType(type);

    CORBA_ULong member_count = tc->member_count();
    CORBA_DynComplex_impl::init_components(member_count);

    if ( init )
       for (CORBA_ULong i=0; i<member_count; i++)
       {
           CORBA_TypeCode_var member_type = tc -> member_type(i);
           components_[i] = CORBA_DynAny_impl::create (member_type);
       }
}

CORBA_DynStruct_impl::~CORBA_DynStruct_impl()
{
}

// ----------------------------------------------------------------------
// CORBA_DynStruct_impl public IDL member implementation
// from CORBA_DynAny interface
// ----------------------------------------------------------------------

CORBA_DynAny_ptr
CORBA_DynStruct_impl::copy()
{
    CORBA_DynStruct_impl* result =
                      new CORBA_DynStruct_impl (type_, CORBA_FALSE);

    for (CORBA_ULong i=0; i<components_.length(); i++) {
        result->components_[i] = components_[i] -> copy ();
    }

    return result;
}

// ----------------------------------------------------------------------
// CORBA_DynStruct_impl public IDL member implementation
// from CORBA_DynStruct interface
// ----------------------------------------------------------------------

CORBA_FieldName
CORBA_DynStruct_impl::current_member_name()
{
    CORBA_TypeCode_var tc = OBGetOrigType(type_);

    return CORBA_string_dup ( tc->member_name(index_) );
}

CORBA_TCKind
CORBA_DynStruct_impl::current_member_kind()
{
    CORBA_TypeCode_var tc = OBGetOrigType(type_);

    CORBA_TypeCode_var member_type = tc->member_type (index_);
    return member_type -> kind ();
}

CORBA_NameValuePairSeq*
CORBA_DynStruct_impl::get_members()
{
    CORBA_TypeCode_var tc = OBGetOrigType(type_);

    CORBA_NameValuePairSeq* result = new CORBA_NameValuePairSeq;
    result->length (components_.length());

    for (CORBA_ULong i=0; i<components_.length(); i++) {
        (*result)[i].id = CORBA_string_dup (tc->member_name (i));
        CORBA_Any_var any = components_[i]->to_any ();
        (*result)[i].value = any;
    }
   
    return result;
}

void
CORBA_DynStruct_impl::set_members(const CORBA_NameValuePairSeq& value)
{
    if ( value.length() != components_.length() )
	throw InvalidSeq ();
    
    CORBA_TypeCode_var tc = OBGetOrigType(type_);

    CORBA_ULong i;
    
    for (i=0; i<components_.length(); i++) {
	if ( strcmp (value[i].id, tc->member_name(i)) != 0 )
	    throw InvalidSeq ();
	
	CORBA_TypeCode_var value_type = value[i].value.type();
	CORBA_TypeCode_var member_type = tc->member_type(i);
	if ( ! value_type->equal(member_type) )
	    throw InvalidSeq ();
    }
    
    for (i=0; i<components_.length(); i++) {
	components_[i]->from_any (value[i].value);
    }
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
//
// CORBA_DynException_impl implementation
//
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
// CORBA_DynException_impl constructor and destructor
// ----------------------------------------------------------------------

CORBA_DynException_impl::CORBA_DynException_impl(CORBA_TypeCode_ptr type,
                                                 CORBA_Boolean init)
    : CORBA_DynStruct_impl(type,init)
    , CORBA_DynComplex_impl(type)
    , CORBA_DynAny_impl (type)
    , id_( type->id() )
{
}

CORBA_DynException_impl::~CORBA_DynException_impl()
{
}

// ----------------------------------------------------------------------
// CORBA_DynException_impl operations
// to marshal and unmarshal components into a complex any value
// ----------------------------------------------------------------------

void
CORBA_DynException_impl::MarshalCount(CORBA_ULong& count)
{
    // Use specific OB function
    OBMarshalCount(id_, count);

    CORBA_DynComplex_impl::MarshalCount(count);
}

void
CORBA_DynException_impl::Marshal (CORBA_Octet*& oct)
{
    // Use specific OB function
    OBMarshal(id_, oct);

    CORBA_DynComplex_impl::Marshal (oct);
}

void
CORBA_DynException_impl::Unmarshal (const CORBA_Octet*& coct)
{
    CORBA_String_var id;

    // Use specific OB function
    OBUnmarshal(id.inout(), coct, CORBA_FALSE);

    assert(strcmp(id, id_) == 0);

    CORBA_DynComplex_impl::Unmarshal (coct);
}

// ----------------------------------------------------------------------
// CORBA_DynException_impl public IDL member implementation
// from CORBA_DynAny interface
// ----------------------------------------------------------------------

CORBA_DynAny_ptr
CORBA_DynException_impl::copy()
{
    CORBA_DynException_impl* result =
                      new CORBA_DynException_impl (type_, CORBA_FALSE);

    for (CORBA_ULong i=0; i<components_.length(); i++) {
        result->components_[i] = components_[i] -> copy ();
    }

    return result;
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
//
// CORBA_DynUnion_impl
//
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
// CORBA_DynUnion_impl constructor and destructor
// ----------------------------------------------------------------------

CORBA_DynUnion_impl::CORBA_DynUnion_impl(CORBA_TypeCode_ptr type)
    : CORBA_DynComplex_impl(type)
    , CORBA_DynAny_impl (type)
    , default_index_ (-1)
    , current_discr_index_ (-1)
{
    CORBA_DynComplex_impl::init_components(2);

    CORBA_TypeCode_var tc = OBGetOrigType(type);

    CORBA_ULong count = tc->member_count();

    member_labels_.length(count);
    member_types_.length(count);

    for(CORBA_ULong i=0; i<count; i++) {
        CORBA_Any_var label = tc->member_label(i);
        member_labels_[i] = compute_any(label);
        member_types_[i] = tc->member_type(i);
    }

    CORBA_TypeCode_var discr_type = tc->discriminator_type();

    default_index_ = tc->default_index();

    if ( default_index_ != -1 ) {
        member_labels_[default_index_] = compute_default_value (discr_type);
    }

    components_[0] = CORBA_DynAny_impl::create(discr_type);
    components_[1] = CORBA_DynAny::_nil();
}

CORBA_DynUnion_impl::~CORBA_DynUnion_impl()
{
}

// ----------------------------------------------------------------------
// private operations
// ----------------------------------------------------------------------

void
CORBA_DynUnion_impl::check_discriminator_and_set_member ()
{
    CORBA_Long discr_index = default_index_;

    CORBA_Any_var any_discr = components_[0]->to_any ();

    if ( any_discr->value() != 0 ) {
        CORBA_Long label = compute_any (any_discr);
        for (CORBA_ULong i=0; i<member_labels_.length(); i++) {
            if ( member_labels_[i] == label ) {
                discr_index = i;
                break;
            }
        }
    }

    if ( discr_index != current_discr_index_ ) {
        current_discr_index_ = discr_index;
        if ( discr_index != -1 )
            components_[1] =
                CORBA_DynAny_impl::create (member_types_[discr_index]);
         else
 	    components_[1] = CORBA_DynAny::_nil();
    }
}

void
CORBA_DynUnion_impl::set_dyn_any (CORBA_DynAny_ptr dyn_any,
                                  CORBA_Long value)
{
    CORBA_TypeCode_var type = dyn_any->type();
    CORBA_TypeCode_var tc = OBGetOrigType(type);

    switch (tc->kind())
    {
    case CORBA_tk_short:
        dyn_any->insert_short((CORBA_Short)value);
        break;

    case CORBA_tk_ushort:
        dyn_any->insert_ushort((CORBA_UShort)value);
        break;

    case CORBA_tk_long:
        dyn_any->insert_long((CORBA_Long)value);
        break;

    case CORBA_tk_ulong:
        dyn_any->insert_ulong((CORBA_ULong)value);
        break;

    case CORBA_tk_char:
        dyn_any->insert_char((CORBA_Char)value);
        break;

    case CORBA_tk_boolean:
        dyn_any->insert_boolean((CORBA_Boolean)value);
        break;

    case CORBA_tk_octet:
        dyn_any->insert_octet((CORBA_Octet)value);
        break;
    
    case CORBA_tk_enum: {
        CORBA_DynEnum_var dyn_enum = CORBA_DynEnum::_narrow (dyn_any);
        dyn_enum->value_as_ulong (value);
      } break;

    default:
       assert(false);
       break;
    }
}

CORBA_Long
CORBA_DynUnion_impl::compute_any (CORBA_Any* any)
{
    CORBA_Long result = 0;

    CORBA_TypeCode_var type = any->type();
    CORBA_TypeCode_var tc = OBGetOrigType(type);

    switch (tc->kind())
    {
    case CORBA_tk_short: {
        CORBA_Short v_short;
        *any >>= v_short;
        result = CORBA_Long(v_short);
      } break;

    case CORBA_tk_ushort: {
        CORBA_UShort v_ushort;
        *any >>= v_ushort;
        result = CORBA_Long(v_ushort);
      } break;

    case CORBA_tk_long: {
        CORBA_Long v_long;
        *any >>= v_long;
        result = CORBA_Long(v_long);
      } break;

    case CORBA_tk_ulong: {
        CORBA_ULong v_ulong;
        *any >>= v_ulong;
        result = CORBA_Long(v_ulong);
      } break;

    case CORBA_tk_char: {
        CORBA_Char v_char;
        CORBA_Any::to_char to_char (v_char);
        *any >>= to_char;
        result = CORBA_Long(v_char);
      } break;

    case CORBA_tk_boolean: {
        CORBA_Boolean v_boolean;
        CORBA_Any::to_boolean to_boolean (v_boolean);
        *any >>= to_boolean;
        result = CORBA_Long(v_boolean);
      } break;

    case CORBA_tk_octet: {
        CORBA_Octet v_octet;
        CORBA_Any::to_octet to_octet (v_octet);
        *any >>= to_octet;
        result = CORBA_Long(v_octet);
      } break;
    
    case CORBA_tk_enum: {
        CORBA_ULong v_enum = READ_ENUM_VALUE (*any);
        result = CORBA_Long(v_enum);
      } break;

    default:
       assert(false);
       break;
    }
    return result;
}

//
// WARNING
//
// This is a simplified version
// It doesn't work for big CORBA_ULong discriminator (>2147483647)
//

CORBA_Long
CORBA_DynUnion_impl::compute_default_value (CORBA_TypeCode_ptr discr_type)
{
    CORBA_Long result = 0;
    CORBA_Long min, max;
 
    CORBA_TypeCode_var tc = OBGetOrigType(discr_type);
   
    switch(tc -> kind())
    {
    case CORBA_tk_short:
	min = -32768;
	max = 32767;
	break;
	
    case CORBA_tk_ushort:
	min = 0;
	max = 65535;
	break;
	
    case CORBA_tk_long:
	min = -2147483647 - 1;
	max = 2147483647;
	break;
	
    case CORBA_tk_ulong:
	min = 0;
	max = 2147483647;
//	max = 4294967294U;
	break;
	
    case CORBA_tk_enum:
	min = 0;
	max = tc -> member_count() - 1;
	break;
	
    case CORBA_tk_char:
	min = 0;
	max = 255;
	break;
	
    case CORBA_tk_boolean:
	min = 0;
	max = 1;
	break;
	
    default:
	assert(false);
	break;
    }

    for(CORBA_Long i = max ; i >= min ; i--) {
	bool ok = true;
	
	for(CORBA_ULong j = 0 ; ok && j < member_labels_.length() ; j++)
	    if(member_labels_[j] == i)
		    ok = false;
	
	if(ok) {
	    result = i;
	    break;
	}
    }
    return result;
}

// ----------------------------------------------------------------------
// CORBA_DynUnion_impl operations
// to marshal and unmarshal components into a complex any value
// ----------------------------------------------------------------------

void
CORBA_DynUnion_impl::Unmarshal (const CORBA_Octet*& coct)
{
    if ( CORBA_is_nil(components_[0]) )
            throw Invalid();
    CORBA_DynAny_impl::_narrow_impl (components_[0]) -> Unmarshal (coct);

    check_discriminator_and_set_member ();

    if ( CORBA_is_nil(components_[1]) )
            throw Invalid();
    CORBA_DynAny_impl::_narrow_impl (components_[1]) -> Unmarshal (coct);
}

// ----------------------------------------------------------------------
// CORBA_DynUnion_impl public IDL member implementation
// from CORBA_DynAny interface
// ----------------------------------------------------------------------

void
CORBA_DynUnion_impl::assign(CORBA_DynAny_ptr dyn_any)
{
    CORBA_TypeCode_var tc = dyn_any->type();

    if ( ! tc->equal(type_) )
        throw Invalid ();

    CORBA_DynUnion_impl* dyn_union =
                 CORBA_DynUnion_impl::_narrow_impl(dyn_any);

    if ( CORBA_is_nil(dyn_union) )
        throw Invalid ();

    CORBA_DynAny_var component = dyn_union->components_[0];

    if ( CORBA_is_nil(component) )
        throw Invalid ();

    components_[0] = component -> copy ();

    check_discriminator_and_set_member ();

    component = dyn_union->components_[1];

    if ( CORBA_is_nil(component) )
        components_[1] = CORBA_DynAny::_nil();
    else
        components_[1] = component -> copy ();
}
  
CORBA_DynAny_ptr
CORBA_DynUnion_impl::copy()
{
    CORBA_DynUnion_impl* result = new CORBA_DynUnion_impl (type_);

    result->current_discr_index_ = current_discr_index_;
 
    for (CORBA_ULong i=0; i<2; i++) {
        CORBA_DynAny_ptr component = components_[i];
        if ( !CORBA_is_nil(component) )
            result->components_[i] = components_[i] -> copy ();
        else
            result->components_[i] = CORBA_DynAny::_nil();
    }

    return result;
}

CORBA_Boolean
CORBA_DynUnion_impl::next()
{
    CORBA_Boolean boolean = CORBA_DynComplex_impl::next();

    if ( boolean && ( index_ == 1 ) ) {
        check_discriminator_and_set_member ();
    }

    return boolean;
}

// ----------------------------------------------------------------------
// CORBA_DynUnion_impl public IDL member implementation
// from CORBA_DynUnion interface
// ----------------------------------------------------------------------

//
// WARNING
//
// I not sure than I have understand
// the semantic of the set_as_default attribute
//

CORBA_Boolean
CORBA_DynUnion_impl::set_as_default()
{
    return ( default_index_ != -1 )
        && ( current_discr_index_ == default_index_);
}

void
CORBA_DynUnion_impl::set_as_default(CORBA_Boolean b)
{
    if ( ! b )
        return;

    if ( default_index_ == -1 )
        return;

    set_dyn_any (components_[0], member_labels_[default_index_]);
next();
    check_discriminator_and_set_member ();
    index_ = 1;
}

CORBA_DynAny_ptr
CORBA_DynUnion_impl::discriminator()
{
    return CORBA_DynAny::_duplicate(components_[0]);
}

CORBA_TCKind
CORBA_DynUnion_impl::discriminator_kind()
{
    CORBA_TypeCode_var discriminator_type = components_[0]->type();
    return discriminator_type->kind();
}

CORBA_DynAny_ptr
CORBA_DynUnion_impl::member()
{
    check_discriminator_and_set_member ();
    return CORBA_DynAny::_duplicate(components_[1]);
}

CORBA_FieldName
CORBA_DynUnion_impl::member_name()
{
    if ( current_discr_index_ == -1 )
        return CORBA_string_dup("");

    CORBA_TypeCode_var tc = OBGetOrigType(type_);

    return CORBA_string_dup (
        tc -> member_name ( CORBA_ULong(current_discr_index_) ) );
}

void
CORBA_DynUnion_impl::member_name(const char* name)
{
    CORBA_TypeCode_var tc = OBGetOrigType(type_);

    for (CORBA_ULong i=0; i<member_labels_.length(); i++)
        if ( strcmp(name, tc->member_name(i)) == 0 ) {
            set_dyn_any (components_[0], member_labels_[i]);
            check_discriminator_and_set_member ();
            index_ = 1;
            return;
        }

    // Must throw an exception?
}

CORBA_TCKind
CORBA_DynUnion_impl::member_kind()
{
    if ( ! CORBA_is_nil (components_[1]) ) {
        CORBA_TypeCode_var member_type = components_[1]->type();
        return member_type->kind();
    }

    // Must throw an exception?

    return CORBA_tk_null;
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
//
// CORBA_DynSequence implementation
//
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
// CORBA_DynSequence_impl constructor and destructor
// ----------------------------------------------------------------------

CORBA_DynSequence_impl::CORBA_DynSequence_impl(CORBA_TypeCode_ptr type)
    : CORBA_DynComplex_impl(type)
    , CORBA_DynAny_impl (type)
{
}

CORBA_DynSequence_impl::~CORBA_DynSequence_impl()
{
}

// ----------------------------------------------------------------------
// internal operation to init components
// ----------------------------------------------------------------------

void
CORBA_DynSequence_impl::init_components (CORBA_ULong value)
{
    CORBA_TypeCode_var tc = OBGetOrigType(type_);

    CORBA_TypeCode_var content_type = tc->content_type();

    CORBA_DynComplex_impl::init_components (value);

    for (CORBA_ULong i=0; i<value; i++) {
        if ( CORBA_is_nil(components_[i]) )
	    components_[i] = CORBA_DynAny_impl::create (content_type);
    }
}

// ----------------------------------------------------------------------
// CORBA_DynSequence_impl operations
// to marshal and unmarshal components into a complex any value
// ----------------------------------------------------------------------

void
CORBA_DynSequence_impl::MarshalCount(CORBA_ULong& count)
{
    // Use specific OB function
    OBMarshalCount (CORBA_ULong(components_.length()), count);

    CORBA_DynComplex_impl::MarshalCount (count);
}

void
CORBA_DynSequence_impl::Marshal (CORBA_Octet*& oct)
{
    // Use specific OB function
    OBMarshal (CORBA_ULong(components_.length()), oct);
 
   CORBA_DynComplex_impl::Marshal (oct);
}

void
CORBA_DynSequence_impl::Unmarshal (const CORBA_Octet*& coct)
{
    CORBA_ULong count;
    
    // Use specific OB function
    OBUnmarshal (count, coct, CORBA_FALSE);

    init_components (count);

    CORBA_DynComplex_impl::Unmarshal (coct);
}

// ----------------------------------------------------------------------
// CORBA_DynSequence_impl public IDL member implementation
// from CORBA_DynAny interface
// ----------------------------------------------------------------------

void
CORBA_DynSequence_impl::assign(CORBA_DynAny_ptr dyn_any)
{
    CORBA_TypeCode_var tc = dyn_any->type();

    if ( ! tc->equal(type_) )
        throw Invalid ();

    CORBA_DynSequence_impl* dyn_sequence =
                 CORBA_DynSequence_impl::_narrow_impl(dyn_any);

    if ( CORBA_is_nil(dyn_sequence) )
        throw Invalid ();

    components_.length(dyn_sequence->components_.length());

    for (CORBA_ULong i=0; i<components_.length(); i++) {
        CORBA_DynAny_ptr component = dyn_sequence->components_[i];
        if ( CORBA_is_nil(component) )
            components_[i] = CORBA_DynAny::_nil();
        else
            components_[i] = component -> copy ();
    }
}
  
CORBA_DynAny_ptr
CORBA_DynSequence_impl::copy()
{
    CORBA_DynSequence_impl* result =
                      new CORBA_DynSequence_impl (type_);

    result->components_.length(components_.length());

    for (CORBA_ULong i=0; i<components_.length(); i++) {
        result->components_[i] = components_[i] -> copy ();
    }

    return result;
}

// ----------------------------------------------------------------------
// CORBA_DynSequence_impl public IDL member implementation
// from CORBA_DynSequence interface
// ----------------------------------------------------------------------

CORBA_ULong
CORBA_DynSequence_impl::length()
{
    return components_.length();
}

void
CORBA_DynSequence_impl::length(CORBA_ULong value)
{
    init_components (value);
}

CORBA_AnySeq*
CORBA_DynSequence_impl::get_elements()
{
    CORBA_AnySeq* result = new CORBA_AnySeq;
    result->length(components_.length());

    for (CORBA_ULong i=0; i<components_.length(); i++) {
        CORBA_Any_var any = components_[i]->to_any();
        (*result)[i] = any; 
    }
    return result;
}

void
CORBA_DynSequence_impl::set_elements(const CORBA_AnySeq& value)
{
    if (value.length() != components_.length())
        throw InvalidSeq ();

    CORBA_TypeCode_var tc = OBGetOrigType(type_);
    CORBA_TypeCode_var content_type = tc->content_type();

    CORBA_ULong i;
    for (i=0; i<components_.length(); i++) {
        CORBA_TypeCode_var value_type = value[i].type();
        if ( ! value_type->equal(content_type) )
             throw InvalidSeq ();
    }

    for (i=0; i<components_.length(); i++)
        components_[i]->from_any (value[i]);
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
//
// CORBA_DynArray_impl implementation
//
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
// CORBA_DynArray_impl constructor and destructor
// ----------------------------------------------------------------------

CORBA_DynArray_impl::CORBA_DynArray_impl(CORBA_TypeCode_ptr type,
                                         CORBA_Boolean init)
    : CORBA_DynComplex_impl(type)
    , CORBA_DynAny_impl (type)
{
    CORBA_TypeCode_var tc = OBGetOrigType(type);

    CORBA_DynComplex_impl::init_components(tc->length());

    if (init) {
        CORBA_TypeCode_var content_type = tc->content_type();
        for (CORBA_ULong i=0; i<components_.length(); i++) {
	    components_[i] = CORBA_DynAny_impl::create (content_type);
        }
    }
}

CORBA_DynArray_impl::~CORBA_DynArray_impl()
{
}

// ----------------------------------------------------------------------
// CORBA_DynArray_impl public IDL member implementation
// from CORBA_DynAny interface
// ----------------------------------------------------------------------

CORBA_DynAny_ptr
CORBA_DynArray_impl::copy()
{
    CORBA_DynArray_impl* result =
                      new CORBA_DynArray_impl (type_, CORBA_FALSE);

    for (CORBA_ULong i=0; i<components_.length(); i++) {
        result->components_[i] = components_[i] -> copy ();
    }

    return result;
}

// ----------------------------------------------------------------------
// CORBA_DynArray_impl public IDL member implementation
// from CORBA_DynArray interface
// ----------------------------------------------------------------------

CORBA_AnySeq*
CORBA_DynArray_impl::get_elements()
{
    CORBA_AnySeq* result = new CORBA_AnySeq;
    result->length(components_.length());

    for (CORBA_ULong i=0; i<components_.length(); i++) {
        CORBA_Any_var any = components_[i]->to_any();
        (*result)[i] = any; 
    }
    return result;
}

void
CORBA_DynArray_impl::set_elements(const CORBA_AnySeq& value)
{
    if (value.length() != components_.length())
        throw InvalidSeq ();

    CORBA_TypeCode_var tc = OBGetOrigType(type_);

    CORBA_TypeCode_var content_type = tc->content_type();

    CORBA_ULong i;

    for (i=0; i<components_.length(); i++) {
        CORBA_TypeCode_var value_type = value[i].type();
        if ( ! value_type->equal(content_type) )
             throw InvalidSeq ();
    }

    for (i=0; i<components_.length(); i++)
        components_[i]->from_any (value[i]);
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
//
// ORB public member implementations that are related to DynAny
//
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

CORBA_DynAny_ptr
CORBA_ORB::create_dyn_any(const CORBA_Any& value)
{
    CORBA_TypeCode_var tc = value.type();
    CORBA_DynAny_ptr result = CORBA_DynAny_impl::create (tc);
    result->from_any (value);
    return result;
}

CORBA_DynAny_ptr
CORBA_ORB::create_basic_dyn_any(CORBA_TypeCode_ptr type)
{
    CORBA_TypeCode_var tc = OBGetOrigType(type);

    switch(tc -> kind())
    {
    case CORBA_tk_null:
    case CORBA_tk_void:
    case CORBA_tk_short:
    case CORBA_tk_long:
    case CORBA_tk_ushort:
    case CORBA_tk_ulong:
    case CORBA_tk_float:
    case CORBA_tk_double:
    case CORBA_tk_boolean:
    case CORBA_tk_char:
    case CORBA_tk_octet:
    case CORBA_tk_any:
    case CORBA_tk_TypeCode:
    case CORBA_tk_Principal:
    case CORBA_tk_objref:
    case CORBA_tk_string:
	break;

    case CORBA_tk_struct:
    case CORBA_tk_union:
    case CORBA_tk_enum:
    case CORBA_tk_sequence:
    case CORBA_tk_array:
    case CORBA_tk_except:
	throw InconsistentTypeCode();

    case CORBA_tk_alias:
	assert(false);
	break;
    }

    return new CORBA_DynBasic_impl(type);
}

CORBA_DynStruct_ptr
CORBA_ORB::create_dyn_struct(CORBA_TypeCode_ptr type)
{
    CORBA_TypeCode_var tc = OBGetOrigType(type);

    if(tc -> kind() == CORBA_tk_struct)
        return new CORBA_DynStruct_impl(type);

    if(tc -> kind() == CORBA_tk_except)
        return new CORBA_DynException_impl(type);

    throw InconsistentTypeCode();
    return CORBA_DynStruct::_nil(); // Some compilers need this
}

CORBA_DynSequence_ptr
CORBA_ORB::create_dyn_sequence(CORBA_TypeCode_ptr type)
{
    CORBA_TypeCode_var tc = OBGetOrigType(type);

    if(tc -> kind() != CORBA_tk_sequence)
	throw InconsistentTypeCode();

    return new CORBA_DynSequence_impl(type);
}

CORBA_DynArray_ptr
CORBA_ORB::create_dyn_array(CORBA_TypeCode_ptr type)
{
    CORBA_TypeCode_var tc = OBGetOrigType(type);

    if(tc -> kind() != CORBA_tk_array)
	throw InconsistentTypeCode();

    return new CORBA_DynArray_impl(type);
}

CORBA_DynUnion_ptr
CORBA_ORB::create_dyn_union(CORBA_TypeCode_ptr type)
{
    CORBA_TypeCode_var tc = OBGetOrigType(type);

    if(tc -> kind() != CORBA_tk_union)
	throw InconsistentTypeCode();

    return new CORBA_DynUnion_impl(type);
}

CORBA_DynEnum_ptr
CORBA_ORB::create_dyn_enum(CORBA_TypeCode_ptr type)
{
    CORBA_TypeCode_var tc = OBGetOrigType(type);

    if(tc -> kind() != CORBA_tk_enum)
	throw InconsistentTypeCode();

    return new CORBA_DynEnum_impl(type);
}

// ----------------------------------------------------------------------
// end of file
// ----------------------------------------------------------------------
