xref: /trunk/main/stoc/source/corereflection/crarray.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_stoc.hxx"
30 #include <typelib/typedescription.h>
31 #include <uno/data.h>
32 
33 #include "base.hxx"
34 
35 
36 namespace stoc_corefl
37 {
38 
39 // XInterface
40 //__________________________________________________________________________________________________
41 Any ArrayIdlClassImpl::queryInterface( const Type & rType )
42     throw(::com::sun::star::uno::RuntimeException)
43 {
44     Any aRet( ::cppu::queryInterface( rType, static_cast< XIdlArray * >( this ) ) );
45     return (aRet.hasValue() ? aRet : IdlClassImpl::queryInterface( rType ));
46 }
47 //__________________________________________________________________________________________________
48 void ArrayIdlClassImpl::acquire() throw()
49 {
50     IdlClassImpl::acquire();
51 }
52 //__________________________________________________________________________________________________
53 void ArrayIdlClassImpl::release() throw()
54 {
55     IdlClassImpl::release();
56 }
57 
58 // XTypeProvider
59 //__________________________________________________________________________________________________
60 Sequence< Type > ArrayIdlClassImpl::getTypes()
61     throw (::com::sun::star::uno::RuntimeException)
62 {
63     static OTypeCollection * s_pTypes = 0;
64     if (! s_pTypes)
65     {
66         MutexGuard aGuard( getMutexAccess() );
67         if (! s_pTypes)
68         {
69             static OTypeCollection s_aTypes(
70                 ::getCppuType( (const Reference< XIdlArray > *)0 ),
71                 IdlClassImpl::getTypes() );
72             s_pTypes = &s_aTypes;
73         }
74     }
75     return s_pTypes->getTypes();
76 }
77 //__________________________________________________________________________________________________
78 Sequence< sal_Int8 > ArrayIdlClassImpl::getImplementationId()
79     throw (::com::sun::star::uno::RuntimeException)
80 {
81     static OImplementationId * s_pId = 0;
82     if (! s_pId)
83     {
84         MutexGuard aGuard( getMutexAccess() );
85         if (! s_pId)
86         {
87             static OImplementationId s_aId;
88             s_pId = &s_aId;
89         }
90     }
91     return s_pId->getImplementationId();
92 }
93 
94 // XIdlArray
95 //__________________________________________________________________________________________________
96 void ArrayIdlClassImpl::realloc( Any & rArray, sal_Int32 nLen )
97     throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
98 {
99     TypeClass eTC = rArray.getValueTypeClass();
100     if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY)
101     {
102         throw IllegalArgumentException(
103             OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ),
104             (XWeak *)(OWeakObject *)this, 0 );
105     }
106     if (nLen < 0)
107     {
108         throw IllegalArgumentException(
109             OUString( RTL_CONSTASCII_USTRINGPARAM("illegal length given!") ),
110             (XWeak *)(OWeakObject *)this, 1 );
111     }
112 
113     uno_Sequence ** ppSeq = (uno_Sequence **)rArray.getValue();
114     uno_sequence_realloc( ppSeq, (typelib_TypeDescription *)getTypeDescr(),
115                           nLen,
116                           reinterpret_cast< uno_AcquireFunc >(cpp_acquire),
117                           reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
118     rArray.pData = ppSeq;
119 }
120 //__________________________________________________________________________________________________
121 sal_Int32 ArrayIdlClassImpl::getLen( const Any & rArray )
122     throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
123 {
124     TypeClass eTC = rArray.getValueTypeClass();
125     if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY)
126     {
127         throw IllegalArgumentException(
128             OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ),
129             (XWeak *)(OWeakObject *)this, 0 );
130     }
131 
132     return (*(uno_Sequence **)rArray.getValue())->nElements;
133 }
134 //__________________________________________________________________________________________________
135 Any ArrayIdlClassImpl::get( const Any & rArray, sal_Int32 nIndex )
136     throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
137 {
138     TypeClass eTC = rArray.getValueTypeClass();
139     if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY)
140     {
141         throw IllegalArgumentException(
142             OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ),
143             (XWeak *)(OWeakObject *)this, 0 );
144     }
145 
146     uno_Sequence * pSeq = *(uno_Sequence **)rArray.getValue();
147     if (pSeq->nElements <= nIndex)
148     {
149         throw ArrayIndexOutOfBoundsException(
150             OUString( RTL_CONSTASCII_USTRINGPARAM("illegal index given!") ),
151             (XWeak *)(OWeakObject *)this );
152     }
153 
154     Any aRet;
155     typelib_TypeDescription * pElemTypeDescr = 0;
156     TYPELIB_DANGER_GET( &pElemTypeDescr, getTypeDescr()->pType );
157     uno_any_destruct( &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
158     uno_any_construct( &aRet, &pSeq->elements[nIndex * pElemTypeDescr->nSize],
159                        pElemTypeDescr,
160                        reinterpret_cast< uno_AcquireFunc >(cpp_acquire) );
161     TYPELIB_DANGER_RELEASE( pElemTypeDescr );
162     return aRet;
163 }
164 
165 //__________________________________________________________________________________________________
166 void ArrayIdlClassImpl::set( Any & rArray, sal_Int32 nIndex, const Any & rNewValue )
167     throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
168 {
169     TypeClass eTC = rArray.getValueTypeClass();
170     if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY)
171     {
172         throw IllegalArgumentException(
173             OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ),
174             (XWeak *)(OWeakObject *)this, 0 );
175     }
176 
177     uno_Sequence * pSeq = *(uno_Sequence **)rArray.getValue();
178     if (pSeq->nElements <= nIndex)
179     {
180         throw ArrayIndexOutOfBoundsException(
181             OUString( RTL_CONSTASCII_USTRINGPARAM("illegal index given!") ),
182             (XWeak *)(OWeakObject *)this );
183     }
184 
185     uno_Sequence ** ppSeq = (uno_Sequence **)rArray.getValue();
186     uno_sequence_reference2One(
187         ppSeq, (typelib_TypeDescription *)getTypeDescr(),
188         reinterpret_cast< uno_AcquireFunc >(cpp_acquire),
189         reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
190     rArray.pData = ppSeq;
191     pSeq = *ppSeq;
192 
193     typelib_TypeDescription * pElemTypeDescr = 0;
194     TYPELIB_DANGER_GET( &pElemTypeDescr, getTypeDescr()->pType );
195 
196     if (! coerce_assign( &pSeq->elements[nIndex * pElemTypeDescr->nSize],
197                          pElemTypeDescr, rNewValue, getReflection() ))
198     {
199         TYPELIB_DANGER_RELEASE( pElemTypeDescr );
200         throw IllegalArgumentException(
201             OUString( RTL_CONSTASCII_USTRINGPARAM("sequence element is not assignable by given value!") ),
202             (XWeak *)(OWeakObject *)this, 2 );
203     }
204     TYPELIB_DANGER_RELEASE( pElemTypeDescr );
205 }
206 
207 // ArrayIdlClassImpl
208 //__________________________________________________________________________________________________
209 sal_Bool ArrayIdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType )
210     throw(::com::sun::star::uno::RuntimeException)
211 {
212     return (xType.is() &&
213             (equals( xType ) ||
214              (xType->getTypeClass() == getTypeClass() && // must be sequence|array
215               getComponentType()->isAssignableFrom( xType->getComponentType() ))));
216 }
217 //__________________________________________________________________________________________________
218 Reference< XIdlClass > ArrayIdlClassImpl::getComponentType()
219     throw(::com::sun::star::uno::RuntimeException)
220 {
221     return getReflection()->forType( getTypeDescr()->pType );
222 }
223 //__________________________________________________________________________________________________
224 Reference< XIdlArray > ArrayIdlClassImpl::getArray()
225     throw(::com::sun::star::uno::RuntimeException)
226 {
227     return this;
228 }
229 
230 }
231 
232 
233