1*647a425cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*647a425cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*647a425cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*647a425cSAndrew Rist  * distributed with this work for additional information
6*647a425cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*647a425cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*647a425cSAndrew Rist  * "License"); you may not use this file except in compliance
9*647a425cSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*647a425cSAndrew Rist  *
11*647a425cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*647a425cSAndrew Rist  *
13*647a425cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*647a425cSAndrew Rist  * software distributed under the License is distributed on an
15*647a425cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*647a425cSAndrew Rist  * KIND, either express or implied.  See the License for the
17*647a425cSAndrew Rist  * specific language governing permissions and limitations
18*647a425cSAndrew Rist  * under the License.
19*647a425cSAndrew Rist  *
20*647a425cSAndrew Rist  *************************************************************/
21*647a425cSAndrew Rist 
22*647a425cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_stoc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir //=========================================================================
28cdf0e10cSrcweir // Todo:
29cdf0e10cSrcweir //
30cdf0e10cSrcweir // - closeKey() calls (according to JSC not really needed because XRegistry
31cdf0e10cSrcweir //   implementation closes key in it's dtor.
32cdf0e10cSrcweir //
33cdf0e10cSrcweir //=========================================================================
34cdf0e10cSrcweir #include <osl/diagnose.h>
35cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
36cdf0e10cSrcweir #include "com/sun/star/reflection/XPublished.hpp"
37cdf0e10cSrcweir #include "cppuhelper/implbase1.hxx"
38cdf0e10cSrcweir #include "registry/reader.hxx"
39cdf0e10cSrcweir #include "registry/version.h"
40cdf0e10cSrcweir #include "base.hxx"
41cdf0e10cSrcweir #include "rdbtdp_tdenumeration.hxx"
42cdf0e10cSrcweir 
43cdf0e10cSrcweir using namespace com::sun::star;
44cdf0e10cSrcweir 
45cdf0e10cSrcweir namespace {
46cdf0e10cSrcweir 
47cdf0e10cSrcweir class IndividualConstantTypeDescriptionImpl:
48cdf0e10cSrcweir     public cppu::ImplInheritanceHelper1<
49cdf0e10cSrcweir         stoc_rdbtdp::ConstantTypeDescriptionImpl,
50cdf0e10cSrcweir         com::sun::star::reflection::XPublished >
51cdf0e10cSrcweir {
52cdf0e10cSrcweir public:
IndividualConstantTypeDescriptionImpl(rtl::OUString const & name,com::sun::star::uno::Any const & value,bool published)53cdf0e10cSrcweir     IndividualConstantTypeDescriptionImpl(
54cdf0e10cSrcweir         rtl::OUString const & name, com::sun::star::uno::Any const & value,
55cdf0e10cSrcweir         bool published):
56cdf0e10cSrcweir         cppu::ImplInheritanceHelper1<
57cdf0e10cSrcweir             stoc_rdbtdp::ConstantTypeDescriptionImpl,
58cdf0e10cSrcweir             com::sun::star::reflection::XPublished >(name, value),
59cdf0e10cSrcweir         m_published(published) {}
60cdf0e10cSrcweir 
isPublished()61cdf0e10cSrcweir     virtual sal_Bool SAL_CALL isPublished()
62cdf0e10cSrcweir         throw (::com::sun::star::uno::RuntimeException)
63cdf0e10cSrcweir     { return m_published; }
64cdf0e10cSrcweir 
65cdf0e10cSrcweir private:
66cdf0e10cSrcweir     bool m_published;
67cdf0e10cSrcweir };
68cdf0e10cSrcweir 
69cdf0e10cSrcweir }
70cdf0e10cSrcweir 
71cdf0e10cSrcweir namespace stoc_rdbtdp
72cdf0e10cSrcweir {
73cdf0e10cSrcweir 
74cdf0e10cSrcweir //=========================================================================
75cdf0e10cSrcweir //=========================================================================
76cdf0e10cSrcweir //
77cdf0e10cSrcweir // TypeDescriptionEnumerationImpl Implementation.
78cdf0e10cSrcweir //
79cdf0e10cSrcweir //=========================================================================
80cdf0e10cSrcweir //=========================================================================
81cdf0e10cSrcweir 
82cdf0e10cSrcweir // static
83cdf0e10cSrcweir rtl::Reference< TypeDescriptionEnumerationImpl >
createInstance(const uno::Reference<container::XHierarchicalNameAccess> & xTDMgr,const rtl::OUString & rModuleName,const uno::Sequence<uno::TypeClass> & rTypes,reflection::TypeDescriptionSearchDepth eDepth,const RegistryKeyList & rBaseKeys)84cdf0e10cSrcweir TypeDescriptionEnumerationImpl::createInstance(
85cdf0e10cSrcweir         const uno::Reference< container::XHierarchicalNameAccess > & xTDMgr,
86cdf0e10cSrcweir         const rtl::OUString & rModuleName,
87cdf0e10cSrcweir         const uno::Sequence< uno::TypeClass > & rTypes,
88cdf0e10cSrcweir         reflection::TypeDescriptionSearchDepth eDepth,
89cdf0e10cSrcweir         const RegistryKeyList & rBaseKeys )
90cdf0e10cSrcweir     throw ( reflection::NoSuchTypeNameException,
91cdf0e10cSrcweir             reflection::InvalidTypeNameException,
92cdf0e10cSrcweir             uno::RuntimeException )
93cdf0e10cSrcweir {
94cdf0e10cSrcweir     if ( rModuleName.getLength() == 0 )
95cdf0e10cSrcweir     {
96cdf0e10cSrcweir         // Enumeration for root requested.
97cdf0e10cSrcweir         return rtl::Reference< TypeDescriptionEnumerationImpl >(
98cdf0e10cSrcweir             new TypeDescriptionEnumerationImpl(
99cdf0e10cSrcweir                 xTDMgr, rBaseKeys, rTypes, eDepth ) );
100cdf0e10cSrcweir     }
101cdf0e10cSrcweir 
102cdf0e10cSrcweir     RegistryKeyList aModuleKeys;
103cdf0e10cSrcweir 
104cdf0e10cSrcweir     rtl::OUString aKey( rModuleName.replace( '.', '/' ) );
105cdf0e10cSrcweir 
106cdf0e10cSrcweir     bool bOpenKeySucceeded = false;
107cdf0e10cSrcweir 
108cdf0e10cSrcweir     const RegistryKeyList::const_iterator end = rBaseKeys.end();
109cdf0e10cSrcweir     RegistryKeyList::const_iterator it = rBaseKeys.begin();
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     while ( it != end )
112cdf0e10cSrcweir     {
113cdf0e10cSrcweir         uno::Reference< registry::XRegistryKey > xKey;
114cdf0e10cSrcweir         try
115cdf0e10cSrcweir         {
116cdf0e10cSrcweir             xKey = (*it)->openKey( aKey );
117cdf0e10cSrcweir             if ( xKey.is() )
118cdf0e10cSrcweir             {
119cdf0e10cSrcweir                 // closes key in it's dtor (which is
120cdf0e10cSrcweir                 // called even in case of exceptions).
121cdf0e10cSrcweir                 RegistryKeyCloser aCloser( xKey );
122cdf0e10cSrcweir 
123cdf0e10cSrcweir                 if ( xKey->isValid() )
124cdf0e10cSrcweir                 {
125cdf0e10cSrcweir                     bOpenKeySucceeded = true;
126cdf0e10cSrcweir 
127cdf0e10cSrcweir                     if ( xKey->getValueType()
128cdf0e10cSrcweir                          == registry::RegistryValueType_BINARY )
129cdf0e10cSrcweir                     {
130cdf0e10cSrcweir                         uno::Sequence< sal_Int8 > aBytes(
131cdf0e10cSrcweir                             xKey->getBinaryValue() );
132cdf0e10cSrcweir 
133cdf0e10cSrcweir                         typereg::Reader aReader(
134cdf0e10cSrcweir                             aBytes.getConstArray(), aBytes.getLength(), false,
135cdf0e10cSrcweir                             TYPEREG_VERSION_1);
136cdf0e10cSrcweir 
137cdf0e10cSrcweir                         rtl::OUString aName(
138cdf0e10cSrcweir                             aReader.getTypeName().replace( '/', '.' ) );
139cdf0e10cSrcweir 
140cdf0e10cSrcweir                         if ( aReader.getTypeClass() == RT_TYPE_MODULE )
141cdf0e10cSrcweir                         {
142cdf0e10cSrcweir                             // Do not close xKey!
143cdf0e10cSrcweir                             aCloser.reset();
144cdf0e10cSrcweir 
145cdf0e10cSrcweir                             aModuleKeys.push_back( xKey );
146cdf0e10cSrcweir                         }
147cdf0e10cSrcweir                     }
148cdf0e10cSrcweir                 }
149cdf0e10cSrcweir                 else
150cdf0e10cSrcweir                 {
151cdf0e10cSrcweir                     OSL_ENSURE(
152cdf0e10cSrcweir                         sal_False,
153cdf0e10cSrcweir                         "TypeDescriptionEnumerationImpl::createInstance "
154cdf0e10cSrcweir                         "- Invalid registry key!" );
155cdf0e10cSrcweir                 }
156cdf0e10cSrcweir             }
157cdf0e10cSrcweir         }
158cdf0e10cSrcweir         catch ( registry::InvalidRegistryException const & )
159cdf0e10cSrcweir         {
160cdf0e10cSrcweir             // openKey, getValueType, getBinaryValue
161cdf0e10cSrcweir 
162cdf0e10cSrcweir             OSL_ENSURE( sal_False,
163cdf0e10cSrcweir                         "TypeDescriptionEnumerationImpl::createInstance "
164cdf0e10cSrcweir                         "- Caught InvalidRegistryException!" );
165cdf0e10cSrcweir         }
166cdf0e10cSrcweir 
167cdf0e10cSrcweir         it++;
168cdf0e10cSrcweir     }
169cdf0e10cSrcweir 
170cdf0e10cSrcweir     if ( !bOpenKeySucceeded )
171cdf0e10cSrcweir         throw reflection::NoSuchTypeNameException();
172cdf0e10cSrcweir 
173cdf0e10cSrcweir     if ( aModuleKeys.size() == 0 )
174cdf0e10cSrcweir         throw reflection::InvalidTypeNameException();
175cdf0e10cSrcweir 
176cdf0e10cSrcweir     return rtl::Reference< TypeDescriptionEnumerationImpl >(
177cdf0e10cSrcweir         new TypeDescriptionEnumerationImpl(
178cdf0e10cSrcweir                 xTDMgr, aModuleKeys, rTypes, eDepth ) );
179cdf0e10cSrcweir }
180cdf0e10cSrcweir 
181cdf0e10cSrcweir //=========================================================================
TypeDescriptionEnumerationImpl(const uno::Reference<container::XHierarchicalNameAccess> & xTDMgr,const RegistryKeyList & rModuleKeys,const uno::Sequence<uno::TypeClass> & rTypes,reflection::TypeDescriptionSearchDepth eDepth)182cdf0e10cSrcweir TypeDescriptionEnumerationImpl::TypeDescriptionEnumerationImpl(
183cdf0e10cSrcweir     const uno::Reference< container::XHierarchicalNameAccess > & xTDMgr,
184cdf0e10cSrcweir     const RegistryKeyList & rModuleKeys,
185cdf0e10cSrcweir     const uno::Sequence< uno::TypeClass > & rTypes,
186cdf0e10cSrcweir     reflection::TypeDescriptionSearchDepth eDepth )
187cdf0e10cSrcweir : m_aModuleKeys( rModuleKeys ),
188cdf0e10cSrcweir   m_aTypes( rTypes ),
189cdf0e10cSrcweir   m_eDepth( eDepth ),
190cdf0e10cSrcweir   m_xTDMgr( xTDMgr )
191cdf0e10cSrcweir {
192cdf0e10cSrcweir     g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
193cdf0e10cSrcweir }
194cdf0e10cSrcweir 
195cdf0e10cSrcweir //=========================================================================
196cdf0e10cSrcweir // virtual
~TypeDescriptionEnumerationImpl()197cdf0e10cSrcweir TypeDescriptionEnumerationImpl::~TypeDescriptionEnumerationImpl()
198cdf0e10cSrcweir {
199cdf0e10cSrcweir     RegistryKeyList::const_iterator it = m_aModuleKeys.begin();
200cdf0e10cSrcweir     RegistryKeyList::const_iterator end = m_aModuleKeys.end();
201cdf0e10cSrcweir /*
202cdf0e10cSrcweir    @@@ in case we enumerate root and queryMore was never called, then
203cdf0e10cSrcweir        m_aModuleKeys contains open root keys which where passed from
204cdf0e10cSrcweir        tdprov and must not be closed by us.
205cdf0e10cSrcweir 
206cdf0e10cSrcweir     while ( it != end )
207cdf0e10cSrcweir     {
208cdf0e10cSrcweir         try
209cdf0e10cSrcweir         {
210cdf0e10cSrcweir             if ( (*it)->isValid() )
211cdf0e10cSrcweir                 (*it)->closeKey();
212cdf0e10cSrcweir         }
213cdf0e10cSrcweir         catch (...)
214cdf0e10cSrcweir         {
215cdf0e10cSrcweir             // No exceptions from dtors, please!
216cdf0e10cSrcweir             OSL_ENSURE( sal_False,
217cdf0e10cSrcweir             "TypeDescriptionEnumerationImpl::~TypeDescriptionEnumerationImpl "
218cdf0e10cSrcweir             "- Caught exception!" );
219cdf0e10cSrcweir         }
220cdf0e10cSrcweir 
221cdf0e10cSrcweir         it++;
222cdf0e10cSrcweir     }
223cdf0e10cSrcweir */
224cdf0e10cSrcweir     it = m_aCurrentModuleSubKeys.begin();
225cdf0e10cSrcweir     end = m_aCurrentModuleSubKeys.end();
226cdf0e10cSrcweir     while ( it != end )
227cdf0e10cSrcweir     {
228cdf0e10cSrcweir         try
229cdf0e10cSrcweir         {
230cdf0e10cSrcweir             if ( (*it)->isValid() )
231cdf0e10cSrcweir                 (*it)->closeKey();
232cdf0e10cSrcweir         }
233cdf0e10cSrcweir         catch (Exception &)
234cdf0e10cSrcweir         {
235cdf0e10cSrcweir             // No exceptions from dtors, please!
236cdf0e10cSrcweir             OSL_ENSURE( sal_False,
237cdf0e10cSrcweir             "TypeDescriptionEnumerationImpl::~TypeDescriptionEnumerationImpl "
238cdf0e10cSrcweir             "- Caught exception!" );
239cdf0e10cSrcweir         }
240cdf0e10cSrcweir 
241cdf0e10cSrcweir         it++;
242cdf0e10cSrcweir     }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir     g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
245cdf0e10cSrcweir }
246cdf0e10cSrcweir 
247cdf0e10cSrcweir //=========================================================================
248cdf0e10cSrcweir //
249cdf0e10cSrcweir // XEnumeration (base of XTypeDescriptionEnumeration) methods
250cdf0e10cSrcweir //
251cdf0e10cSrcweir //=========================================================================
252cdf0e10cSrcweir 
253cdf0e10cSrcweir // virtual
hasMoreElements()254cdf0e10cSrcweir sal_Bool SAL_CALL TypeDescriptionEnumerationImpl::hasMoreElements()
255cdf0e10cSrcweir     throw ( uno::RuntimeException )
256cdf0e10cSrcweir {
257cdf0e10cSrcweir     return queryMore();
258cdf0e10cSrcweir }
259cdf0e10cSrcweir 
260cdf0e10cSrcweir //=========================================================================
261cdf0e10cSrcweir // virtual
nextElement()262cdf0e10cSrcweir uno::Any SAL_CALL TypeDescriptionEnumerationImpl::nextElement()
263cdf0e10cSrcweir     throw ( container::NoSuchElementException,
264cdf0e10cSrcweir             lang::WrappedTargetException,
265cdf0e10cSrcweir             uno::RuntimeException )
266cdf0e10cSrcweir {
267cdf0e10cSrcweir     return uno::Any( uno::makeAny( nextTypeDescription() ) );
268cdf0e10cSrcweir }
269cdf0e10cSrcweir 
270cdf0e10cSrcweir //=========================================================================
271cdf0e10cSrcweir //
272cdf0e10cSrcweir // XTypeDescriptionEnumeration methods
273cdf0e10cSrcweir //
274cdf0e10cSrcweir //=========================================================================
275cdf0e10cSrcweir 
276cdf0e10cSrcweir // virtual
277cdf0e10cSrcweir uno::Reference< reflection::XTypeDescription > SAL_CALL
nextTypeDescription()278cdf0e10cSrcweir TypeDescriptionEnumerationImpl::nextTypeDescription()
279cdf0e10cSrcweir     throw ( container::NoSuchElementException,
280cdf0e10cSrcweir             uno::RuntimeException )
281cdf0e10cSrcweir {
282cdf0e10cSrcweir     uno::Reference< reflection::XTypeDescription > xTD( queryNext() );
283cdf0e10cSrcweir 
284cdf0e10cSrcweir     if ( xTD.is() )
285cdf0e10cSrcweir         return xTD;
286cdf0e10cSrcweir 
287cdf0e10cSrcweir     throw container::NoSuchElementException(
288cdf0e10cSrcweir         rtl::OUString::createFromAscii(
289cdf0e10cSrcweir             "No further elements in enumeration!" ),
290cdf0e10cSrcweir         static_cast< cppu::OWeakObject * >( this  ) );
291cdf0e10cSrcweir }
292cdf0e10cSrcweir 
293cdf0e10cSrcweir //=========================================================================
match(RTTypeClass eType1,uno::TypeClass eType2)294cdf0e10cSrcweir bool TypeDescriptionEnumerationImpl::match(
295cdf0e10cSrcweir     RTTypeClass eType1, uno::TypeClass eType2 )
296cdf0e10cSrcweir {
297cdf0e10cSrcweir     switch ( eType1 )
298cdf0e10cSrcweir     {
299cdf0e10cSrcweir     case RT_TYPE_INTERFACE:
300cdf0e10cSrcweir         return eType2 == uno::TypeClass_INTERFACE;
301cdf0e10cSrcweir 
302cdf0e10cSrcweir     case RT_TYPE_MODULE:
303cdf0e10cSrcweir         return eType2 == uno::TypeClass_MODULE;
304cdf0e10cSrcweir 
305cdf0e10cSrcweir     case RT_TYPE_STRUCT:
306cdf0e10cSrcweir         return eType2 == uno::TypeClass_STRUCT;
307cdf0e10cSrcweir 
308cdf0e10cSrcweir     case RT_TYPE_ENUM:
309cdf0e10cSrcweir         return eType2 == uno::TypeClass_ENUM;
310cdf0e10cSrcweir 
311cdf0e10cSrcweir     case RT_TYPE_EXCEPTION:
312cdf0e10cSrcweir         return eType2 == uno::TypeClass_EXCEPTION;
313cdf0e10cSrcweir 
314cdf0e10cSrcweir     case RT_TYPE_TYPEDEF:
315cdf0e10cSrcweir         return eType2 == uno::TypeClass_TYPEDEF;
316cdf0e10cSrcweir 
317cdf0e10cSrcweir     case RT_TYPE_SERVICE:
318cdf0e10cSrcweir         return eType2 == uno::TypeClass_SERVICE;
319cdf0e10cSrcweir 
320cdf0e10cSrcweir     case RT_TYPE_SINGLETON:
321cdf0e10cSrcweir         return eType2 == uno::TypeClass_SINGLETON;
322cdf0e10cSrcweir 
323cdf0e10cSrcweir     case RT_TYPE_CONSTANTS:
324cdf0e10cSrcweir         return eType2 == uno::TypeClass_CONSTANTS;
325cdf0e10cSrcweir 
326cdf0e10cSrcweir     case RT_TYPE_UNION:
327cdf0e10cSrcweir         return eType2 == uno::TypeClass_UNION;
328cdf0e10cSrcweir 
329cdf0e10cSrcweir     default:
330cdf0e10cSrcweir         return false;
331cdf0e10cSrcweir     }
332cdf0e10cSrcweir }
333cdf0e10cSrcweir 
334cdf0e10cSrcweir //=========================================================================
queryMore()335cdf0e10cSrcweir bool TypeDescriptionEnumerationImpl::queryMore()
336cdf0e10cSrcweir {
337cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
338cdf0e10cSrcweir 
339cdf0e10cSrcweir     for (;;)
340cdf0e10cSrcweir     {
341cdf0e10cSrcweir         if ( !m_aCurrentModuleSubKeys.empty() || !m_aTypeDescs.empty() )
342cdf0e10cSrcweir         {
343cdf0e10cSrcweir             // Okay, there is at least one more element.
344cdf0e10cSrcweir             return true;
345cdf0e10cSrcweir         }
346cdf0e10cSrcweir 
347cdf0e10cSrcweir         if ( m_aModuleKeys.empty() )
348cdf0e10cSrcweir         {
349cdf0e10cSrcweir             // No module keys (therefore no elements) left.
350cdf0e10cSrcweir             return false;
351cdf0e10cSrcweir         }
352cdf0e10cSrcweir 
353cdf0e10cSrcweir         // Note: m_aCurrentModuleSubKeys is always empty AND m_aModuleKeys is
354cdf0e10cSrcweir         //       never empty when ariving here.
355cdf0e10cSrcweir         //       ==> select new module key, fill m_aCurrentModuleSubKeys
356cdf0e10cSrcweir 
357cdf0e10cSrcweir         uno::Sequence< uno::Reference< registry::XRegistryKey > > aKeys;
358cdf0e10cSrcweir         try
359cdf0e10cSrcweir         {
360cdf0e10cSrcweir             aKeys = m_aModuleKeys.front()->openKeys();
361cdf0e10cSrcweir             for ( sal_Int32 n = 0; n < aKeys.getLength(); ++n )
362cdf0e10cSrcweir             {
363cdf0e10cSrcweir                 uno::Reference< registry::XRegistryKey > xKey = aKeys[ n ];
364cdf0e10cSrcweir 
365cdf0e10cSrcweir                 // closes key in it's dtor (which is
366cdf0e10cSrcweir                 // called even in case of exceptions).
367cdf0e10cSrcweir                 RegistryKeyCloser aCloser( xKey );
368cdf0e10cSrcweir 
369cdf0e10cSrcweir                 try
370cdf0e10cSrcweir                 {
371cdf0e10cSrcweir                     if ( xKey->isValid() )
372cdf0e10cSrcweir                     {
373cdf0e10cSrcweir                         if ( xKey->getValueType()
374cdf0e10cSrcweir                                 == registry::RegistryValueType_BINARY )
375cdf0e10cSrcweir                         {
376cdf0e10cSrcweir                             bool bIncludeIt = (m_aTypes.getLength() == 0);
377cdf0e10cSrcweir                             bool bNeedTypeClass =
378cdf0e10cSrcweir                                 ((m_aTypes.getLength() > 0) ||
379cdf0e10cSrcweir                                  (m_eDepth
380cdf0e10cSrcweir                                     == reflection::TypeDescriptionSearchDepth_INFINITE));
381cdf0e10cSrcweir                             if ( bNeedTypeClass )
382cdf0e10cSrcweir                             {
383cdf0e10cSrcweir                                 uno::Sequence< sal_Int8 > aBytes(
384cdf0e10cSrcweir                                     xKey->getBinaryValue() );
385cdf0e10cSrcweir 
386cdf0e10cSrcweir                                 typereg::Reader aReader(
387cdf0e10cSrcweir                                     aBytes.getConstArray(), aBytes.getLength(),
388cdf0e10cSrcweir                                     false, TYPEREG_VERSION_1);
389cdf0e10cSrcweir 
390cdf0e10cSrcweir                                 RTTypeClass eTypeClass = aReader.getTypeClass();
391cdf0e10cSrcweir 
392cdf0e10cSrcweir                                 // Does key match requested types? Empty
393cdf0e10cSrcweir                                 // sequence means include all.
394cdf0e10cSrcweir                                 if ( m_aTypes.getLength() > 0 )
395cdf0e10cSrcweir                                 {
396cdf0e10cSrcweir                                     for ( sal_Int32 m = 0;
397cdf0e10cSrcweir                                           m < m_aTypes.getLength();
398cdf0e10cSrcweir                                           ++m )
399cdf0e10cSrcweir                                     {
400cdf0e10cSrcweir                                         if ( match(eTypeClass, m_aTypes[ m ]) )
401cdf0e10cSrcweir                                         {
402cdf0e10cSrcweir                                             bIncludeIt = true;
403cdf0e10cSrcweir                                             break;
404cdf0e10cSrcweir                                         }
405cdf0e10cSrcweir                                     }
406cdf0e10cSrcweir                                 }
407cdf0e10cSrcweir 
408cdf0e10cSrcweir                                 if ( m_eDepth ==
409cdf0e10cSrcweir                                         reflection::TypeDescriptionSearchDepth_INFINITE )
410cdf0e10cSrcweir                                 {
411cdf0e10cSrcweir                                     if ( eTypeClass == RT_TYPE_MODULE )
412cdf0e10cSrcweir                                     {
413cdf0e10cSrcweir                                         // Do not close xKey!
414cdf0e10cSrcweir                                         aCloser.reset();
415cdf0e10cSrcweir 
416cdf0e10cSrcweir                                         // Remember new module key.
417cdf0e10cSrcweir                                         m_aModuleKeys.push_back( xKey );
418cdf0e10cSrcweir                                     }
419cdf0e10cSrcweir                                 }
420cdf0e10cSrcweir                             }
421cdf0e10cSrcweir 
422cdf0e10cSrcweir                             if ( bIncludeIt )
423cdf0e10cSrcweir                             {
424cdf0e10cSrcweir                                 // Do not close xKey!
425cdf0e10cSrcweir                                 aCloser.reset();
426cdf0e10cSrcweir 
427cdf0e10cSrcweir                                 m_aCurrentModuleSubKeys.push_back( xKey );
428cdf0e10cSrcweir                             }
429cdf0e10cSrcweir                         }
430cdf0e10cSrcweir                     }
431cdf0e10cSrcweir                     else
432cdf0e10cSrcweir                     {
433cdf0e10cSrcweir                         OSL_ENSURE( sal_False,
434cdf0e10cSrcweir                             "TypeDescriptionEnumerationImpl::queryMore "
435cdf0e10cSrcweir                             "- Invalid registry key!" );
436cdf0e10cSrcweir                     }
437cdf0e10cSrcweir 
438cdf0e10cSrcweir                 }
439cdf0e10cSrcweir                 catch ( registry::InvalidRegistryException const & )
440cdf0e10cSrcweir                 {
441cdf0e10cSrcweir                     // getValueType, getBinaryValue
442cdf0e10cSrcweir 
443cdf0e10cSrcweir                     OSL_ENSURE( sal_False,
444cdf0e10cSrcweir                                 "TypeDescriptionEnumerationImpl::queryMore "
445cdf0e10cSrcweir                                 "- Caught InvalidRegistryException!" );
446cdf0e10cSrcweir 
447cdf0e10cSrcweir                     // Don't stop iterating!
448cdf0e10cSrcweir                 }
449cdf0e10cSrcweir             }
450cdf0e10cSrcweir         }
451cdf0e10cSrcweir         catch ( registry::InvalidRegistryException const & )
452cdf0e10cSrcweir         {
453cdf0e10cSrcweir             // openKeys
454cdf0e10cSrcweir 
455cdf0e10cSrcweir             for ( sal_Int32 n = 0; n < aKeys.getLength(); ++n )
456cdf0e10cSrcweir             {
457cdf0e10cSrcweir                 try
458cdf0e10cSrcweir                 {
459cdf0e10cSrcweir                     aKeys[ n ]->closeKey();
460cdf0e10cSrcweir                 }
461cdf0e10cSrcweir                 catch ( registry::InvalidRegistryException const & )
462cdf0e10cSrcweir                 {
463cdf0e10cSrcweir                     OSL_ENSURE( sal_False,
464cdf0e10cSrcweir                                 "TypeDescriptionEnumerationImpl::queryMore "
465cdf0e10cSrcweir                                 "- Caught InvalidRegistryException!" );
466cdf0e10cSrcweir                 }
467cdf0e10cSrcweir             }
468cdf0e10cSrcweir         }
469cdf0e10cSrcweir 
470cdf0e10cSrcweir         /////////////////////////////////////////////////////////////////////
471cdf0e10cSrcweir         // Special handling for constants contained directly in module.
472cdf0e10cSrcweir         /////////////////////////////////////////////////////////////////////
473cdf0e10cSrcweir 
474cdf0e10cSrcweir         // Constants requested?
475cdf0e10cSrcweir         bool bIncludeConstants = ( m_aTypes.getLength() == 0 );
476cdf0e10cSrcweir         if ( !bIncludeConstants )
477cdf0e10cSrcweir         {
478cdf0e10cSrcweir             for ( sal_Int32 m = 0; m < m_aTypes.getLength(); ++m )
479cdf0e10cSrcweir             {
480cdf0e10cSrcweir                 if ( m_aTypes[ m ] == uno::TypeClass_CONSTANT )
481cdf0e10cSrcweir                 {
482cdf0e10cSrcweir                     bIncludeConstants = true;
483cdf0e10cSrcweir                     break;
484cdf0e10cSrcweir                 }
485cdf0e10cSrcweir             }
486cdf0e10cSrcweir 
487cdf0e10cSrcweir         }
488cdf0e10cSrcweir 
489cdf0e10cSrcweir         if ( bIncludeConstants )
490cdf0e10cSrcweir         {
491cdf0e10cSrcweir             if ( m_aModuleKeys.front()->getValueType()
492cdf0e10cSrcweir                     == registry::RegistryValueType_BINARY )
493cdf0e10cSrcweir             {
494cdf0e10cSrcweir                 try
495cdf0e10cSrcweir                 {
496cdf0e10cSrcweir                     uno::Sequence< sal_Int8 > aBytes(
497cdf0e10cSrcweir                         m_aModuleKeys.front()->getBinaryValue() );
498cdf0e10cSrcweir 
499cdf0e10cSrcweir                     typereg::Reader aReader(
500cdf0e10cSrcweir                         aBytes.getConstArray(), aBytes.getLength(), false,
501cdf0e10cSrcweir                         TYPEREG_VERSION_1);
502cdf0e10cSrcweir 
503cdf0e10cSrcweir                     if ( aReader.getTypeClass() == RT_TYPE_MODULE )
504cdf0e10cSrcweir                     {
505cdf0e10cSrcweir                         sal_uInt16 nFields = aReader.getFieldCount();
506cdf0e10cSrcweir                         while ( nFields-- )
507cdf0e10cSrcweir                         {
508cdf0e10cSrcweir                             rtl::OUStringBuffer aName(
509cdf0e10cSrcweir                                 aReader.getTypeName().replace( '/', '.' ) );
510cdf0e10cSrcweir                             aName.appendAscii( "." );
511cdf0e10cSrcweir                             aName.append( aReader.getFieldName( nFields ) );
512cdf0e10cSrcweir 
513cdf0e10cSrcweir                             uno::Any aValue(
514cdf0e10cSrcweir                                 getRTValue(
515cdf0e10cSrcweir                                     aReader.getFieldValue( nFields ) ) );
516cdf0e10cSrcweir 
517cdf0e10cSrcweir                             m_aTypeDescs.push_back(
518cdf0e10cSrcweir                                 new IndividualConstantTypeDescriptionImpl(
519cdf0e10cSrcweir                                     aName.makeStringAndClear(), aValue,
520cdf0e10cSrcweir                                     ( ( aReader.getFieldFlags( nFields )
521cdf0e10cSrcweir                                         & RT_ACCESS_PUBLISHED )
522cdf0e10cSrcweir                                       != 0 ) ) );
523cdf0e10cSrcweir                         }
524cdf0e10cSrcweir                     }
525cdf0e10cSrcweir                 }
526cdf0e10cSrcweir                 catch ( registry::InvalidRegistryException const & )
527cdf0e10cSrcweir                 {
528cdf0e10cSrcweir                     // getBinaryValue
529cdf0e10cSrcweir 
530cdf0e10cSrcweir                     OSL_ENSURE( sal_False,
531cdf0e10cSrcweir                                 "TypeDescriptionEnumerationImpl::queryMore "
532cdf0e10cSrcweir                                 "- Caught InvalidRegistryException!" );
533cdf0e10cSrcweir                 }
534cdf0e10cSrcweir             }
535cdf0e10cSrcweir         }
536cdf0e10cSrcweir 
537cdf0e10cSrcweir         /////////////////////////////////////////////////////////////////////
538cdf0e10cSrcweir 
539cdf0e10cSrcweir /*
540cdf0e10cSrcweir    @@@ m_aModuleKeys.front() may have open sub keys (may be contained in
541cdf0e10cSrcweir        both m_aModuleKeys and m_aCurrentModuleSubKeys)!
542cdf0e10cSrcweir 
543cdf0e10cSrcweir         try
544cdf0e10cSrcweir         {
545cdf0e10cSrcweir            m_aModuleKeys.front()->closeKey();
546cdf0e10cSrcweir         }
547cdf0e10cSrcweir         catch ( registry::InvalidRegistryException const & )
548cdf0e10cSrcweir         {
549cdf0e10cSrcweir             OSL_ENSURE( sal_False,
550cdf0e10cSrcweir                         "TypeDescriptionEnumerationImpl::queryMore "
551cdf0e10cSrcweir                         "- Caught InvalidRegistryException!" );
552cdf0e10cSrcweir         }
553cdf0e10cSrcweir */
554cdf0e10cSrcweir         // We're done with this module key, even if there were errors.
555cdf0e10cSrcweir         m_aModuleKeys.pop_front();
556cdf0e10cSrcweir     }
557cdf0e10cSrcweir 
558cdf0e10cSrcweir     // unreachable
559cdf0e10cSrcweir }
560cdf0e10cSrcweir 
561cdf0e10cSrcweir //=========================================================================
562cdf0e10cSrcweir uno::Reference< reflection::XTypeDescription >
queryNext()563cdf0e10cSrcweir TypeDescriptionEnumerationImpl::queryNext()
564cdf0e10cSrcweir {
565cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
566cdf0e10cSrcweir 
567cdf0e10cSrcweir     for (;;)
568cdf0e10cSrcweir     {
569cdf0e10cSrcweir         if ( !queryMore() )
570cdf0e10cSrcweir             return uno::Reference< reflection::XTypeDescription >();
571cdf0e10cSrcweir 
572cdf0e10cSrcweir         uno::Reference< reflection::XTypeDescription > xTD;
573cdf0e10cSrcweir 
574cdf0e10cSrcweir         if ( !m_aTypeDescs.empty() )
575cdf0e10cSrcweir         {
576cdf0e10cSrcweir             xTD = m_aTypeDescs.front();
577cdf0e10cSrcweir             m_aTypeDescs.pop_front();
578cdf0e10cSrcweir             return xTD;
579cdf0e10cSrcweir         }
580cdf0e10cSrcweir 
581cdf0e10cSrcweir         // Note: xKey is already opened.
582cdf0e10cSrcweir         uno::Reference< registry::XRegistryKey >
583cdf0e10cSrcweir             xKey( m_aCurrentModuleSubKeys.front() );
584cdf0e10cSrcweir /*
585cdf0e10cSrcweir    @@@ xKey may still be contained in m_aModuleKeys, too
586cdf0e10cSrcweir 
587cdf0e10cSrcweir         // closes key in it's dtor (which is
588cdf0e10cSrcweir         // called even in case of exceptions).
589cdf0e10cSrcweir         RegistryKeyCloser aCloser( xKey );
590cdf0e10cSrcweir */
591cdf0e10cSrcweir         try
592cdf0e10cSrcweir         {
593cdf0e10cSrcweir             {
594cdf0e10cSrcweir                 if ( xKey->isValid() )
595cdf0e10cSrcweir                 {
596cdf0e10cSrcweir                     if ( xKey->getValueType()
597cdf0e10cSrcweir                             == registry::RegistryValueType_BINARY )
598cdf0e10cSrcweir                     {
599cdf0e10cSrcweir                         uno::Sequence< sal_Int8 > aBytes(
600cdf0e10cSrcweir                             xKey->getBinaryValue() );
601cdf0e10cSrcweir 
602cdf0e10cSrcweir                         xTD = createTypeDescription( aBytes,
603cdf0e10cSrcweir                                                      m_xTDMgr,
604cdf0e10cSrcweir                                                      false );
605cdf0e10cSrcweir                         OSL_ENSURE( xTD.is(),
606cdf0e10cSrcweir                             "TypeDescriptionEnumerationImpl::queryNext "
607cdf0e10cSrcweir                             "- No XTypeDescription created!" );
608cdf0e10cSrcweir                     }
609cdf0e10cSrcweir                 }
610cdf0e10cSrcweir                 else
611cdf0e10cSrcweir                 {
612cdf0e10cSrcweir                     OSL_ENSURE( sal_False,
613cdf0e10cSrcweir                         "TypeDescriptionEnumerationImpl::queryNext "
614cdf0e10cSrcweir                         "- Invalid registry key!" );
615cdf0e10cSrcweir                 }
616cdf0e10cSrcweir             }
617cdf0e10cSrcweir         }
618cdf0e10cSrcweir         catch ( registry::InvalidRegistryException const & )
619cdf0e10cSrcweir         {
620cdf0e10cSrcweir             // getValueType, getBinaryValue
621cdf0e10cSrcweir 
622cdf0e10cSrcweir             OSL_ENSURE( sal_False,
623cdf0e10cSrcweir                         "TypeDescriptionEnumerationImpl::queryNext "
624cdf0e10cSrcweir                         "- Caught InvalidRegistryException!" );
625cdf0e10cSrcweir         }
626cdf0e10cSrcweir 
627cdf0e10cSrcweir         // We're done with this key, even if there were errors.
628cdf0e10cSrcweir         m_aCurrentModuleSubKeys.pop_front();
629cdf0e10cSrcweir 
630cdf0e10cSrcweir         if ( xTD.is() )
631cdf0e10cSrcweir             return xTD;
632cdf0e10cSrcweir 
633cdf0e10cSrcweir         // next try...
634cdf0e10cSrcweir 
635cdf0e10cSrcweir     } // for (;;)
636cdf0e10cSrcweir }
637cdf0e10cSrcweir 
638cdf0e10cSrcweir } // namespace stoc_rdbtdp
639cdf0e10cSrcweir 
640