Any - Using CORBA Any's

Description:

The CORBA 'any' type provides an universal wrapper around any data type (therefore its name) including basic data types as well as user defined data types. Although 'any' is a CORBA IDL basic data type, it is usually mapped into a special class within the target language.

Therefore, the CORBA standard provides a (P)IDL for 'any' instances, which contains operations for insertion & extraction of all other basic data types. The necessary operations for insertion & extraction of a user defined data type will be generated into its 'Helper' class.

There is a unique typecode generated for each new data type as well which provides a standardized way to identify the type of the wrapped object during runtime.

Source:

\Demo\Any

Mapping:

CORBA IDL 'any' <---> Ics.CORBA.Any


Example

Step 1. The IDL (ANYDemo.idl):

    module Demo
    {
        interface AnyDemo
        {
            exception MyExcp
            {
                string  strWhy;
                long    lErrorCode;
            };
            
            struct Person
            {
                string  strSurname;
                string  strName;
                long    lAge;
            };
            
            typedef string arName[4];
            typedef sequence  sqName;
            
            void fkt( in any oParam );
        };
    };

(Will be compiled into ANYDemo.cs)

Step 2. The Server Implementation (ANYSrv.cs):

    public class DemoAnyImpl: AnyDemoPOA
    {
        override public void fkt( Ics.CORBA.Any a_oParam )
        {
            // Read the parameters TypeCode to identify the wrapped objects type:
            Ics.CORBA.TypeCode oTc = a_oParam.type();
            Console.Write("Typecode:{0}", oTc.kind());

            switch( oTc.kind())
            {
                case Ics.CORBA.TCKind.tk_null:
                    Console.WriteLine("\tValue: null" );
                    break;

                case Ics.CORBA.TCKind.tk_void:
                    Console.WriteLine("\tValue: void" );
                    break;

                case Ics.CORBA.TCKind.tk_boolean:
                    Console.WriteLine("\tValue: {0}", a_oParam.extract_boolean().ToString()  );
                    break;
            
                case Ics.CORBA.TCKind.tk_char:
                    Console.WriteLine("\tValue: {0}", a_oParam.extract_char().ToString()  );
                    break;

                // [...]
                
                case Ics.CORBA.TCKind.tk_objref:
                    Ics.CORBA.Object oObj = a_oParam.extract_Object();
                    oObj.printIOR();
                    break;

                // If the typecode shows an exception, 
                // we make an "educated guess" for our own exception:
                case Ics.CORBA.TCKind.tk_except:
                {
                    try{
                        throw  Demo.AnyDemoPackage.MyExcpHelper.extract( a_oParam); 
                    }
                    catch( Demo.AnyDemoPackage.MyExcp oExcep )
                    {
                        Console.WriteLine("Exception: Why:{0} ErrorCode:{1} ",
                            oExcep.strWhy, oExcep.lErrorCode.ToString());    
                    }
                } break;

                // If the typecode shows a struct, 
                // we make an "educated guess" for our own struct:
                case Ics.CORBA.TCKind.tk_struct:
                {
                    Demo.AnyDemoPackage.Person oPerson = Demo.AnyDemoPackage.PersonHelper.extract( a_oParam); 
                    Console.WriteLine("Person: Surname:{0} Name:{1} Age:{2}",
                        oPerson.strSurname, oPerson.strName, oPerson.lAge);    
                
                } break;

                // If the typecode shows an array or a sequence, 
                // we make an "educated guess" for our own data types:
                case Ics.CORBA.TCKind.tk_alias:
                {
                    switch( a_oParam.type().content_type().kind())
                    {
                        case Ics.CORBA.TCKind.tk_array:
                        {
                            Console.WriteLine(" - Contenttype: tk_array\t");
                            string[] strLst = Demo.AnyDemoPackage.arNameHelper.extract( a_oParam); 
                            Console.Write(" Array: ");
                            foreach( string str in strLst)
                                Console.Write("{0}\t", str);
                                
                        }   break;

                        case Ics.CORBA.TCKind.tk_sequence:
                        {
                            Console.WriteLine(" - Contenttype: tk_sequence\t");
                            string[] strLst = Demo.AnyDemoPackage.sqNameHelper.extract( a_oParam); 
                            Console.Write(" Squence: ");
                            foreach( string str in strLst)
                                Console.Write("{0}\t", str);
                                
                        }   break;

                    }
                }   break;
            }
        }
    }    

Step 3. The Client (ANYClt.cs):

Note, that (due to the hybrid character of 'any's) instances of class 'Any' will be obtained via the ORB interface:

    Ics.CORBA.Any oAny = oOrb.create_any();

Once there is an Any, we can insert a basic data type or an object reference:

    oAny.insert_null();
    a_oAnyDemo.fkt( oAny);
    
    oAny.insert_void();
    a_oAnyDemo.fkt( oAny);
    
    oAny.insert_boolean( true);
    a_oAnyDemo.fkt( oAny);
    
    oAny.insert_char( 'A');
    a_oAnyDemo.fkt( oAny);
    
    // [...]

    oAny.insert_Object( a_oAnyDemo);
    a_oAnyDemo.fkt( oAny);

To insert a user defined complex or constructed data type, we have explicitly to make use of its 'Helper' class:

    // Struct
    Demo.AnyDemoPackage.Person oPerson = new Demo.AnyDemoPackage.Person( "Meier", "Hans", 30);
    Demo.AnyDemoPackage.PersonHelper.insert( oAny, oPerson);
    a_oAnyDemo.fkt( oAny);
           
    // Array
    string[] str = {"John", "Tom", "Fred", "Ted"};
    Demo.AnyDemoPackage.arNameHelper.insert( oAny, str);
    a_oAnyDemo.fkt( oAny);
    
    // Sequence
    string[] strLst = {"Meier", "Smit", "Hansen"};
    Demo.AnyDemoPackage.sqNameHelper.insert( oAny, strLst);
    a_oAnyDemo.fkt( oAny);
    
    // Exception
    try {
        throw new Demo.AnyDemoPackage.MyExcp("The Test", 99);
    }
    catch( Demo.AnyDemoPackage.MyExcp oEx )
    {
        Demo.AnyDemoPackage.MyExcpHelper.insert( oAny, oEx);
        a_oAnyDemo.fkt( oAny);
    }

Step 4. Run the example

a.) Start the Server.

b.) Start the Client.