/*
 *  MICO --- a free CORBA implementation
 *  Copyright (C) 1997-98 Kay Roemer & Arno Puder
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Send comments and/or bug reports to:
 *                 mico@informatik.uni-frankfurt.de
 */

#include <CORBA.h>
#include <mico/impl.h>
#include <mico/throw.h>
#include <mico/template_impl.h>


/************************* Generated *******************************/


CORBA::DynAny::Invalid::Invalid()
{
}

CORBA::DynAny::Invalid::Invalid( const Invalid& _s )
{
}

CORBA::DynAny::Invalid::~Invalid()
{
}

CORBA::DynAny::Invalid&
CORBA::DynAny::Invalid::operator=( const Invalid& _s )
{
    return *this;
}

void CORBA::DynAny::Invalid::_throwit() const
{
#ifdef HAVE_EXCEPTIONS
    throw Invalid_var( (Invalid *)_clone() );
#else
    assert (0);
#endif
}

const char *CORBA::DynAny::Invalid::_repoid() const
{
    return "IDL:omg.org/CORBA/DynAny/Invalid:1.0";
}

void CORBA::DynAny::Invalid::_encode( CORBA::DataEncoder &_en ) const
{
    assert (0);
}

CORBA::Exception *CORBA::DynAny::Invalid::_clone() const
{
    return new Invalid( *this );
}

CORBA::DynAny::Invalid *
CORBA::DynAny::Invalid::_narrow( CORBA::Exception *_ex )
{
    if( _ex && !strcmp( _ex->_repoid(), "IDL:omg.org/CORBA/DynAny/Invalid:1.0" ) )
	return (Invalid *) _ex;
    return NULL;
}



CORBA::DynAny::InvalidValue::InvalidValue()
{
}

CORBA::DynAny::InvalidValue::InvalidValue( const InvalidValue& _s )
{
}

CORBA::DynAny::InvalidValue::~InvalidValue()
{
}

CORBA::DynAny::InvalidValue&
CORBA::DynAny::InvalidValue::operator=( const InvalidValue& _s )
{
  return *this;
}

void CORBA::DynAny::InvalidValue::_throwit() const
{
#ifdef HAVE_EXCEPTIONS
    throw InvalidValue_var( (InvalidValue *)_clone() );
#else
    assert (0);
#endif
}

const char *CORBA::DynAny::InvalidValue::_repoid() const
{
    return "IDL:omg.org/CORBA/DynAny/InvalidValue:1.0";
}

void CORBA::DynAny::InvalidValue::_encode( CORBA::DataEncoder &_en ) const
{
    assert (0);
}

CORBA::Exception *
CORBA::DynAny::InvalidValue::_clone() const
{
    return new InvalidValue( *this );
}

CORBA::DynAny::InvalidValue *
CORBA::DynAny::InvalidValue::_narrow( CORBA::Exception *_ex )
{
    if( _ex && !strcmp( _ex->_repoid(),
			"IDL:omg.org/CORBA/DynAny/InvalidValue:1.0" ) )
	return (InvalidValue *) _ex;
    return NULL;
}



CORBA::DynAny::InvalidSeq::InvalidSeq()
{
}

CORBA::DynAny::InvalidSeq::InvalidSeq( const InvalidSeq& _s )
{
}

CORBA::DynAny::InvalidSeq::~InvalidSeq()
{
}

CORBA::DynAny::InvalidSeq&
CORBA::DynAny::InvalidSeq::operator=( const InvalidSeq& _s )
{
    return *this;
}

void CORBA::DynAny::InvalidSeq::_throwit() const
{
#ifdef HAVE_EXCEPTIONS
    throw InvalidSeq_var( (InvalidSeq *)_clone() );
#else
    assert (0);
#endif
}

const char *CORBA::DynAny::InvalidSeq::_repoid() const
{
    return "IDL:omg.org/CORBA/DynAny/InvalidSeq:1.0";
}

void CORBA::DynAny::InvalidSeq::_encode( CORBA::DataEncoder &_en ) const
{
    assert (0);
}

CORBA::Exception *CORBA::DynAny::InvalidSeq::_clone() const
{
    return new InvalidSeq( *this );
}

CORBA::DynAny::InvalidSeq *
CORBA::DynAny::InvalidSeq::_narrow( CORBA::Exception *_ex )
{
    if( _ex && !strcmp( _ex->_repoid(),
			"IDL:omg.org/CORBA/DynAny/InvalidSeq:1.0" ) )
	return (InvalidSeq *) _ex;
    return NULL;
}



CORBA::DynAny::TypeMismatch::TypeMismatch()
{
}

CORBA::DynAny::TypeMismatch::TypeMismatch( const TypeMismatch& _s )
{
}

CORBA::DynAny::TypeMismatch::~TypeMismatch()
{
}

CORBA::DynAny::TypeMismatch&
CORBA::DynAny::TypeMismatch::operator=( const TypeMismatch& _s )
{
    return *this;
}

void CORBA::DynAny::TypeMismatch::_throwit() const
{
#ifdef HAVE_EXCEPTIONS
    throw TypeMismatch_var( (TypeMismatch *)_clone() );
#else
    assert (0);
#endif
}

const char *CORBA::DynAny::TypeMismatch::_repoid() const
{
    return "IDL:omg.org/CORBA/DynAny/TypeMismatch:1.0";
}

void CORBA::DynAny::TypeMismatch::_encode( CORBA::DataEncoder &_en ) const
{
    assert (0);
}

CORBA::Exception *
CORBA::DynAny::TypeMismatch::_clone() const
{
    return new TypeMismatch( *this );
}

CORBA::DynAny::TypeMismatch *
CORBA::DynAny::TypeMismatch::_narrow( CORBA::Exception *_ex )
{
    if( _ex && !strcmp( _ex->_repoid(),
			"IDL:omg.org/CORBA/DynAny/TypeMismatch:1.0" ) )
	return (TypeMismatch *) _ex;
    return NULL;
}


// gcc 2.7.2 references this although not used; moved to orb/dynany.cc
#if 0
CORBA::NameValuePair::NameValuePair()
{
}

CORBA::NameValuePair::NameValuePair( const NameValuePair& _s )
{
    id = ((NameValuePair&)_s).id;
    value = ((NameValuePair&)_s).value;
}

CORBA::NameValuePair::~NameValuePair()
{
}

CORBA::NameValuePair&
CORBA::NameValuePair::operator=( const NameValuePair& _s )
{
    id = ((NameValuePair&)_s).id;
    value = ((NameValuePair&)_s).value;
    return *this;
}
#endif


CORBA::ORB::InconsistentTypeCode::InconsistentTypeCode()
{
}

CORBA::ORB::InconsistentTypeCode::InconsistentTypeCode(
    const InconsistentTypeCode& _s )
{
}

CORBA::ORB::InconsistentTypeCode::~InconsistentTypeCode()
{
}

CORBA::ORB::InconsistentTypeCode&
CORBA::ORB::InconsistentTypeCode::operator=(
    const InconsistentTypeCode& _s )
{
    return *this;
}

