Difference between revisions of "Documentation/DevGuide/ProUNO/C++/Mapping of Sequence Types"

From Apache OpenOffice Wiki
Jump to: navigation, search
m (1 revision(s))
m (Robot: Changing Category:Professional UNO)
Line 214: Line 214:
  
 
{{PDL1}}
 
{{PDL1}}
[[Category: Professional UNO]]
+
 
 +
[[Category:Documentation/Developers Guide/Professional UNO]]

Revision as of 15:07, 8 May 2008




An IDL sequence is mapped to:

 template< class t >
 com::sun::star::uno::Sequence< t > 

The sequence class is a reference to a reference counted handle that is allocated on the heap.

The sequence follows a copy-on-modify strategy. If a sequence is about to be modified, it is checked if the reference count of the sequence is 1. If this is the case, it gets modified directly, otherwise a copy of the sequence is created that has a reference count of 1.

A sequence can be created with an arbitrary UNO type as element type, but do not use a non-UNO type. The full reflection data provided by the type library are needed for construction, destruction and comparison.

You can construct a sequence with an initial number of elements. Each element is default constructed.

 {
     // create an integer sequence with 3 elements,
     // elements default to zero.
     Sequence< sal_Int32 > seqInt( 3 );
     
     // get a read/write array pointer (this method checks for
     // the refcount and does a copy on demand).
     sal_Int32 *pArray = seqInt.getArray();
     
     // if you know, that the refocunt is one
     // as in this case, where the sequence has just been
     // constructed, you could avoid the check,
     // which is a C-call overhead,
     // by writing sal_Int32 *pArray = (sal_Int32*) seqInt.getConstArray();
     
     // modify the members
     pArray[0] = 4;
     pArray[1] = 5;
     pArray[2] = 3;
 }

You can also initialize a sequence from an array of the same type by using a different constructor. The new sequence is allocated on the heap and all elements are copied from the source.

 {
     sal_Int32 sourceArray[3] = {3,5,3};
 
     // result is the same as above, but we initialize from a buffer.
     Sequence< sal_Int32 > seqInt( sourceArray , 3 );
 }

Complex UNO types like structs can be stored within sequences, too:

 {
     // construct a sequence of Property structs,
     // the structs are default constructed
     Sequence< Property > seqProperty(2);
     seqProperty[0].Name = OUString::createFromAscii( "A" );
     seqProperty[0].Handle = 0;
     seqProperty[1].Name = OUString::createFromAscii( "B" );
     seqProperty[1].Handle = 1;
     
     // copy construct the sequence (The refcount is raised)
     Sequence< Property > seqProperty2 = seqProperty;
     
     // access a sequence
     for( sal_Int32 i = 0 ; i < seqProperty.getLength() ; i ++ )
     {
         // Please NOTE : seqProperty.getArray() would also work, but 
         // it is more expensive, because a
         // unnessecary copy construction
         // of the sequence takes place.
         printf( "%d\n" , seqProperty.getConstArray()[i].Handle );
     }
 }

The size of sequences can be changed using the realloc() method, which takes the new number of elements as a parameter. For instance:

 // construct an empty sequence
 Sequence < Any > anySequence;
 
 // get your enumeration from somewhere
 Reference< XEnumeration > rEnum = ...;
 
 // iterate over the enumeration
 while( rEnum->hasMoreElements() )
 {
     anySequence.realloc( anySequence.getLength() + 1 );
     anySequence[anySequence.getLength()-1] = rEnum->nextElement();
 }

The above code shows an enumeration is transformed into a sequence,using an inefficient method. The realloc() default constructs a new element at the end of the sequence. If the sequence is shrunk by realloc, the elements at the end are destroyed.

The sequence is meant as a transportation container only, therefore it lacks methods for efficient insertion and removal of elements. Use a C++ Standard Template Library vector as an intermediate container to manipulate a list of elements and finally copy the elements into the sequence.

Sequences of a specific type are a fully supported UNO type. There can also be a sequence of sequences. This is similar to a multidimensional array with the exception that each row may vary in length. For instance:

 {
     sal_Int32 a[ ] = { 1,2,3 }, b[] = {4,5,6}, c[] = {7,8,9,10};
     Sequence< Sequence< sal_Int32 > > aaSeq ( 3 );
     aaSeq[0] = Sequence< sal_Int32 >( a , 3 );
     aaSeq[1] = Sequence< sal_Int32 >( b , 3 );
     aaSeq[2] = Sequence< sal_Int32 >( c , 4 );
 }

