Previous Table of Contents Next


9.2 DynAny AP

   If the programmer wants to destroy a DynAny object but still wants to manipulate some component of the data value associated with it, then he or she should first create a DynAny for the component and, after that, make a copy of the created DynAny object.

   The behavior of DynAny objects has been defined in order to enable efficient implementations in terms of allocated memory space and speed of access. DynAny objects are intended to be used for traversing values extracted from anys or constructing values of anys at runtime. Their use for other purposes is not recommended.

   The DynAny API comprises the following IDL definitions, located in the DynamicAny module:

   // IDL// File: DynamicAny.idl#ifndef _DYNAMIC_ANY_IDL_#define _DYNAMIC_ANY_IDL_

   import ::CORBA;

   module DynamicAny { typeprefix DynamicAny “omg.org?;

   local interface DynAny {exception InvalidValue {};exception TypeMismatch {};

   CORBA::TypeCode type();

   void assign(in DynAny dyn_any) raises(TypeMismatch); void from_any(in any value) raises(TypeMismatch, InvalidValue); any to_any();

   boolean equal(in DynAny dyn_any);

   void destroy();DynAny copy();

   void insert_boolean(in boolean value)raises(TypeMismatch, InvalidValue);void insert_octet(in octet value)raises(TypeMismatch, InvalidValue);void insert_char(in char value)raises(TypeMismatch, InvalidValue);void insert_short(in short value)raises(TypeMismatch, InvalidValue);void insert_ushort(in unsigned short value)

   raises(TypeMismatch, InvalidValue); void insert_long(in long value)

   raises(TypeMismatch, InvalidValue); void insert_ulong(in unsigned long value) raises(TypeMismatch, InvalidValue);

   void insert_float(in float value) raises(TypeMismatch, InvalidValue); void insert_double(in double value) raises(TypeMismatch, InvalidValue); void insert_string(in string value) raises(TypeMismatch, InvalidValue); void insert_reference(in Object value) raises(TypeMismatch, InvalidValue); void insert_typecode(in CORBA::TypeCode value) raises(TypeMismatch, InvalidValue); void insert_longlong(in long long value) raises(TypeMismatch, InvalidValue); void insert_ulonglong(in unsigned long long value)

   raises(TypeMismatch, InvalidValue);void insert_longdouble(in long double value)raises(TypeMismatch, InvalidValue);

   void insert_wchar(in wchar value) raises(TypeMismatch, InvalidValue); void insert_wstring(in wstring value) raises(TypeMismatch, InvalidValue); void insert_any(in any value) raises(TypeMismatch, InvalidValue); void insert_dyn_any(in DynAny value) raises(TypeMismatch, InvalidValue); void insert_val(in ValueBase value) raises(TypeMismatch, InvalidValue);

   boolean get_boolean() raises(TypeMismatch, InvalidValue); octet get_octet() raises(TypeMismatch, InvalidValue); char get_char() raises(TypeMismatch, InvalidValue); short get_short() raises(TypeMismatch, InvalidValue); unsigned short get_ushort() raises(TypeMismatch, InvalidValue); long get_long() raises(TypeMismatch, InvalidValue); unsigned long get_ulong() raises(TypeMismatch, InvalidValue); float get_float() raises(TypeMismatch, InvalidValue); double get_double() raises(TypeMismatch, InvalidValue); string get_string()

   raises(TypeMismatch, InvalidValue);

   Object get_reference() raises(TypeMismatch, InvalidValue);

   CORBA::TypeCode get_typecode() raises(TypeMismatch, InvalidValue);

   long long get_longlong() raises(TypeMismatch, InvalidValue);

   unsigned long long get_ulonglong() raises(TypeMismatch, InvalidValue);

   long double get_longdouble() raises(TypeMismatch, InvalidValue);

   wchar get_wchar() raises(TypeMismatch, InvalidValue);

   wstring get_wstring() raises(TypeMismatch, InvalidValue);

   any get_any() raises(TypeMismatch, InvalidValue);

   DynAny get_dyn_any() raises(TypeMismatch, InvalidValue);

   ValueBase get_val() raises(TypeMismatch, InvalidValue);

   boolean seek(in long index);void rewind();boolean next();unsigned long component_count();DynAny current_component() raises(TypeMismatch);

   void insert_abstract(in CORBA::AbstractBase value) raises(TypeMismatch, InvalidValue);

   CORBA::AbstractBase get_abstract() raises(TypeMismatch, InvalidValue);

   void insert_boolean_seq(in CORBA::BooleanSeq value) raises(TypeMismatch, InvalidValue);

   void insert_octet_seq(in CORBA::OctetSeq value) raises(TypeMismatch, InvalidValue);

   void insert_char_seq(in CORBA::CharSeq value) raises(TypeMismatch, InvalidValue);

   void insert_short_seq(in CORBA::ShortSeq value) raises(TypeMismatch, InvalidValue);

   void insert_ushort_seq(in CORBA::UShortSeq value) raises(TypeMismatch, InvalidValue);

   void insert_long_seq(in CORBA::LongSeq value) raises(TypeMismatch, InvalidValue);

   void insert_ulong_seq(in CORBA::ULongSeq value) raises(TypeMismatch, InvalidValue);

   void insert_float_seq(in CORBA::FloatSeq value) raises(TypeMismatch, InvalidValue);

   void insert_double_seq(in CORBA::DoubleSeq value) raises(TypeMismatch, InvalidValue);

   void insert_longlong_seq(in CORBA::LongLongSeq value) raises(TypeMismatch, InvalidValue); void insert_ulonglong_seq(in CORBA::ULongLongSeq value) raises(TypeMismatch, InvalidValue); void insert_longdouble_seq(in CORBA::LongDoubleSeq value) raises(TypeMismatch, InvalidValue); void insert_wchar_seq(in CORBA::WCharSeq value) raises(TypeMismatch, InvalidValue);

   CORBA::BooleanSeq get_boolean_seq() raises(TypeMismatch, InvalidValue);CORBA::OctetSeq get_octet_seq() raises(TypeMismatch, InvalidValue);CORBA::CharSeq get_char_seq() raises(TypeMismatch, InvalidValue);CORBA::ShortSeq get_short_seq() raises(TypeMismatch, InvalidValue);CORBA::UShortSeq get_ushort_seq() raises(TypeMismatch, InvalidValue);CORBA::LongSeq get_long_seq()raises(TypeMismatch, InvalidValue);CORBA::ULongSeq get_ulong_seq() raises(TypeMismatch, InvalidValue);CORBA::FloatSeq get_float_seq() raises(TypeMismatch, InvalidValue);CORBA::DoubleSeq get_double_seq()

   raises(TypeMismatch, InvalidValue);CORBA::LongLongSeq get_longlong_seq() raises(TypeMismatch, InvalidValue);

   CORBA::ULongLongSeq get_ulonglong_seq() raises(TypeMismatch, InvalidValue); CORBA::LongDoubleSeq get_longdouble_seq() raises(TypeMismatch, InvalidValue); CORBA::WCharSeq get_wchar_seq() raises(TypeMismatch, InvalidValue); };

   local interface DynFixed : DynAny { string get_value(); boolean set_value(in string val) raises(TypeMismatch, InvalidValue);

   };

   local interface DynEnum : DynAny { string get_as_string(); void set_as_string(in string value) raises(InvalidValue); unsigned long get_as_ulong(); void set_as_ulong(in unsigned long value) raises(InvalidValue);

   };

   typedef string FieldName;

   struct NameValuePair { FieldName id; any value;

   };

   typedef sequence<NameValuePair> NameValuePairSeq;

   struct NameDynAnyPair { FieldName id; DynAny value;

   };

   typedef sequence<NameDynAnyPair> NameDynAnyPairSeq;

   local interface DynStruct : DynAny { FieldName current_member_name() raises(TypeMismatch, InvalidValue); CORBA::TCKind current_member_kind()

   raises(TypeMismatch, InvalidValue);NameValuePairSeq get_members();void set_members(in NameValuePairSeq value)

   raises(TypeMismatch, InvalidValue); NameDynAnyPairSeq get_members_as_dyn_any(); void set_members_as_dyn_any(in NameDynAnyPairSeq value)

   raises(TypeMismatch, InvalidValue); };

   local interface DynUnion : DynAny { DynAny get_discriminator(); void set_discriminator(in DynAny d) raises(TypeMismatch); void set_to_default_member() raises(TypeMismatch); void set_to_no_active_member() raises(TypeMismatch); boolean has_no_active_member(); CORBA::TCKind discriminator_kind(); DynAny member() raises(InvalidValue); FieldName member_name() raises(InvalidValue); CORBA::TCKind member_kind() raises(InvalidValue);

   };

   typedef sequence<any> AnySeq; typedef sequence<DynAny> DynAnySeq;

   local interface DynSequence : DynAny { unsigned long get_length(); void set_length(in unsigned long len) raises(InvalidValue); AnySeq get_elements(); void set_elements(in AnySeq value)

   raises(TypeMismatch, InvalidValue);DynAnySeq get_elements_as_dyn_any();void set_elements_as_dyn_any(in DynAnySeq value)

   raises(TypeMismatch, InvalidValue); };

   local interface DynArray : DynAny { AnySeq get_elements(); void set_elements(in AnySeq value)

   raises(TypeMismatch, InvalidValue);DynAnySeq get_elements_as_dyn_any();void set_elements_as_dyn_any(in DynAnySeq value)

   raises(TypeMismatch, InvalidValue); };

   local interface DynValueCommon : DynAny { boolean is_null(); void set_to_null(); void set_to_value();

   };

   local interface DynValue : DynValueCommon { FieldName current_member_name() raises(TypeMismatch, InvalidValue); CORBA::TCKind current_member_kind() raises(TypeMismatch, InvalidValue); NameValuePairSeq get_members() raises(InvalidValue); void set_members(in NameValuePairSeq value) raises(TypeMismatch, InvalidValue); NameDynAnyPairSeq get_members_as_dyn_any()

   raises(InvalidValue); void set_members_as_dyn_any(in NameDynAnyPairSeq value) raises(TypeMismatch, InvalidValue);

   };

   local interface DynValueBox : DynValueCommon { any get_boxed_value() raises(InvalidValue); void set_boxed_value(in any boxed) raises(TypeMismatch, InvalidValue); DynAny get_boxed_value_as_dyn_any() raises(InvalidValue); void set_boxed_value_as_dyn_any(in DynAny boxed) raises(TypeMismatch); };

   exception MustTruncate { };

   local interface DynAnyFactory { exception InconsistentTypeCode {}; DynAny create_dyn_any(in any value)

   raises(InconsistentTypeCode); DynAny create_dyn_any_from_type_code(in CORBA::TypeCode type)

   raises(InconsistentTypeCode);

   DynAny create_dyn_any_without_truncation(in any value) raises(InconsistentTypeCode, MustTruncate);

   DynAnySeq create_multiple_dyn_anys( in AnySeq values, in boolean allow_truncate) raises(InconsistentTypeCode, MustTruncate);

   AnySeq create_multiple_anys(in DynAnySeq values); }; }; // module DynamicAny

   #endif // _DYNAMIC_ANY_IDL_

   9.2.1 Creating a DynAny Object

   A DynAny object can be created as a result of:

   A constructed DynAny object supports operations that enable the creation of new DynAny objects encapsulating access to the value of some constituent. DynAny objects also support the copy operation for creating new DynAny objects.

   In addition, DynAny objects can be created by invoking operations on the DynAnyFactory object. A reference to the DynAnyFactory object is obtained by calling CORBA::ORB::resolve_initial_references with the identifier parameter set to “DynAnyFactory?.

   local interface DynAnyFactory {exception InconsistentTypeCode {};DynAny create_dyn_any(in any value)

   raises(InconsistentTypeCode); DynAny create_dyn_any_from_type_code(in CORBA::TypeCode type) raises(InconsistentTypeCode); };

   The create_dyn_any operation creates a new DynAny object from an any value. A copy of the TypeCode associated with the any value is assigned to the resulting DynAny object. The value associated with the DynAny object is a copy of the value in the original any. The create_dyn_any operation sets the current position of the created DynAny to zero if the passed value has components; otherwise, the current position is set to −1. The operation raises InconsistentTypeCode if value has a TypeCode with a TCKind of tk_Principal or tk_native.

   The create_dyn_any_from_type_code operation creates a DynAny from a TypeCode. Depending on the TypeCode, the created object may be of type DynAny, or one of its derived types, such as DynStruct. The returned reference can be narrowed to the derived type.

   For both create_dyn_any and create_dyn_any_from_type_code, the source type code is copied into the DynAny object unchanged. This means that, after creation of a DynAny object, the source type code and the type code inside the DynAny must compare equal as determined by TypeCode::equal. The same is true for type codes extracted from a DynAny with the type operation and for type codes that are part of any values that are constructed from a DynAny: such type codes compare equal to to the type code that was originally used to create the DynAny. For a given parent DynAny with its associated TypeCode, the TypeCode of a component DynAny also compares equal to the corresponding results of the member_type or component_type operation on the parent TypeCode.

   The create_dyn_any_without_truncation operation has the same semantics as create_dyn_any, but will raise the MustTruncate exception if it cannot avoid truncating a valuetype.

   The create_multiple_dyn_anys operation converts a sequence of anys into a sequence of DynAnys, ensuring that each reference to a valuetype instance is converted consistently to the same DynValue or DynValueBox instance. If the allow_truncate parameter is false, the operation will raise the MustTruncate exception if it cannot avoid truncating a valuetype.

   The create_multiple_anys operation converts a sequence of DynAnys into a sequence of anys, ensuring that each DynValue or DynValueBox instance is consistently converted to the same valuetype instance.

   Creation of DynAnys with TCKind tk_null and tk_void is legal and results in the creation of a DynAny without a value and with zero components.

   In all cases, a DynAny constructed from a TypeCode has an initial default value. The default values of basic types are:

   For complex types, creation of the corresponding DynAny assigns a default value as follows:

   Dynamic interpretation of an any usually involves creating a DynAny object using DynAnyFactory::create_dyn_any as the first step. Depending on the type of the any, the resulting DynAny object reference can be narrowed to a DynFixed, DynStruct, DynSequence, DynArray, DynUnion, DynEnum, or DynValue object reference.

   Dynamic creation of an any involves creating a DynAny object using DynAnyFactory::create_dyn_any_from_type_code, passing the TypeCode associated with the value to be created. The returned reference is narrowed to one of the complex types, such as DynStruct, if appropriate. Then, the value can be initialized by means of invoking operations on the resulting object. Finally, the to_any operation can be invoked to create an any value from the constructed DynAny.

   9.2.2 The DynAny Interface

   The following operations can be applied to a DynAny object:

   9.2.2.1 Obtaining the TypeCode associated with a DynAny object

   CORBA::TypeCode type();

   A DynAny object is created with a TypeCode value assigned to it. This TypeCode value determines the type of the value handled through the DynAny object. The type operation returns the TypeCode associated with a DynAny object.

   Note that the TypeCode associated with a DynAny object is initialized at the time the DynAny is created and cannot be changed during lifetime of the DynAny object.

   9.2.2.2 Initializing a DynAny object from another DynAny object

   void assign(in DynAny dyn_any) raises(TypeMismatch);

   The assign operation initializes the value associated with a DynAny object with the value associated with another DynAny object.

   If the type of the passed DynAny is not equivalent to the type of target DynAny, the operation raises TypeMismatch. The current position of the target DynAny is set to zero for values that have components and to −1 for values that do not have components.

   9.2.2.3 Initializing a DynAny object from an any value

   void from_any(in any value) raises(TypeMismatch, InvalidValue);

   The from_any operation initializes the value associated with a DynAny object with the value contained in an any.

   If the type of the passed Any is not equivalent to the type of target DynAny, the operation raises TypeMismatch. If the passed Any does not contain a legal value (such as a null string), the operation raises InvalidValue. The current position of the target DynAny is set to zero for values that have components and to −1 for values that do not have components.

   9.2.2.4 Generating an any value from a DynAny object

   any to_any();

   The to_any operation creates an any value from a DynAny object. A copy of the TypeCode associated with the DynAny object is assigned to the resulting any. The value associated with the DynAny object is copied into the any.

   9.2.2.5 Comparing DynAny values

   boolean equal(in DynAny dyn_any);

   The equal operation compares two DynAny references for equality and returns true if the DynAnys are equal, false otherwise. For DynAny references that are not derived from DynValueCommon, they are equal if their TypeCodes are equivalent and, recursively, all component DynAnys are equal. For DynAny references that are derived from DynValueCommon, they are equal only if they are exactly the same reference. The current position of the two DynAnys being compared has no effect on the result of equal. To determine equality of object references, the equal operation uses Object::is_equivalent. To determine equality of type codes, the equal operation uses TypeCode::equivalent.

   Note – If two DynAnys happen to contain *values* of type TypeCode, these values are compared using TypeCode::equal. The type codes that *describe* the values of DynAnys are always compared using TypeCode::equivalent, however. (In the case of comparing two DynAnys containing type code values, the type codes describing these type code values are tk_TypeCode in each DynAny, and will therefore always compare as equivalent.)

   9.2.2.6 Destroying a DynAny object

   void destroy();

   The destroy operation destroys a DynAny object. This operation frees any resources used to represent the data value associated with a DynAny object. destroy must be invoked on references obtained from one of the creation operations on the DynAnyFactory interface or on a reference returned by DynAny::copy to avoid resource leaks. Invoking destroy on component DynAny objects (for example, on objects returned by the current_component operation) does nothing.

   Destruction of a DynAny object implies destruction of all DynAny objects obtained from it. That is, references to components of a destroyed DynAny become invalid; invocations on such references raise OBJECT_NOT_EXIST.

   It is possible to manipulate a component of a DynAny beyond the life time of the DynAny from which the component was obtained by making a copy of the component with the copy operation before destroying the DynAny from which the component was obtained.

   9.2.2.7 Creating a copy of a DynAny object

   DynAny copy();

   The copy operation creates a new DynAny object whose value is a deep copy of the DynAny on which it is invoked. The operation is polymorphic, that is, invoking it on one of the types derived from DynAny, such as DynStruct, creates the derived type but returns its reference as the DynAny base type.

   9.2.2.8 Accessing a value of some basic type in a DynAny object

   The insert and get operations enable insertion/extraction of basic data type values into/from a DynAny object.

   Both bounded and unbounded strings are inserted using insert_string and insert_wstring. These operations raise the InvalidValue exception if the string inserted is longer than the bound of a bounded string.

   Calling an insert or get operation on a DynAny that has components but has a current position of −1 raises InvalidValue.

   Get operations raise TypeMismatch if the accessed component in the DynAny is of a type that is not equivalent to the requested type. (Note that get_string and get_wstring are used for both unbounded and bounded strings.)

   A type is consistent for inserting or extracting a value if its TypeCode is equivalent to the TypeCode contained in the DynAny or, if the DynAny has components, is equivalent to the TypeCode of the DynAny at the current position.

   The get_dyn_any and insert_dyn_any operations are provided to deal with any values that contain another any. The operations behave identically to get_any and insert_any, but use parameters of type DynAny (instead of any); they are useful to avoid otherwise redundant conversions between any and DynAny.

   Calling an insert or get operation leaves the current position unchanged.

   These operations are necessary to handle basic DynAny objects but are also helpful to handle constructed DynAny objects. Inserting a basic data type value into a constructed DynAny object implies initializing the current component of the constructed data value associated with the DynAny object. For example, invoking insert_boolean on a DynStruct implies inserting a boolean data value at the current position of the associated struct data value. If dyn_construct points to a constructed DynAny object, then:

   result = dyn_construct->get_boolean();

   has the same effect as:

   DynamicAny::DynAny_var temp = dyn_construct->current_component();result = temp->get_boolean();

   Calling an insert or get operation on a DynAny whose current component itself has components raises TypeMismatch.

   In addition, availability of these operations enable the traversal of anys associated with sequences of basic data types without the need to generate a DynAny object for each element in the sequence.

   In the same way that basic types are inserted/extracted from a DynAny object, arrays or sequences of basic types can be inserted/extracted from a DynAny. For example, the get_boolean_seq operation extracts a sequence of booleans from a DynAny that contains either a sequence or an array of booleans, and the insert_boolean_seq operation stores the sequence back into the DynAny.

   The TypeCode of the DynAny, or the TypeCode of the component at the current position of the DynAny, must be equivalent to a sequence or array TypeCode with the basic type as its element, otherwise the operations raise TypeMismatch. For the insert operations, if the length of the sequence is incompatible with a bounded sequence or array represented by the DynAny, then the operations raise InvalidValue.

   9.2.2.9 Iterating through components of a DynAny

   The DynAny interface allows a client to iterate through the components of the values pointed to by DynStruct, DynSequence, DynArray, DynUnion, DynAny, and DynValue objects.

   As mentioned previously, a DynAny object may be seen as an ordered collection of components, together with a current position.

   boolean seek(in long index);

   The seek operation sets the current position to index. The current position is indexed 0 to n−1, that is, index zero corresponds to the first component. The operation returns true if the resulting current position indicates a component of the DynAny and false if index indicates a position that does not correspond to a component.

   Calling seek with a negative index is legal. It sets the current position to −1 to indicate no component and returns false. Passing a non-negative index value for a DynAny that does not have a component at the corresponding position sets the current position to −1 and returns false.

   void rewind();

   The rewind operation is equivalent to calling seek(0);

   boolean next();

   The next operation advances the current position to the next component. The operation returns true while the resulting current position indicates a component, false otherwise. A false return value leaves the current position at −1. Invoking next on a DynAny without components leaves the current position at −1 and returns false.

   unsigned long component_count();

   The component_count operation returns the number of components of a DynAny. For a DynAny without components, it returns zero. The operation only counts the components at the top level. For example, if component_count is invoked on a DynStruct with a single member, the return value is 1, irrespective of the type of the member.

   For sequences, the operation returns the current number of elements. For structures, exceptions, and valuetypes, the operation returns the number of members. For arrays, the operation returns the number of elements. For unions, the operation returns 2 if the discriminator indicates that a named member is active; otherwise, it returns 1. For DynFixed and DynEnum, the operation returns zero.

   DynAny current_component() raises(TypeMismatch);

   The current_component operation returns the DynAny for the component at the current position. It does not advance the current position, so repeated calls to current_component without an intervening call to rewind, next, or seek return the same component.

   The returned DynAny object reference can be used to get/set the value of the current component. If the current component represents a complex type, the returned reference can be narrowed based on the TypeCode to get the interface corresponding to the to the complex type.

   Calling current_component on a DynAny that cannot have components, such as a DynEnum or an empty exception, raises TypeMismatch. Calling current_component on a DynAny whose current position is −1 returns a nil reference.

   The iteration operations, together with current_component, can be used to dynamically compose an any value. After creating a dynamic any, such as a DynStruct, current_component and next can be used to initialize all the components of the value. Once the dynamic value is completely initialized, to_any creates the corresponding any value.

   9.2.3 The DynFixed Interface

   DynFixed objects are associated with values of the IDL fixed type.

   local interface DynFixed : DynAny {string get_value();boolean set_value(in string val)

   raises (TypeMismatch, InvalidValue);};

   Because IDL does not have a generic type that can represent fixed types with arbitrary number of digits and arbitrary scale, the operations use the IDL string type.

   The get_value operation returns the value of a DynFixed.

   The set_value operation sets the value of the DynFixed. The val string must contain a fixed string constant in the same format as used for IDL fixed-point literals. However, the trailing d or D is optional. If val has more fractional digits than specified by the scale of the DynFixed, the extra digits are truncated. If the truncated value has more digits than the DynFixed, the operation raises InvalidValue. If the value is not too large, set_value returns TRUE if no truncation was required, FALSE otherwise. The return value is TRUE if val can be represented as the DynFixed without loss of precision. If val has more fractional digits than can be represented in the DynFixed, fractional digits are truncated and the return value is FALSE. If val does not contain a valid fixed-point literal or contains extraneous characters other than leading or trailing white space, the operation raises TypeMismatch.

   9.2.4 The DynEnum Interface

   DynEnum objects are associated with enumerated values.

   local interface DynEnum : DynAny { string get_as_string(); void set_as_string(in string value) raises(InvalidValue);

   unsigned long get_as_ulong(); void set_as_ulong(in unsigned long value) raises(InvalidValue); };

   The get_as_string operation returns the value of the DynEnum as an IDL identifier.

   The set_as_string operation sets the value of the DynEnum to the enumerated value whose IDL identifier is passed in the value parameter. If value contains a string that is not a valid IDL identifier for the corresponding enumerated type, the operation raises InvalidValue.

   The get_as_ulong operation returns the value of the DynEnum as the enumerated value’s ordinal value. Enumerators have ordinal values 0 to n−1, as they appear from left to right in the corresponding IDL definition.

   The set_as_ulong operation sets the value of the DynEnum as the enumerated value’s ordinal value. If value contains a value that is outside the range of ordinal values for the corresponding enumerated type, the operation raises InvalidValue.

   The current position of a DynEnum is always −1.

   9.2.5 The DynStruct Interface

   DynStruct objects are associated with struct values and exception values.

   typedef string FieldName;

   struct NameValuePair {FieldName id;any value;

   };typedef sequence<NameValuePair> NameValuePairSeq;

   struct NameDynAnyPair {FieldName id;DynAny value;

   };typedef sequence<NameDynAnyPair> NameDynAnyPairSeq;

   local interface DynStruct : DynAny {FieldName current_member_name()raises(TypeMismatch, InvalidValue);CORBA::TCKind current_member_kind()

   raises(TypeMismatch, InvalidValue); NameValuePairSeq get_members(); void set_members(in NameValuePairSeq value)

   raises(TypeMismatch, InvalidValue); NameDynAnyPairSeq get_members_as_dyn_any(); void set_members_as_dyn_any(in NameDynAnyPairSeq value)

   raises(TypeMismatch, InvalidValue);};

   FieldName current_member_name()raises(TypeMismatch, InvalidValue);

   The current_member_name operation returns the name of the member at the current position. If the DynStruct represents an empty exception, the operation raises TypeMismatch. If the current position does not indicate a member, the operation raises InvalidValue.

   This operation may return an empty string since the TypeCode of the value being manipulated may not contain the names of members.

   CORBA::TCKind current_member_kind()raises(TypeMismatch, InvalidValue);

   current_member_kind returns the TCKind associated with the member at the current position. If the DynStruct represents an empty exception, the operation raises TypeMismatch. If the current position does not indicate a member, the operation raises InvalidValue.

   NameValuePairSeq get_members();

   The get_members operation returns a sequence of name/value pairs describing the name and the value of each member in the struct associated with a DynStruct object. The sequence contains members in the same order as the declaration order of members as indicated by the DynStruct’s TypeCode. The current position is not affected. The member names in the returned sequence will be empty strings if the DynStruct’s TypeCode does not contain member names.

   void set_members(in NameValuePairSeq value)raises(TypeMismatch, InvalidValue);

   The set_members operation initializes the struct data value associated with a DynStruct object from a sequence of name value pairs. The operation sets the current position to zero if the passed sequences has non-zero length; otherwise, if an empty sequence is passed, the current position is set to −1.

   Members must appear in the NameValuePairSeq in the order in which they appear in the IDL specification of the struct. If one or more sequence elements have a type that is not equivalent to the TypeCode of the corresponding member, the operation raises TypeMismatch. If the passed sequence has a number of elements that disagrees with the number of members as indicated by the DynStruct’s TypeCode, the operation raises InvalidValue.

   If member names are supplied in the passed sequence, they must either match the corresponding member name in the DynStruct’s TypeCode or must be empty strings, otherwise, the operation raises TypeMismatch. Members must be supplied in the same order as indicated by the DynStruct’s TypeCode. (The operation makes no attempt to assign member values based on member names.)

   The get_members_as_dyn_any and set_members_as_dyn_any operations have the same semantics as their Any counterparts, but accept and return values of type DynAny instead of Any.

   DynStruct objects can also be used for handling exception values. In that case, members of the exceptions are handled in the same way as members of a struct.

   9.2.6 The DynUnion Interface

   DynUnion objects are associated with unions.

   local interface DynUnion : DynAny {DynAny get_discriminator();void set_discriminator(in DynAny d)

   raises(TypeMismatch);void set_to_default_member()raises(TypeMismatch);

   void set_to_no_active_member() raises(TypeMismatch); boolean has_no_active_member()

   raises(InvalidValue); CORBA::TCKind discriminator_kind(); DynAny member()

   raises(InvalidValue);FieldName member_name()raises(InvalidValue);

   CORBA::TCKind member_kind() raises(InvalidValue);boolean is_set_to_default_member();};

   The DynUnion interface allows for the insertion/extraction of an OMG IDL union type into/from a DynUnion object.

   A union can have only two valid current positions: zero, which denotes the discriminator, and one, which denotes the active member. The component_count value for a union depends on the current discriminator: it is 2 for a union whose discriminator indicates a named member, and 1 otherwise.

   DynAny get_discriminator()

   The get_discriminator operation returns the current discriminator value of the DynUnion.

   void set_discriminator(in DynAny d) raises(TypeMismatch);

   The set_discriminator operation sets the discriminator of the DynUnion to the specified value. If the TypeCode of the d parameter is not equivalent to the TypeCode of the union’s discriminator, the operation raises TypeMismatch.

   Setting the discriminator to a value that is consistent with the currently active union member does not affect the currently active member. Setting the discriminator to a value that is inconsistent with the currently active member deactivates the member and activates the member that is consistent with the new discriminator value (if there is a member for that value) by initializing the member to its default value.

   Setting the discriminator of a union sets the current position to 0 if the discriminator value indicates a non-existent union member (has_no_active_member returns true in this case). Otherwise, if the discriminator value indicates a named union member, the current position is set to 1 (has_no_active_member returns false and component_count returns 2 in this case).

   void set_to_default_member()raises(TypeMismatch);

   The set_to_default_member operation sets the discriminator to a value that is consistent with the value of the default case of a union; it sets the current position to zero and causes component_count to return 2. Calling set_to_default_member on a union that does not have an explicit default case raises TypeMismatch.

   void set_to_no_active_member()raises(TypeMismatch);

   The set_to_no_active_member operation sets the discriminator to a value that does not correspond to any of the union’s case labels; it sets the current position to zero and causes component_count to return 1. Calling set_to_no_active_member on a union that has an explicit default case or on a union that uses the entire range of discriminator values for explicit case labels raises TypeMismatch.

   boolean has_no_active_member();

   The has_no_active_member operation returns true if the union has no active member (that is, the union’s value consists solely of its discriminator because the discriminator has a value that is not listed as an explicit case label). Calling this operation on a union that has a default case returns false. Calling this operation on a union that uses the entire range of discriminator values for explicit case labels returns false.

   CORBA::TCKind discriminator_kind();

   The discriminator_kind operation returns the TCKind value of the discriminator’s TypeCode.

   CORBA::TCKind member_kind()raises(InvalidValue);

   The member_kind operation returns the TCKind value of the currently active member’s TypeCode. Calling this operation on a union that does not have a currently active member raises InvalidValue.

   DynAny member()raises(InvalidValue);

   The member operation returns the currently active member. If the union has no active member, the operation raises InvalidValue. Note that the returned reference remains valid only for as long as the currently active member does not change. Using the returned reference beyond the life time of the currently active member raises OBJECT_NOT_EXIST.

   FieldName member_name()raises(InvalidValue);

   The member_name operation returns the name of the currently active member. If the union’s TypeCode does not contain a member name for the currently active member, the operation returns an empty string. Calling member_name on a union without an active member raises InvalidValue.

   boolean is_set_to_default_member();

   The is_set_to_default_member operation returns TRUE if a union has an explicit default label and the discriminator value does not match any of the union's other case labels.

   9.2.7 The DynSequence Interface

   DynSequence objects are associated with sequences.

   typedef sequence<any> AnySeq;typedef sequence<DynAny> DynAnySeq;

   local interface DynSequence : DynAny {unsigned long get_length();void set_length(in unsigned long len)

   raises(InvalidValue); AnySeq get_elements(); void set_elements(in AnySeq value)

   raises(TypeMismatch, InvalidValue); DynAnySeq get_elements_as_dyn_any(); void set_elements_as_dyn_any(in DynAnySeq value)

   raises(TypeMismatch, InvalidValue);};

   unsigned long get_length();

   The get_length operation returns the current length of the sequence.

   void set_length(in unsigned long len) raises(InvalidValue);

   The set_length operation sets the length of the sequence. Increasing the length of a sequence adds new elements at the tail without affecting the values of already existing elements. Newly added elements are default-initialized.

   Increasing the length of a sequence sets the current position to the first newly-added element if the previous current position was −1. Otherwise, if the previous current position was not −1, the current position is not affected.

   Increasing the length of a bounded sequence to a value larger than the bound raises InvalidValue.

   Decreasing the length of a sequence removes elements from the tail without affecting the value of those elements that remain. The new current position after decreasing the length of a sequence is determined as follows:

   DynAnySeq get_elements();

   The get_elements operation returns the elements of the sequence.

   void set_elements(in AnySeq value) raises(TypeMismatch, InvalidValue);

   The set_elements operation sets the elements of a sequence. The length of the DynSequence is set to the length of value. The current position is set to zero if value has non-zero length and to −1 if value is a zero-length sequence.

   If value contains one or more elements whose TypeCode is not equivalent to the element TypeCode of the DynSequence, the operation raises TypeMismatch. If the length of value exceeds the bound of a bounded sequence, the operation raises InvalidValue.

   The get_elements_as_dyn_any and set_elements_as_dyn_any operations have the same semantics, but accept and return values of type DynAny instead of Any.

   9.2.8 The DynArray Interface

   DynArray objects are associated with arrays.

   local interface DynArray : DynAny {AnySeq get_elements();void set_elements(in AnySeq value)

   raises(TypeMismatch, InvalidValue); DynAnySeq get_elements_as_dyn_any(); void set_elements_as_dyn_any(in DynAnySeq value)

   raises(TypeMismatch, InvalidValue);};

   DynAnySeq get_elements();

   The get_elements operation returns the elements of the DynArray.

   void set_elements(in DynAnySeq value) raises(TypeMismatch, InvalidValue);

   The set_elements operation sets the DynArray to contain the passed elements. If the sequence does not contain the same number of elements as the array dimension, the operation raises InvalidValue. If one or more elements have a type that is inconsistent with the DynArray’s TypeCode, the operation raises TypeMismatch.

   The get_elements_as_dyn_any and set_elements_as_dyn_any operations have the same semantics as their Any counterparts, but accept and return values of type DynAny instead of Any.

   Note that the dimension of the array is contained in the TypeCode, which is accessible through the type attribute. It can also be obtained by calling the component_count operation.

   9.2.9 The DynValueCommon Interface

   DynValueCommon provides operations supported by both the DynValue and DynValueBox interfaces.

   local interface DynValueCommon : DynAny { boolean is_null(); void set_to_null(); void set_to_value();

   };

   boolean is_null();

   The is_null operation returns TRUE if the DynValueCommon represents a null valuetype.

   void set_to_null();

   The set_to_null operation changes the representation of a DynValueCommon to a null valuetype.

   void set_to_value();

   If the DynValueCommon represents a null valuetype, then set_to_value replaces it with a newly constructed value, with its components initialized to default values as in DynAnyFactory::create_dyn_any_from_type_code. If the DynValueCommon represents a non-null valuetype, then this operation has no effect.

   A reference to a DynValueCommon interface (and interfaces derived from it) exhibit the same sharing semantics as the underlying valuetype that it represents. This means that the relationships between valuetypes in a graph of valuetypes will remain unchanged when converted into DynAny form and vice versa. This is necessary to ensure that applications that use the DII and DSI can correctly view and preserve the semantics of the valuetype graph.

   9.2.10 The DynValue Interface

   DynValue objects are associated with non-boxed valuetypes.

   local interface DynValue : DynValueCommon { FieldName current_member_name() raises(TypeMismatch, InvalidValue); CORBA::TCKind current_member_kind() raises(TypeMismatch, InvalidValue); NameValuePairSeq get_members() raises(InvalidValue); void set_members(in NameValuePairSeq value) raises(TypeMismatch, InvalidValue); NameDynAnyPairSeq get_members_as_dyn_any() raises(InvalidValue); void set_members_as_dyn_any(in NameDynAnyPairSeq value) raises(TypeMismatch, InvalidValue); };

   The DynValue interface can represent both null and non-null valuetypes. For a DynValue representing a non-null valuetype, the DynValue's components comprise the public and private members of the valuetype, including those inherited from concrete base valuetypes, in the order of definition. A DynValue representing a null valuetype has no components and a current position of -1.

   The remaining operations on the DynValue interface generally have equivalent semantics to the same operations on DynStruct. When invoked on a DynValue representing a null valuetype, get_members and get_members_as_dyn_any raise InvalidValue. When invoked on a DynValue representing a null valuetype, set_members and set_members_as_dyn_any convert the DynValue to a non-null valuetype.

   Warning – Indiscriminately changing the contents of private valuetype members can cause the valuetype implementation to break by violating internal constraints. Access to private members is provided to support such activities as ORB bridging and debugging and should not be used to arbitrarily violate the encapsulation of the valuetype.

   9.2.11 The DynValueBox Interface

   DynValueBox objects are associated with boxed valuetypes.

   local interface DynValueBox : DynValueCommon { any get_boxed_value() raises(InvalidValue);

   void set_boxed_value(in any boxed) raises(TypeMismatch, InvalidValue); DynAny get_boxed_value_as_dyn_any() raises(InvalidValue); void set_boxed_value_as_dyn_any(in DynAny boxed) raises(TypeMismatch); };

   The DynValueBox interface can represent both null and non-null valuetypes. For a DynValueBox representing a non-null valuetype, the DynValueBox has a single component of the boxed type. A DynValueBox representing a null valuetype has no components and a current position of -1.

   any get_boxed_value() raises(InvalidValue);

   The get_boxed_value operation returns the boxed value as an any. If the DynBoxedValue represents a null valuetype, the operation raises InvalidValue.

   void set_boxed_value(in any boxed) raises(TypeMismatch, InvalidValue);

   The set_boxed_value operation replaces the boxed value with the specified value. If the type of the passed Any is not equivalent to the boxed type, the operation raises TypeMismatch. If the passed Any does not contain a legal value, the operation raises InvalidValue. If the DynBoxedValue represents a null valuetype, it is converted to a non-null value.

   The get_boxed_value_as_dyn_any and set_boxed_value_as_dyn_any have the same semantics as their any counterparts, but accept and return values of type DynAny instead of any.