NonStop Software

IDL to C++ Mapping for Sequences

Previous Topic | Next Topic | Contents | Index
Getting Started Guide | Administration Guide | Programmer's Guide

Subtopics

IDL Sequences
IDL Bounded Sequences
IDL to C++ Mapping for Bounded Sequences
IDL Unbounded Sequences
IDL to C++ Mapping for Unbounded Sequences
Parameter Passing Table for IDL Sequences
Memory Management for IDL Sequences

IDL Sequences

An IDL sequence type gets mapped to a C++ class that behaves similarly to an array type, but with a current length and a maximum length. The maximum length is fixed for a bounded sequence, and changeable in the case of an unbounded sequence, the maximum is simply an initial value set in an unbounded sequence's constructor. The details of the generated C++ class differ slightly for bounded and unbounded sequences, and this is discussed in the following sections.

A _var type is also produced for each IDL sequence type; this can optionally be used to manage the storage of dynamically allocated sequences.

IDL Bounded Sequences

Given the following IDL typedef

typedef sequence<1ong,10> seq10;

an instance of this type can be defined as follows in C++:

seq10 x1;

Elements can be added using operator[ ], for example:

CORBA::ULong i;
x1.length(5);
for (i=O; i < 5; i++){ //	Enter five elements.
X1[i] = i;
}

Note that the length must be set explicitly using the length( ) member function, operator [ ] does not change the length. Note that operator [ ] should not be used to access or change an element outside of the current length. The maximum number of elements in this sequence is fixed at 10, the bound of the sequence type. Setting the length to a value larger than the sequence's bound produces undefined behavior.

A sequence can be dynamically allocated using either of the following two statements:

seq10 pi = new seq10;
seq10_var p2 = new seq10;

The difference is that the sequence pointed to by pi must be deallocated explicitly with delete p1, whereas the sequence pointed to by p2 is deallocated automatically when p2 goes out of scope.

IDL to C++ Mapping for Bounded Sequences

The generated C++ class seq10 is declared as follows:

public:class seq10; {
    seq10;	   // Allocates space for 10 elements
	           // and sets length to 0.
    seq10(const seq10&); // Deep copy.
    seq10(CORBA::ULong initial_length,
      CORBA::Long *data-buffer,
      CORBA::Boolean release = 0);
    ~seq10;
    seq10; operator=(const seq10&); // Deep copy.
    static CORBA::Long* allocbuf(CORBA::ULong number_elements);
    static void freebuf(CORBA::Long* data);
    CORBA::ULong maximum( ) const;   // get the max size
    CORBA::ULong length( ) const;    // get current length
    void length(CORBA::ULong new_length);
    CORBA::Long& operator[ ] (CORBA::ULong index); 
    const CORBA::Long& operator[ ] (CORBA::Ulong index) const;
    }

IDL Unbounded Sequences

The difference between a bounded and an unbounded sequence is that bounded has a fixed maximum length while unbounded has no theoretical maximum. A sequence of any length can be passed where an unbounded sequence is expected. Therefore, unbounded sequences are normally used in preference to bounded ones, unless the maximum length can be determined confidently.

In the C++ class that represents an unbounded sequence, there is a maximum( ) function that returns the sequence's current maximum. This is only an indication of the amount of space that is currently allocated to the sequence and it is normally not very important. The maximum is automatically increased if the length is increased to require more space than is currently allocated.

Given the following typedef

typedef sequence<float> seq;

an instance of this type can be defined as follows:

seq x2(50); //	Initial maximum of 50.

A sequence can be dynamically allocated by either of the following two statements:

seq p1, = new seq(50);
seq_var p1 = new seq(50);

The length must be set using length( ) as before, otherwise the length is zero. Elements can then be added using operator [ ]. operator [ ] should not be used to access or change an element outside of the current length.

An unbounded sequence defined using the following default constructor,

seq x3;

allocates some implementation-dependent amount of initial space for the sequence.

// Create the data buffer:
CORBA::Long *buf = seq::allocbuf(50);
// Initialize that buffer:
CORBA::ULong i;
for (i=O; i<27; i++)
	buf[i] = i; // Normal operator[]

Now create the sequence:

seq10 x2(50, 27, buf, 1); // Length is 27

The initial maximum has been set here to 50 (when the buffer is allocated and in the first parameter to the sequence's constructor). The length is 27 after this code sequence.

IDL to C++ Mapping for Unbounded Sequences

Continuing the example from the previous section, the generated C++ class seq is declared as follows:

class seq { 
    seq( ); // sets the length to zero. 
    seq(const seq&); // Deep copy. 
    seq(CORBA::ULong maximum); 
    seq(CORBA::ULong maximum, CORBA::ULong initial_length,
      CORBA::Long *data, CORBA::Boolean release = 0);
    ~seq( );
    seq& operator=(const seq&); // Deep copy.
    static CORBA::Long* allocbuf(CORBA::ULong number-elements);
    static void freebuf(CORBA::Long* data);
    CORBA::ULong maximum( ) const;
    // Get and set length: CORBA::ULong length( ) const; 
    void length(CORBA::ULength new_length);
    CORBA::Long& operator[ ] (CORBA::ULong index); 
    const CORBA::Long& operator[ ] (CORBA::Ulong index) const;
    };

Parameter Passing Table for IDL Sequences

When a sequence is passed as a parameter to an operation or appears as the return type, the corresponding C++ formal parameter types are used.

Table 1. Parameter Passing Modes for Sequences
IDL type in out inout return
sequence s const S& S*& S& S*

Remember that pointers are not valid IDL types, so you should not pass or return a zero pointer. It is of course valid to return (or pass as an out parameter) a pointer to an empty sequence.

Memory Management for IDL Sequences

The memory management rules for sequences can be summarized as follows. For an in parameter, the client is responsible for memory management. For an out parameter or return value, the target object must allocate the sequence, and return a pointer to this to the client. The client must deallocate the returned sequence when it no longer needs it. For an inout sequence, the client must allocate an initial sequence, which is passed by reference to the target object, and can be changed by it. The client remains responsible for deallocating the memory.

If the client and target object are in different address spaces, the receiver's copy of the sequence will have a release flag of 1 (so deallocating the sequence releases the buffer space). If the client and server are in the same address space, the creator of the sequence will have determined whether or not the buffer space needs to be released. If the release flag is 0, the creator must have arranged for another part of the code to release the space.


Previous Topic | Next Topic | Contents | Top
Getting Started Guide | Administration Guide | Programmer's Guide
Bibliography | Index | Glossary
© Tandem, a division of Compaq. All rights reserved. Legal notices.