void CORBA::ORB::InconsistentTypeCode::_throwit() const
{
#ifdef HAVE_EXCEPTIONS
    throw InconsistentTypeCode_var( (InconsistentTypeCode *)_clone() );
#else
    assert (0);
#endif
}

const char *CORBA::ORB::InconsistentTypeCode::_repoid() const
{
    return "IDL:omg.org/CORBA/ORB/InconsistentTypeCode:1.0";
}

void CORBA::ORB::InconsistentTypeCode::_encode(
    CORBA::DataEncoder &_en ) const
{
    assert (0);
}

CORBA::Exception *
CORBA::ORB::InconsistentTypeCode::_clone() const
{
    return new InconsistentTypeCode( *this );
}

CORBA::ORB::InconsistentTypeCode *
CORBA::ORB::InconsistentTypeCode::_narrow(
    CORBA::Exception *_ex )
{
    if( _ex &&
	!strcmp( _ex->_repoid(),
		 "IDL:omg.org/CORBA/ORB/InconsistentTypeCode:1.0" ) )
	return (InconsistentTypeCode *) _ex;
    return NULL;
}


/************************** DynAny *********************************/


CORBA::DynAny::DynAny ()
    : _index (0)
{
}

CORBA::DynAny::~DynAny ()
{
}

const char *
CORBA::DynAny::_repoid () const
{
    return "IDL:omg.org/CORBA/DynAny:1.0";
}

#if 0
CORBA::DynAny_ptr
CORBA::DynAny::_nil ()
{
    return NULL;
}

CORBA::DynAny_ptr
CORBA::DynAny::_duplicate (DynAny_ptr _obj)
{
    if( !CORBA::is_nil( _obj ) )
	_obj->_ref();
    return _obj;
}
#endif

CORBA::DynAny_ptr
CORBA::DynAny::_narrow (DynAny_ptr _obj)
{
    return _duplicate (_obj);
}

CORBA::ORB_ptr
CORBA::DynAny::_factory ()
{
    static CORBA::ORB_ptr factory =
	CORBA::ORB::_nil();

    if (CORBA::is_nil (factory))
	factory = CORBA::ORB_instance ("mico-local-orb");

    return factory;
}

void
CORBA::DynAny::update_element (CORBA::Long idx)
{
}

void
CORBA::DynAny::assign (CORBA::DynAny_ptr dyn_any)
{
    CORBA::Any_var a = dyn_any->to_any ();
    from_any (a);
}

CORBA::DynAny_ptr
CORBA::DynAny::copy ()
{
    CORBA::Any_var a = to_any ();
    return _factory()->create_dyn_any (a);
}

CORBA::TypeCode_ptr
CORBA::DynAny::type ()
{
    return CORBA::TypeCode::_duplicate (_type);
}

void
CORBA::DynAny::destroy ()
{
    for (CORBA::ULong i = 0; i < _elements.size(); ++i)
	_elements[i]->destroy();
    _elements.erase (_elements.begin(), _elements.end());
    CORBA::release (this);
}

/*
 * do insert_* and get_* advance _index? This isn't explicitely
 * stated in the docs, but the given example suggests that at least
 * the insert_* ops do so.
 */

