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