is a valid sequence of sequence< sal_Int32>.

The maximal length of a com::sun::star::uno::Sequence is limited; therefore, it is an error if a UNO sequence that is too long is used in the context of the C++ language binding.

Mapping of Sequence Types

An IDL sequence is mapped to:

 template< class t >
 com::sun::star::uno::Sequence< t > 

The sequence class is a reference to a reference counted handle that is allocated on the heap.

The sequence follows a copy-on-modify strategy. If a sequence is about to be modified, it is checked if the reference count of the sequence is 1. If this is the case, it gets modified directly, otherwise a copy of the sequence is created that has a reference count of 1.

A sequence can be created with an arbitrary UNO type as element type, but do not use a non-UNO type. The full reflection data provided by the type library are needed for construction, destruction and comparison.

You can construct a sequence with an initial number of elements. Each element is default constructed.

 {
     // create an integer sequence with 3 elements,
     // elements default to zero.
     Sequence< sal_Int32 > seqInt( 3 );
     
     // get a read/write array pointer (this method checks for
     // the refcount and does a copy on demand).
     sal_Int32 *pArray = seqInt.getArray();
     
     // if you know, that the refocunt is one
     // as in this case, where the sequence has just been
     // constructed, you could avoid the check,
     // which is a C-call overhead,
     // by writing sal_Int32 *pArray = (sal_Int32*) seqInt.getConstArray();
     
     // modify the members
     pArray[0] = 4;
     pArray[1] = 5;
     pArray[2] = 3;
 }

You can also initialize a sequence from an array of the same type by using a different constructor. The new sequence is allocated on the heap and all elements are copied from the source.

 {
     sal_Int32 sourceArray[3] = {3,5,3};
 
     // result is the same as above, but we initialize from a buffer.
     Sequence< sal_Int32 > seqInt( sourceArray , 3 );
 }

Complex UNO types like structs can be stored within sequences, too:

 {
     // construct a sequence of Property structs,
     // the structs are default constructed
     Sequence< Property > seqProperty(2);
     seqProperty[0].Name = OUString::createFromAscii( "A" );
     seqProperty[0].Handle = 0;
     seqProperty[1].Name = OUString::createFromAscii( "B" );
     seqProperty[1].Handle = 1;
     
     // copy construct the sequence (The refcount is raised)
     Sequence< Property > seqProperty2 = seqProperty;
     
     // access a sequence
     for( sal_Int32 i = 0 ; i < seqProperty.getLength() ; i ++ )
     {
         // Please NOTE : seqProperty.getArray() would also work, but 
         // it is more expensive, because a
         // unnessecary copy construction
         // of the sequence takes place.
         printf( "%d\n" , seqProperty.getConstArray()[i].Handle );
     }
 }

The size of sequences can be changed using the realloc() method, which takes the new number of elements as a parameter. For instance:

 // construct an empty sequence
 Sequence < Any > anySequence;
 
 // get your enumeration from somewhere
 Reference< XEnumeration > rEnum = ...;
 
 // iterate over the enumeration
 while( rEnum->hasMoreElements() )
 {
     anySequence.realloc( anySequence.getLength() + 1 );
     anySequence[anySequence.getLength()-1] = rEnum->nextElement();
 }

The above code shows an enumeration is transformed into a sequence,using an inefficient method. The realloc() default constructs a new element at the end of the sequence. If the sequence is shrunk by realloc, the elements at the end are destroyed.

The sequence is meant as a transportation container only, therefore it lacks methods for efficient insertion and removal of elements. Use a C++ Standard Template Library vector as an intermediate container to manipulate a list of elements and finally copy the elements into the sequence.

Sequences of a specific type are a fully supported UNO type. There can also be a sequence of sequences. This is similar to a multidimensional array with the exception that each row may vary in length. For instance:

 {
     sal_Int32 a[ ] = { 1,2,3 }, b[] = {4,5,6}, c[] = {7,8,9,10};
     Sequence< Sequence< sal_Int32 > > aaSeq ( 3 );
     aaSeq[0] = Sequence< sal_Int32 >( a , 3 );
     aaSeq[1] = Sequence< sal_Int32 >( b , 3 );
     aaSeq[2] = Sequence< sal_Int32 >( c , 4 );
 }

is a valid sequence of sequence< sal_Int32>.

The maximal length of a com::sun::star::uno::Sequence is limited; therefore, it is an error if a UNO sequence that is too long is used in the context of the C++ language binding.

Content on this page is licensed under the Public Documentation License (PDL).
Personal tools