void
CORBA::DynAny::insert_boolean (CORBA::Boolean value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= CORBA::Any::from_boolean (value);
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_octet (CORBA::Octet value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= CORBA::Any::from_octet (value);
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_char (CORBA::Char value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= CORBA::Any::from_char (value);
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_wchar (CORBA::WChar value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= CORBA::Any::from_wchar (value);
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_short (CORBA::Short value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= value;
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_ushort (CORBA::UShort value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= value;
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_long (CORBA::Long value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= value;
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_longlong (CORBA::LongLong value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= value;
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_ulong (CORBA::ULong value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= value;
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_ulonglong (CORBA::ULongLong value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= value;
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_float (CORBA::Float value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= value;
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_double (CORBA::Double value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= value;
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_longdouble (CORBA::LongDouble value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= value;
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_string (const char* value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= value;
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_wstring (const CORBA::WChar* value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= value;
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_reference (CORBA::Object_ptr value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    if (_type->unalias()->kind() == CORBA::tk_objref)
        a <<= CORBA::Any::from_object (value, _type->name());
    else
        a <<= CORBA::Any::from_object (value, "");
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_typecode (CORBA::TypeCode_ptr value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= value;
    _elements[_index]->from_any (a);
    next ();
}

void
CORBA::DynAny::insert_any (const CORBA::Any &value)
{
    update_element (_index);
    CORBA::Any a;
    // take care for aliases of base types
    a.type (_elements[_index]->_type);
    a <<= value;
    _elements[_index]->from_any (a);
    next ();
}

CORBA::Boolean
CORBA::DynAny::get_boolean ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::Boolean value;
    if (!((CORBA::Any &)a >>= CORBA::Any::to_boolean (value)))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::Octet
CORBA::DynAny::get_octet ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::Octet value;
    if (!((CORBA::Any &)a >>= CORBA::Any::to_octet (value)))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::Char
CORBA::DynAny::get_char ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::Char value;
    if (!((CORBA::Any &)a >>= CORBA::Any::to_char (value)))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::WChar
CORBA::DynAny::get_wchar ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::WChar value;
    if (!((CORBA::Any &)a >>= CORBA::Any::to_wchar (value)))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::Short
CORBA::DynAny::get_short ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::Short value;
    if (!((CORBA::Any &)a >>= value))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::UShort
CORBA::DynAny::get_ushort ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::UShort value;
    if (!((CORBA::Any &)a >>= value))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::Long
CORBA::DynAny::get_long ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::Long value;
    if (!((CORBA::Any &)a >>= value))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::LongLong
CORBA::DynAny::get_longlong ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::LongLong value;
    if (!((CORBA::Any &)a >>= value))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::ULong
CORBA::DynAny::get_ulong ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::ULong value;
    if (!((CORBA::Any &)a >>= value))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::ULongLong
CORBA::DynAny::get_ulonglong ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::ULongLong value;
    if (!((CORBA::Any &)a >>= value))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::Float
CORBA::DynAny::get_float ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::Float value;
    if (!((CORBA::Any &)a >>= value))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::Double
CORBA::DynAny::get_double ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::Double value;
    if (!((CORBA::Any &)a >>= value))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::LongDouble
CORBA::DynAny::get_longdouble ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::LongDouble value;
    if (!((CORBA::Any &)a >>= value))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

char*
CORBA::DynAny::get_string ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    char *value;
    if (!((CORBA::Any &)a >>= value))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::WChar*
CORBA::DynAny::get_wstring ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::WChar *value;
    if (!((CORBA::Any &)a >>= value))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::Object_ptr
CORBA::DynAny::get_reference ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::Object_ptr value;
    if (!((CORBA::Any &)a >>= CORBA::Any::to_object (value)))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::TypeCode_ptr
CORBA::DynAny::get_typecode ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::TypeCode_ptr value;
    if (!((CORBA::Any &)a >>= value))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::Any*
CORBA::DynAny::get_any ()
{
    update_element (_index);
    CORBA::Any_var a = _elements[_index]->to_any();
    CORBA::Any *value = new CORBA::Any;
    if (!((CORBA::Any &)a >>= *value))
	mico_throw (TypeMismatch ());
    next ();
    return value;
}

CORBA::DynAny_ptr
CORBA::DynAny::current_component ()
{
    update_element (_index);
    return CORBA::DynAny::_duplicate (_elements[_index]);
}

CORBA::Boolean
CORBA::DynAny::next ()
{
    if ((CORBA::ULong)_index+1 == _elements.size())
	return FALSE;
    ++_index;
    return TRUE;
}

CORBA::Boolean
CORBA::DynAny::seek (CORBA::Long index)
{
    update_element (index); // might cause element to disappear
    if (index < 0 || (CORBA::ULong)index >= _elements.size())
	return FALSE;
    _index = index;
    return TRUE;
}

void
CORBA::DynAny::rewind ()
{
    _index = 0;
}


/************************* DynBasic *******************************/


CORBA::DynBasic::DynBasic (CORBA::TypeCode_ptr tc)
{
    _type = CORBA::TypeCode::_duplicate (tc);
    // take care for aliases of base types
    _value.type (_type);
    tc = tc->unalias ();
    switch (tc->kind()) {
    case CORBA::tk_void:
    case CORBA::tk_null:
	break;
    case CORBA::tk_char:
	_value <<= CORBA::Any::from_char (0);
	break;
    case CORBA::tk_wchar:
	_value <<= CORBA::Any::from_wchar (0);
	break;
    case CORBA::tk_boolean:
	_value <<= CORBA::Any::from_boolean (FALSE);
	break;
    case CORBA::tk_octet:
	_value <<= CORBA::Any::from_octet (0);
	break;
    case CORBA::tk_short:
	_value <<= (CORBA::Short)0;
	break;
    case CORBA::tk_ushort:
	_value <<= (CORBA::UShort)0;
	break;
    case CORBA::tk_long:
	_value <<= (CORBA::Long)0;
	break;
    case CORBA::tk_longlong:
	_value <<= (CORBA::LongLong)0;
	break;
    case CORBA::tk_ulong:
	_value <<= (CORBA::ULong)0;
	break;
    case CORBA::tk_ulonglong:
	_value <<= (CORBA::ULongLong)0;
	break;
    case CORBA::tk_float:
	_value <<= (CORBA::Float)0;
	break;
    case CORBA::tk_double:
	_value <<= (CORBA::Double)0;
	break;
    case CORBA::tk_longdouble:
	_value <<= (CORBA::LongDouble)0;
	break;
    case CORBA::tk_any:
	_value <<= CORBA::Any();
	break;
    case CORBA::tk_TypeCode:
	_value <<= CORBA::_tc_void;
	break;
    case CORBA::tk_objref:
	_value <<= CORBA::Any::from_object (CORBA::Object::_nil(), "");
	break;
    case CORBA::tk_string:
        _value <<= "";
        break;
    case CORBA::tk_wstring:
        _value <<= L"";
        break;
    default:
	mico_throw (CORBA::ORB::InconsistentTypeCode ());
    }
    _elements.push_back (_duplicate (this));
}

CORBA::DynBasic::DynBasic (const CORBA::Any &a)
{
    _value = a;
    _type = _value.type();

    switch (_type->unalias()->kind()) {
    case CORBA::tk_void:
    case CORBA::tk_null:
    case CORBA::tk_char:
    case CORBA::tk_wchar:
    case CORBA::tk_boolean:
    case CORBA::tk_octet:
    case CORBA::tk_short:
    case CORBA::tk_ushort:
    case CORBA::tk_long:
    case CORBA::tk_longlong:
    case CORBA::tk_ulong:
    case CORBA::tk_ulonglong:
    case CORBA::tk_float:
    case CORBA::tk_double:
    case CORBA::tk_longdouble:
    case CORBA::tk_any:
    case CORBA::tk_TypeCode:
    case CORBA::tk_objref:
    case CORBA::tk_string:
    case CORBA::tk_wstring:
	break;
    default:
	mico_throw (CORBA::ORB::InconsistentTypeCode ());
    }
    _elements.push_back (_duplicate (this));
}

CORBA::DynBasic::~DynBasic ()
{
}

const char *
CORBA::DynBasic::_repoid () const
{
    return "IDL:omg.org/CORBA/DynBasic:1.0";
}

#if 0
CORBA::DynBasic_ptr
CORBA::DynBasic::_nil ()
{
    return NULL;
}

CORBA::DynBasic_ptr
CORBA::DynBasic::_duplicate (DynBasic_ptr _obj)
{
    if( !CORBA::is_nil( _obj ) )
	_obj->_ref();
    return _obj;
}
#endif

CORBA::DynBasic_ptr
CORBA::DynBasic::_narrow (DynAny_ptr _obj)
{
    if (CORBA::is_nil (_obj))
	return _nil();
    if (!strcmp (_obj->_repoid(), "IDL:omg.org/CORBA/DynBasic:1.0"))
	return _duplicate ((DynBasic_ptr)_obj);
    return _nil();
}

void
CORBA::DynBasic::destroy ()
{
    _elements.pop_back ();
    CORBA::release (this);
}

void
CORBA::DynBasic::from_any (const CORBA::Any& value)
{
    CORBA::TypeCode_var tc = value.type();
    if (_type->unalias()->kind() != CORBA::tk_objref ||
	tc->unalias()->kind() != CORBA::tk_objref) {
        if (!_type->equaltype (tc))
            mico_throw (Invalid ());
    }
    _value = value;
}

CORBA::Any*
CORBA::DynBasic::to_any ()
{
    return new CORBA::Any (_value);
}


/************************** DynFixed ********************************/


CORBA::DynFixed::DynFixed (CORBA::TypeCode_ptr tc)
{
    if (tc->unalias()->kind() != CORBA::tk_fixed)
	mico_throw (CORBA::ORB::InconsistentTypeCode ());

    _type = CORBA::TypeCode::_duplicate (tc);

    FixedBase::FixedValue_var v = new FixedBase::FixedValue;
    v->length (tc->unalias()->fixed_digits()+1);
    
    CORBA::Boolean r =
	(_value <<= CORBA::Any::from_fixed (v,tc->unalias()->fixed_digits(),
					    tc->unalias()->fixed_scale()));
    assert (r);

    _elements.push_back (_duplicate (this));
}

CORBA::DynFixed::DynFixed (const CORBA::Any &a)
{
    _value = a;
    _type = a.type();
    if (_type->unalias()->kind() != CORBA::tk_fixed)
	mico_throw (CORBA::ORB::InconsistentTypeCode ());

    _elements.push_back (_duplicate (this));
}

CORBA::DynFixed::~DynFixed ()
{
}

const char *
CORBA::DynFixed::_repoid () const
{
    return "IDL:omg.org/CORBA/DynFixed:1.0";
}

#if 0
CORBA::DynFixed_ptr
CORBA::DynFixed::_nil ()
{
    return NULL;
}

CORBA::DynFixed_ptr
CORBA::DynFixed::_duplicate (DynFixed_ptr _obj)
{
    if( !CORBA::is_nil( _obj ) )
	_obj->_ref();
    return _obj;
}
#endif

CORBA::DynFixed_ptr
CORBA::DynFixed::_narrow (DynAny_ptr _obj)
{
    if (CORBA::is_nil (_obj))
	return _nil();
    if (!strcmp (_obj->_repoid(), "IDL:omg.org/CORBA/DynFixed:1.0"))
	return _duplicate ((DynFixed_ptr)_obj);
    return _nil();
}

void
CORBA::DynFixed::destroy ()
{
    _elements.pop_back ();
    CORBA::release (this);
}

void
CORBA::DynFixed::from_any (const CORBA::Any& value)
{
    CORBA::TypeCode_var tc = value.type();
    if (!_type->equaltype (tc))
	mico_throw (Invalid ());
    _value = value;
}

CORBA::Any*
CORBA::DynFixed::to_any ()
{
    return new CORBA::Any (_value);
}

CORBA::OctetSeq*
CORBA::DynFixed::get_value ()
{
    FixedBase::FixedValue_var v;
    CORBA::TypeCode_ptr tc = _type->unalias();

    CORBA::Boolean r = (_value >>= CORBA::Any::to_fixed (v, tc->fixed_digits(),
							 tc->fixed_scale()));
    assert (r);

    // convert to CDR format
    MICO::CDREncoder ec;
    ec.put_fixed (v, tc->fixed_digits(), tc->fixed_scale());
    CORBA::OctetSeq *out =
	new CORBA::OctetSeq (ec.buffer()->length(),
				  ec.buffer()->length(),
				  (CORBA::OctetWrapper *)ec.buffer()->buffer(),
				  FALSE);
    return out;
}

void
CORBA::DynFixed::set_value (const CORBA::OctetSeq& in)
{
    CORBA::TypeCode_ptr tc = _type->unalias();

    // convert from CDR format
    FixedBase::FixedValue_var v = new FixedBase::FixedValue;
    MICO::CDRDecoder dc;
    dc.buffer()->put (&in[0], in.length());
    // XXX what exception
    CORBA::Boolean r = dc.get_fixed (v, tc->fixed_digits(), tc->fixed_scale());
    assert (r);

    // XXX what exception
    r = (_value <<= CORBA::Any::from_fixed (v, tc->fixed_digits(),
					    tc->fixed_scale()));
    assert (r);
}


/************************** DynEnum ********************************/


CORBA::DynEnum::DynEnum (CORBA::TypeCode_ptr tc)
{
    if (tc->unalias()->kind() != CORBA::tk_enum)
	mico_throw (CORBA::ORB::InconsistentTypeCode ());

    _type = CORBA::TypeCode::_duplicate (tc);
    _value.type (tc);
    _value.enum_put (0);

    _elements.push_back (_duplicate (this));
}

CORBA::DynEnum::DynEnum (const CORBA::Any &a)
{
    _value = a;
    _type = a.type();
    if (_type->unalias()->kind() != CORBA::tk_enum)
	mico_throw (CORBA::ORB::InconsistentTypeCode ());

    _elements.push_back (_duplicate (this));
}

CORBA::DynEnum::~DynEnum ()
{
}

const char *
CORBA::DynEnum::_repoid () const
{
    return "IDL:omg.org/CORBA/DynEnum:1.0";
}

#if 0
CORBA::DynEnum_ptr
CORBA::DynEnum::_nil ()
{
    return NULL;
}

CORBA::DynEnum_ptr
CORBA::DynEnum::_duplicate (DynEnum_ptr _obj)
{
    if( !CORBA::is_nil( _obj ) )
	_obj->_ref();
    return _obj;
}
#endif

CORBA::DynEnum_ptr
CORBA::DynEnum::_narrow (DynAny_ptr _obj)
{
    if (CORBA::is_nil (_obj))
	return _nil();
    if (!strcmp (_obj->_repoid(), "IDL:omg.org/CORBA/DynEnum:1.0"))
	return _duplicate ((DynEnum_ptr)_obj);
    return _nil();
}

void
CORBA::DynEnum::destroy ()
{
    _elements.pop_back ();
    CORBA::release (this);
}

void
CORBA::DynEnum::from_any (const CORBA::Any& value)
{
    CORBA::TypeCode_var tc = value.type();
    if (!_type->equaltype (tc))
	mico_throw (Invalid ());
    _value = value;
}

CORBA::Any*
CORBA::DynEnum::to_any ()
{
    return new CORBA::Any (_value);
}

char*
CORBA::DynEnum::value_as_string ()
{
    return CORBA::string_dup (
	_type->unalias()->member_name (value_as_ulong()));
}

void
CORBA::DynEnum::value_as_string (const char* value)
{
    CORBA::TypeCode_ptr tc = _type->unalias();
    CORBA::Long idx = tc->member_index (value);
    // XXX what exception ???
    assert (idx >= 0);
    CORBA::Boolean r = _value.enum_put (idx);
    assert (r);
}

CORBA::ULong
CORBA::DynEnum::value_as_ulong ()
{
    CORBA::ULong l;
    CORBA::Boolean r = _value.enum_get (l);
    assert (r);
    return l;
}

void
CORBA::DynEnum::value_as_ulong (CORBA::ULong value)
{
    // XXX what exception ???
    CORBA::Boolean r = _value.enum_put (value);
    assert (r);
}


/************************* DynStruct *******************************/


CORBA::DynStruct::DynStruct (CORBA::TypeCode_ptr tc)
{
    _type = CORBA::TypeCode::_duplicate (tc);
    tc = tc->unalias();
    if (tc->kind() != CORBA::tk_struct && tc->kind() != CORBA::tk_except)
	mico_throw (CORBA::ORB::InconsistentTypeCode ());
    _isexcept = (tc->kind() == CORBA::tk_except);
    for (CORBA::ULong i = 0; i < tc->member_count(); ++i) {
	CORBA::TypeCode_var memtc = tc->member_type(i);
	_elements.push_back (_factory()->create_dyn_tc (memtc));
    }
}

CORBA::DynStruct::DynStruct (const CORBA::Any &a)
{
    _type = a.type();
    CORBA::TypeCode_ptr tc = _type->unalias();
    if (tc->kind() != CORBA::tk_struct && tc->kind() != CORBA::tk_except)
	mico_throw (CORBA::ORB::InconsistentTypeCode ());
    _isexcept = (tc->kind() == CORBA::tk_except);

    if (_isexcept) {
	CORBA::String_var repoid;
	CORBA::Boolean r = a.except_get_begin (repoid);
	assert (r);
    } else {
	CORBA::Boolean r = a.struct_get_begin ();
	assert (r);
    }
    for (CORBA::ULong i = 0; i < tc->member_count(); ++i) {
	CORBA::Any el;
	CORBA::Boolean r = a.any_get (el);
	assert (r);
	_elements.push_back (_factory()->create_dyn_any (el));
    }
    if (_isexcept) {
	CORBA::Boolean r = a.except_get_end ();
	assert (r);
    } else {
	CORBA::Boolean r = a.struct_get_end ();
	assert (r);
    }
}

CORBA::DynStruct::~DynStruct ()
{
}

const char *
CORBA::DynStruct::_repoid () const
{
    return "IDL:omg.org/CORBA/DynStruct:1.0";
}

#if 0
CORBA::DynStruct_ptr
CORBA::DynStruct::_nil ()
{
    return NULL;
}

CORBA::DynStruct_ptr
CORBA::DynStruct::_duplicate (DynStruct_ptr _obj)
{
    if( !CORBA::is_nil( _obj ) )
	_obj->_ref();
    return _obj;
}
#endif

CORBA::DynStruct_ptr
CORBA::DynStruct::_narrow (DynAny_ptr _obj)
{
    if (CORBA::is_nil (_obj))
	return _nil();
    if (!strcmp (_obj->_repoid(), "IDL:omg.org/CORBA/DynStruct:1.0"))
	return _duplicate ((DynStruct_ptr)_obj);
    return _nil();
}

void
CORBA::DynStruct::from_any (const CORBA::Any& value)
{
    CORBA::TypeCode_var tc = value.type();
    if (!_type->equaltype (tc))
	mico_throw (Invalid ());

    if (_isexcept) {
	CORBA::String_var repoid;
	CORBA::Boolean r = value.except_get_begin (repoid);
	assert (r);
    } else {
	CORBA::Boolean r = value.struct_get_begin ();
	assert (r);
    }
    CORBA::TypeCode_ptr tc2 = tc->unalias();
    for (CORBA::ULong i = 0; i < tc2->member_count(); ++i) {
	CORBA::Any el;
	CORBA::Boolean r = value.any_get (el);
	assert (r);
	_elements[i]->from_any (el);
    }
    if (_isexcept) {
	CORBA::Boolean r = value.except_get_end ();
	assert (r);
    } else {
	CORBA::Boolean r = value.struct_get_end ();
	assert (r);
    }
}

CORBA::Any*
CORBA::DynStruct::to_any ()
{
    CORBA::Any *a = new CORBA::Any;

    a->type (_type);

    if (_isexcept) {
	CORBA::TypeCode_ptr tc = _type->unalias();
	CORBA::Boolean r = a->except_put_begin (tc->id());
	assert (r);
    } else {
	CORBA::Boolean r = a->struct_put_begin ();
	assert (r);
    }
    for (CORBA::ULong i = 0; i < _elements.size(); ++i) {
	CORBA::Any_var el = _elements[i]->to_any ();
	CORBA::Boolean r = a->any_put (el);
	assert (r);
    }
    if (_isexcept) {
	CORBA::Boolean r = a->except_put_end ();
	assert (r);
    } else {
	CORBA::Boolean r = a->struct_put_end ();
	assert (r);
    }
    return a;
}

CORBA::FieldName
CORBA::DynStruct::current_member_name ()
{
    return CORBA::string_dup (_type->unalias()->member_name (_index));
}

CORBA::TCKind
CORBA::DynStruct::current_member_kind ()
{
    // XXX unlias ???
    CORBA::TypeCode_var tc = _type->unalias()->member_type (_index);
    return tc->kind();
}

CORBA::NameValuePairSeq*
CORBA::DynStruct::get_members ()
{
    CORBA::NameValuePairSeq *seq = new CORBA::NameValuePairSeq;
    seq->length (_elements.size());
    CORBA::TypeCode_ptr tc = _type->unalias ();
    for (CORBA::ULong i = 0; i < _elements.size(); ++i) {
	(*seq)[i].id = tc->member_name (i);
	CORBA::Any_var a = _elements[i]->to_any ();
	(*seq)[i].value = a;
    }
    return seq;
}

void
CORBA::DynStruct::set_members (const CORBA::NameValuePairSeq& value)
{
    CORBA::TypeCode_ptr tc = _type->unalias ();
    if (value.length() != tc->member_count())
	mico_throw (InvalidSeq ());

    for (CORBA::ULong i = 0; i < value.length(); ++i) {
	if (strcmp (tc->member_name(i), value[i].id))
	    mico_throw (InvalidSeq ());
	// XXX throws Invalid() instead of InvalidSeq() ...
	_elements[i]->from_any (value[i].value);
    }
}


/************************* DynUnion *******************************/


CORBA::DynUnion::DynUnion (CORBA::TypeCode_ptr tc)
{
    _type = CORBA::TypeCode::_duplicate (tc);
    tc = tc->unalias ();
    if (tc->kind() != CORBA::tk_union)
	mico_throw (CORBA::ORB::InconsistentTypeCode ());

    CORBA::TypeCode_var disctc = tc->discriminator_type();
    _elements.push_back (_factory()->create_dyn_tc (disctc));
    CORBA::Any_var disc = _elements[0]->to_any ();
    _member_idx = tc->member_index (disc);
    if (_member_idx >= 0) {
	CORBA::TypeCode_var memtc = tc->member_type (_member_idx);
	_elements.push_back (_factory()->create_dyn_tc (memtc));
    } else {
	// XXX what to do for implicit default case ???
    }
}

CORBA::DynUnion::DynUnion (const CORBA::Any &a)
{
    _type = a.type();
    CORBA::TypeCode_ptr tc = _type->unalias ();
    if (tc->kind() != CORBA::tk_union)
	mico_throw (CORBA::ORB::InconsistentTypeCode ());

    CORBA::Boolean r = a.union_get_begin ();
    assert (r);
    CORBA::Any disc;
    r = a.any_get (disc);
    assert (r);
    _elements.push_back (_factory()->create_dyn_any (disc));
    _member_idx = tc->member_index (disc);
    if (_member_idx >= 0) {
	r = a.union_get_selection (_member_idx);
	assert (r);
	CORBA::Any el;
	r = a.any_get (el);
	assert (r);
	_elements.push_back (_factory()->create_dyn_any (el));
    } else {
	// XXX what to do for implicit default case ???
    }
    r = a.union_get_end ();
    assert (r);
}

CORBA::DynUnion::~DynUnion ()
{
}

const char *
CORBA::DynUnion::_repoid () const
{
    return "IDL:omg.org/CORBA/DynUnion:1.0";
}

#if 0
CORBA::DynUnion_ptr
CORBA::DynUnion::_nil ()
{
    return NULL;
}

CORBA::DynUnion_ptr
CORBA::DynUnion::_duplicate (DynUnion_ptr _obj)
{
    if( !CORBA::is_nil( _obj ) )
	_obj->_ref();
    return _obj;
}
#endif

CORBA::DynUnion_ptr
CORBA::DynUnion::_narrow (DynAny_ptr _obj)
{
    if (CORBA::is_nil (_obj))
	return _nil();
    if (!strcmp (_obj->_repoid(), "IDL:omg.org/CORBA/DynUnion:1.0"))
	return _duplicate ((DynUnion_ptr)_obj);
    return _nil();
}

void
CORBA::DynUnion::update_element (CORBA::Long idx)
{
    if (idx != 1)
	return;

    // XXX slow 
    CORBA::Any_var disc = _elements[0]->to_any ();
    CORBA::Long nidx = _type->unalias()->member_index (disc);
    if (nidx == _member_idx)
	return;

    if (_elements.size() == 2)
	_elements.pop_back ();
    if (nidx >= 0) {
	CORBA::TypeCode_var tc = _type->unalias()->member_type (nidx);
	_elements.push_back (_factory()->create_dyn_tc (tc));
    } else {
	// XXX what to do for implicit default case ???
    }
    _member_idx = nidx;

    if (_index >= (CORBA::Long)_elements.size())
	_index = _elements.size()-1;
}

void
CORBA::DynUnion::from_any (const CORBA::Any& value)
{
    CORBA::TypeCode_var tc = value.type();
    if (!_type->equaltype (tc))
	mico_throw (Invalid ());

    CORBA::Boolean r = value.union_get_begin ();
    assert (r);
    CORBA::Any disc;
    r = value.any_get (disc);
    assert (r);
    _elements[0]->from_any (disc);
    update_element (1);
    if (_member_idx >= 0) {
	r = value.union_get_selection (_member_idx);
	assert (r);
	CORBA::Any el;
	r = value.any_get (el);
	assert (r);
	_elements[1]->from_any (el);
    } else {
	// XXX what to do for implicit default case ???
    }
    r = value.union_get_end ();
    assert (r);
}

CORBA::Any*
CORBA::DynUnion::to_any ()
{
    if (set_as_default()) {
      set_as_default (TRUE);
    }

    CORBA::Any *a = new CORBA::Any;

    a->type (_type);
    CORBA::Boolean r = a->union_put_begin ();
    assert (r);
    CORBA::Any_var disc = _elements[0]->to_any ();
    r = a->any_put (disc);
    assert (r);
    CORBA::Long idx = _type->unalias()->member_index (disc);
    update_element (1);
    if (idx >= 0) {
	r = a->union_put_selection (idx);
	assert (r);
	CORBA::Any_var val = _elements[1]->to_any ();
	r = a->any_put (val);
	assert (r);
    }
    r = a->union_put_end ();
    assert (r);
    return a;
}

CORBA::Boolean
CORBA::DynUnion::set_as_default ()
{
    CORBA::Any_var disc = _elements[0]->to_any ();
    CORBA::Long idx = _type->unalias()->member_index (disc);
    return idx < 0 || idx == _type->unalias()->default_index();
}

void
CORBA::DynUnion::set_as_default (CORBA::Boolean value)
{
    CORBA::TypeCode_ptr tc = _type->unalias();
    CORBA::Long defidx = tc->default_index();

    if (value) {
	CORBA::TypeCode_var disc = tc->discriminator_type();
	disc = CORBA::TypeCode::_duplicate (disc->unalias());

	if (disc->kind() == CORBA::tk_enum) {
            CORBA::Any any;
            any.type (disc);
	    for (CORBA::ULong i = 0; i < disc->member_count(); ++i) {
		CORBA::Boolean r = any.enum_put (i);
		assert (r);
		if (tc->member_index (any) == defidx) {
		    _elements[0]->from_any (any);
		    return;
		}
	    }
	    // XXX what exception ???
	    assert (0);
	}
	if (disc->kind() == CORBA::tk_long) {
	    CORBA::Long l = 0;
            CORBA::Any any;
	    do {
		CORBA::Boolean r = (any <<= l);
		assert (r);
		if (tc->member_index (any) == defidx) {
		    _elements[0]->from_any (any);
		    return;
		}
	    } while (++l);
	    // XXX what exception ???
	    assert (0);
	}
	if (disc->kind() == CORBA::tk_longlong) {
	    CORBA::LongLong l = 0;
            CORBA::Any any;
	    do {
		CORBA::Boolean r = (any <<= l);
		assert (r);
		if (tc->member_index (any) == defidx) {
		    _elements[0]->from_any (any);
		    return;
		}
	    } while (++l);
	    // XXX what exception ???
	    assert (0);
	}
	if (disc->kind() == CORBA::tk_ulong) {
	    CORBA::ULong l = 0;
            CORBA::Any any;
	    do {
		CORBA::Boolean r = (any <<= l);
		assert (r);
		if (tc->member_index (any) == defidx) {
		    _elements[0]->from_any (any);
		    return;
		}
	    } while (++l);
	    // XXX what exception ???
	    assert (0);
	}
	if (disc->kind() == CORBA::tk_ulonglong) {
	    CORBA::ULongLong l = 0;
            CORBA::Any any;
	    do {
		CORBA::Boolean r = (any <<= l);
		assert (r);
		if (tc->member_index (any) == defidx) {
		    _elements[0]->from_any (any);
		    return;
		}
	    } while (++l);
	    // XXX what exception ???
	    assert (0);
	}
	if (disc->kind() == CORBA::tk_char) {
	    CORBA::Char l = 0;
            CORBA::Any any;
	    do {
		CORBA::Boolean r = (any <<= CORBA::Any::from_char (l));
		assert (r);
		if (tc->member_index (any) == defidx) {
		    _elements[0]->from_any (any);
		    return;
		}
	    } while (++l);
	    // XXX what exception ???
	    assert (0);
	}
	if (disc->kind() == CORBA::tk_wchar) {
	    CORBA::WChar l = 0;
            CORBA::Any any;
	    do {
		CORBA::Boolean r = (any <<= CORBA::Any::from_wchar (l));
		assert (r);
		if (tc->member_index (any) == defidx) {
		    _elements[0]->from_any (any);
		    return;
		}
	    } while (++l);
	    // XXX what exception ???
	    assert (0);
	}
	if (disc->kind() == CORBA::tk_short) {
	    CORBA::Short l = 0;
            CORBA::Any any;
	    do {
		CORBA::Boolean r = (any <<= l);
		assert (r);
		if (tc->member_index (any) == defidx) {
		    _elements[0]->from_any (any);
		    return;
		}
	    } while (++l);
	    // XXX what exception ???
	    assert (0);
	}
	if (disc->kind() == CORBA::tk_ushort) {
#if !defined(__GNUG__) && defined(__sgi)
	    volatile
#endif
	    CORBA::UShort l = 0;
            CORBA::Any any;
	    do {
		CORBA::Boolean r = (any <<= l);
		assert (r);
		if (tc->member_index (any) == defidx) {
		    _elements[0]->from_any (any);
		    return;
		}
	    } while (++l);
	    // XXX what exception ???
	    assert (0);
	}
	if (disc->kind() == CORBA::tk_boolean) {
	    CORBA::Any any;
	    CORBA::Boolean r = (any <<= CORBA::Any::from_boolean (TRUE));
	    assert (r);
	    if (tc->member_index (any) == defidx) {
		_elements[0]->from_any (any);
		return;
	    }
	    r = (any <<= CORBA::Any::from_boolean (FALSE));
	    assert (r);
	    if (tc->member_index (any) == defidx) {
		_elements[0]->from_any (any);
		return;
	    }
	    // XXX what exception ???
	    assert (0);
	}
    } else {
	for (CORBA::ULong i = 0; i < tc->member_count(); ++i) {
	    if (i != (CORBA::ULong)defidx) {
		CORBA::Any_var mem = tc->member_label (i);
		_elements[0]->from_any (mem);
		return;
	    }
	}
	// unreachable, since empty union not allowed
	assert (0);
    }
}

CORBA::FieldName
CORBA::DynUnion::member_name ()
{
    CORBA::Any_var disc = _elements[0]->to_any ();
    CORBA::Long idx = _type->unalias()->member_index (disc);
    if (idx < 0)
	return CORBA::string_dup ("");
    return CORBA::string_dup (_type->unalias()->member_name (idx));
}

void
CORBA::DynUnion::member_name (const CORBA::FieldName value)
{
    CORBA::TypeCode_ptr tc = _type->unalias();
    CORBA::Long idx = tc->member_index (value);
    assert (idx >= 0);
    if (idx == tc->default_index()) {
	set_as_default (TRUE);
    } else {
	CORBA::Any_var mem = tc->member_label(idx);
	_elements[0]->from_any (mem);
    }
}

CORBA::DynAny_ptr
CORBA::DynUnion::discriminator ()
{
    return CORBA::DynAny::_duplicate (_elements[0]);
}

CORBA::TCKind
CORBA::DynUnion::discriminator_kind ()
{
    // XXX unalias ???
    CORBA::TypeCode_var tc = _elements[0]->type();
    return tc->kind();
}

CORBA::DynAny_ptr
CORBA::DynUnion::member ()
{
    // XXX implicit default has no value ???
    update_element (1);
    return CORBA::DynAny::_duplicate (_elements[1]);
}

CORBA::TCKind
CORBA::DynUnion::member_kind ()
{
    // XXX unalias ???
    // XXX implicit default has no value ???
    update_element (1);
    CORBA::TypeCode_var tc = _elements[1]->type();
    return tc->kind();
}


/************************ DynSequence *****************************/


CORBA::DynSequence::DynSequence (CORBA::TypeCode_ptr tc)
{
    _type = CORBA::TypeCode::_duplicate (tc);
    tc = tc->unalias ();
    if (tc->kind() != CORBA::tk_sequence)
	mico_throw (CORBA::ORB::InconsistentTypeCode ());
    _length = 0;
}

CORBA::DynSequence::DynSequence (const CORBA::Any &a)
{
    _type = a.type ();
    CORBA::TypeCode_ptr tc = _type->unalias ();
    if (tc->kind() != CORBA::tk_sequence)
	mico_throw (CORBA::ORB::InconsistentTypeCode ());

    CORBA::Boolean r = a.seq_get_begin (_length);
    assert (r);
    for (CORBA::ULong i = 0; i < _length; ++i) {
	CORBA::Any el;
	r = a.any_get (el);
	assert (r);
	_elements.push_back (_factory()->create_dyn_any (el));
    }
    r = a.seq_get_end ();
    assert (r);
}

CORBA::DynSequence::~DynSequence ()
{
}

const char *
CORBA::DynSequence::_repoid () const
{
    return "IDL:omg.org/CORBA/DynSequence:1.0";
}

#if 0
CORBA::DynSequence_ptr
CORBA::DynSequence::_nil ()
{
    return NULL;
}

CORBA::DynSequence_ptr
CORBA::DynSequence::_duplicate (DynSequence_ptr _obj)
{
    if( !CORBA::is_nil( _obj ) )
	_obj->_ref();
    return _obj;
}
#endif

CORBA::DynSequence_ptr
CORBA::DynSequence::_narrow (DynAny_ptr _obj)
{
    if (CORBA::is_nil (_obj))
	return _nil();
    if (!strcmp (_obj->_repoid(), "IDL:omg.org/CORBA/DynSequence:1.0"))
	return _duplicate ((DynSequence_ptr)_obj);
    return _nil();
}

void
CORBA::DynSequence::from_any (const CORBA::Any& value)
{
    CORBA::TypeCode_var tc = value.type();
    if (!_type->equaltype (tc))
	mico_throw (Invalid ());

    CORBA::ULong len;
    CORBA::Boolean r = value.seq_get_begin (len);
    assert (r);
    if (len != _length)
	length (len);
    for (CORBA::ULong i = 0; i < _length; ++i) {
	CORBA::Any el;
	r = value.any_get (el);
	assert (r);
	_elements[i]->from_any (el);
    }
    r = value.seq_get_end ();
    assert (r);
}

CORBA::Any*
CORBA::DynSequence::to_any ()
{
    CORBA::Any *a = new CORBA::Any;

    a->type (_type);
    CORBA::Boolean r = a->seq_put_begin (_length);
    assert (r);
    for (CORBA::ULong i = 0; i < _elements.size(); ++i) {
	CORBA::Any_var el = _elements[i]->to_any();
	r = a->any_put (el);
	assert (r);
    }
    r = a->seq_put_end ();
    assert (r);
    return a;
}

CORBA::ULong
CORBA::DynSequence::length ()
{
    return _length;
}

void
CORBA::DynSequence::length (CORBA::ULong value)
{
    if (value < _elements.size ()) {
	_elements.erase (_elements.begin() + value, _elements.end());
	if (value == 0)
	    _index = 0;
	else if (_index >= (CORBA::Long)value)
	    _index = value-1;
    } else if (value > _elements.size()) {
	CORBA::TypeCode_var tc = _type->unalias()->content_type ();
	for (CORBA::ULong i = 0; i < value - _length; ++i)
	    _elements.push_back (_factory()->create_dyn_tc (tc));
    }
    _length = value;
}

CORBA::AnySeq*
CORBA::DynSequence::get_elements ()
{
    CORBA::AnySeq *seq = new CORBA::AnySeq;
    seq->length (_length);

    for (CORBA::ULong i = 0; i < _length; ++i) {
	CORBA::Any_var el = _elements[i]->to_any ();
	(*seq)[i] = el;
    }
    return seq;
}

void
CORBA::DynSequence::set_elements (const CORBA::AnySeq& value)
{
    if (value.length() != _length)
	mico_throw (InvalidSeq ());

    for (CORBA::ULong i = 0; i < _length; ++i) {
	_elements[i]->from_any (value[i]);
    }
}



/************************** DynArray *******************************/


CORBA::DynArray::DynArray (CORBA::TypeCode_ptr tc)
{
    _type = CORBA::TypeCode::_duplicate (tc);
    tc = tc->unalias();
    if (tc->kind() != CORBA::tk_array)
	mico_throw (CORBA::ORB::InconsistentTypeCode ());

    CORBA::ULong len = tc->length();
    CORBA::TypeCode_var eltc = tc->content_type();
    for (CORBA::ULong i = 0; i < len; ++i)
	_elements.push_back (_factory()->create_dyn_tc (eltc));
}

CORBA::DynArray::DynArray (const CORBA::Any &a)
{
    _type = a.type ();
    CORBA::TypeCode_ptr tc = _type->unalias();
    if (tc->kind() != CORBA::tk_array)
	mico_throw (CORBA::ORB::InconsistentTypeCode ());

    CORBA::ULong len = tc->length();
    CORBA::Boolean r = a.array_get_begin ();
    assert (r);
    for (CORBA::ULong i = 0; i < len; ++i) {
	CORBA::Any el;
	r = a.any_get (el);
	assert (r);
	_elements.push_back (_factory()->create_dyn_any (el));
    }
    r = a.array_get_end ();
    assert (r);
}

CORBA::DynArray::~DynArray ()
{
}

const char *
CORBA::DynArray::_repoid () const
{
    return "IDL:omg.org/CORBA/DynArray:1.0";
}

#if 0
CORBA::DynArray_ptr
CORBA::DynArray::_nil ()
{
    return NULL;
}

CORBA::DynArray_ptr
CORBA::DynArray::_duplicate (DynArray_ptr _obj)
{
    if( !CORBA::is_nil( _obj ) )
	_obj->_ref();
    return _obj;
}
#endif

CORBA::DynArray_ptr
CORBA::DynArray::_narrow (DynAny_ptr _obj)
{
    if (CORBA::is_nil (_obj))
	return _nil();
    if (!strcmp (_obj->_repoid(), "IDL:omg.org/CORBA/DynArray:1.0"))
	return _duplicate ((DynArray_ptr)_obj);
    return _nil();
}

void
CORBA::DynArray::from_any (const CORBA::Any& value)
{
    CORBA::TypeCode_var tc = value.type();
    if (!_type->equaltype (tc))
	mico_throw (Invalid ());

    CORBA::ULong len = tc->unalias()->length();
    CORBA::Boolean r = value.array_get_begin ();
    assert (r);
    for (CORBA::ULong i = 0; i < len; ++i) {
	CORBA::Any el;
	r = value.any_get (el);
	assert (r);
	_elements[i]->from_any (el);
    }
    r = value.array_get_end ();
    assert (r);
}

CORBA::Any*
CORBA::DynArray::to_any ()
{
    CORBA::Any *a = new CORBA::Any;

    a->type (_type);
    CORBA::Boolean r = a->array_put_begin ();
    assert (r);
    for (CORBA::ULong i = 0; i < _elements.size(); ++i) {
	CORBA::Any_var el = _elements[i]->to_any ();
	r = a->any_put (el);
	assert (r);
    }
    r = a->array_put_end ();
    assert (r);
    return a;
}

CORBA::AnySeq*
CORBA::DynArray::get_elements ()
{
    CORBA::AnySeq *seq = new CORBA::AnySeq;
    seq->length (_elements.size());

    for (CORBA::ULong i = 0; i < _elements.size(); ++i) {
	CORBA::Any_var el = _elements[i]->to_any ();
	(*seq)[i] = el;
    }
    return seq;
}

void
CORBA::DynArray::set_elements (const CORBA::AnySeq& value)
{
    if (value.length() != _elements.size())
	mico_throw (InvalidSeq ());

    for (CORBA::ULong i = 0; i < _elements.size(); ++i) {
	_elements[i]->from_any (value[i]);
    }
}


/************************* ORB ***************************/


CORBA::DynAny_ptr
CORBA::ORB::create_dyn_any (const CORBA::Any& value)
{
    CORBA::TypeCode_var tc = value.type();
    switch (tc->unalias()->kind()) {
    case CORBA::tk_void:
    case CORBA::tk_null:
    case CORBA::tk_char:
    case CORBA::tk_wchar:
    case CORBA::tk_boolean:
    case CORBA::tk_octet:
    case CORBA::tk_short:
    case CORBA::tk_ushort:
    case CORBA::tk_long:
    case CORBA::tk_longlong:
    case CORBA::tk_ulong:
    case CORBA::tk_ulonglong:
    case CORBA::tk_float:
    case CORBA::tk_double:
    case CORBA::tk_longdouble:
    case CORBA::tk_any:
    case CORBA::tk_TypeCode:
    case CORBA::tk_objref:
    case CORBA::tk_string:
    case CORBA::tk_wstring:
	return CORBA::DynBasic::_duplicate (new DynBasic (value));
    case CORBA::tk_enum:
	return CORBA::DynEnum::_duplicate (new DynEnum (value));
    case CORBA::tk_struct:
    case CORBA::tk_except:
	return CORBA::DynStruct::_duplicate (new DynStruct (value));
    case CORBA::tk_union:
	return CORBA::DynUnion::_duplicate (new DynUnion (value));
    case CORBA::tk_sequence:
	return CORBA::DynSequence::_duplicate (
	    new DynSequence (value));
    case CORBA::tk_array:
	return CORBA::DynArray::_duplicate (new DynArray (value));
    case CORBA::tk_fixed:
	return CORBA::DynFixed::_duplicate (new DynFixed (value));
    default:
	assert (0);
    }
    return 0;
}

CORBA::DynAny_ptr
CORBA::ORB::create_dyn_tc (CORBA::TypeCode_ptr type)
{
    switch (type->unalias()->kind()) {
    case CORBA::tk_void:
    case CORBA::tk_null:
    case CORBA::tk_char:
    case CORBA::tk_wchar:
    case CORBA::tk_boolean:
    case CORBA::tk_octet:
    case CORBA::tk_short:
    case CORBA::tk_ushort:
    case CORBA::tk_long:
    case CORBA::tk_longlong:
    case CORBA::tk_ulong:
    case CORBA::tk_ulonglong:
    case CORBA::tk_float:
    case CORBA::tk_double:
    case CORBA::tk_longdouble:
    case CORBA::tk_any:
    case CORBA::tk_TypeCode:
    case CORBA::tk_objref:
    case CORBA::tk_string:
    case CORBA::tk_wstring:
	return CORBA::DynBasic::_duplicate (new DynBasic (type));
    case CORBA::tk_enum:
	return CORBA::DynEnum::_duplicate (new DynEnum (type));
    case CORBA::tk_struct:
    case CORBA::tk_except:
	return CORBA::DynStruct::_duplicate (new DynStruct (type));
    case CORBA::tk_union:
	return CORBA::DynUnion::_duplicate (new DynUnion (type));
    case CORBA::tk_sequence:
	return CORBA::DynSequence::_duplicate (
	    new DynSequence (type));
    case CORBA::tk_array:
	return CORBA::DynArray::_duplicate (new DynArray (type));
    case CORBA::tk_fixed:
	return CORBA::DynFixed::_duplicate (new DynFixed (type));
    default:
	assert (0);
    }
    return 0;
}

CORBA::DynAny_ptr
CORBA::ORB::create_basic_dyn_any (CORBA::TypeCode_ptr type)
{
    return CORBA::DynAny::_duplicate (new DynBasic (type));
}

CORBA::DynStruct_ptr
CORBA::ORB::create_dyn_struct (CORBA::TypeCode_ptr type)
{
    return CORBA::DynStruct::_duplicate (new DynStruct (type));
}

CORBA::DynSequence_ptr
CORBA::ORB::create_dyn_sequence (CORBA::TypeCode_ptr type)
{
    return CORBA::DynSequence::_duplicate (new DynSequence (type));
}

CORBA::DynArray_ptr
CORBA::ORB::create_dyn_array (CORBA::TypeCode_ptr type)
{
    return CORBA::DynArray::_duplicate (new DynArray (type));
}

CORBA::DynUnion_ptr
CORBA::ORB::create_dyn_union (CORBA::TypeCode_ptr type)
{
    return CORBA::DynUnion::_duplicate (new DynUnion (type));
}

CORBA::DynEnum_ptr
CORBA::ORB::create_dyn_enum (CORBA::TypeCode_ptr type)
{
    return CORBA::DynEnum::_duplicate (new DynEnum (type));
}

CORBA::DynFixed_ptr
CORBA::ORB::create_dyn_fixed (CORBA::TypeCode_ptr type)
{
    return CORBA::DynFixed::_duplicate (new DynFixed (type));
}
