xref: /trunk/main/codemaker/source/codemaker/typemanager.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_codemaker.hxx"
26 
27 #include "rtl/alloc.h"
28 #include "codemaker/typemanager.hxx"
29 #include "registry/reader.hxx"
30 #include "registry/version.h"
31 
32 using namespace rtl;
33 
TypeManager()34 TypeManager::TypeManager()
35 {
36     m_pImpl = new TypeManagerImpl();
37     acquire();
38 }
39 
~TypeManager()40 TypeManager::~TypeManager()
41 {
42     release();
43 }
44 
acquire()45 sal_Int32 TypeManager::acquire()
46 {
47     return osl_incrementInterlockedCount(&m_pImpl->m_refCount);
48 }
49 
release()50 sal_Int32 TypeManager::release()
51 {
52     sal_Int32 refCount = 0;
53     if (0 == (refCount = osl_decrementInterlockedCount(&m_pImpl->m_refCount)) )
54     {
55         delete m_pImpl;
56     }
57     return refCount;
58 }
59 
isBaseType(const::rtl::OString & name)60 sal_Bool TypeManager::isBaseType(const ::rtl::OString& name)
61 {
62     if ( name.equals(OString("short")) )
63         return sal_True;
64     if ( name.equals(OString("unsigned short")) )
65         return sal_True;
66     if ( name.equals(OString("long")) )
67         return sal_True;
68     if ( name.equals(OString("unsigned long")) )
69         return sal_True;
70     if ( name.equals(OString("hyper")) )
71         return sal_True;
72     if ( name.equals(OString("unsigned hyper")) )
73         return sal_True;
74     if ( name.equals(OString("string")) )
75         return sal_True;
76     if ( name.equals(OString("boolean")) )
77         return sal_True;
78     if ( name.equals(OString("char")) )
79         return sal_True;
80     if ( name.equals(OString("byte")) )
81         return sal_True;
82     if ( name.equals(OString("any")) )
83         return sal_True;
84     if ( name.equals(OString("type")) )
85         return sal_True;
86     if ( name.equals(OString("float")) )
87         return sal_True;
88     if ( name.equals(OString("double")) )
89         return sal_True;
90     if ( name.equals(OString("void")) )
91         return sal_True;
92 
93     return sal_False;
94 }
95 
RegistryTypeManager()96 RegistryTypeManager::RegistryTypeManager()
97 {
98     m_pImpl = new RegistryTypeManagerImpl();
99     acquire();
100 }
101 
~RegistryTypeManager()102 RegistryTypeManager::~RegistryTypeManager()
103 {
104     release();
105 }
106 
acquire()107 void RegistryTypeManager::acquire()
108 {
109     TypeManager::acquire();
110 }
111 
release()112 void RegistryTypeManager::release()
113 {
114     if (0 == TypeManager::release())
115     {
116         freeRegistries();
117 
118         delete m_pImpl;
119     }
120 }
121 
init(const StringVector & regFiles,StringVector const & extraFiles)122 sal_Bool RegistryTypeManager::init(
123     const StringVector& regFiles,
124     StringVector const & extraFiles )
125 {
126     if (regFiles.empty())
127         return sal_False;
128 
129     StringVector::const_iterator iter = regFiles.begin();
130 
131     Registry tmpReg;
132     while (iter != regFiles.end())
133     {
134         if (!tmpReg.open( convertToFileUrl(*iter), REG_READONLY))
135             m_pImpl->m_registries.push_back(new Registry(tmpReg));
136         else
137         {
138             freeRegistries();
139             return sal_False;
140         }
141         ++iter;
142     }
143     iter = extraFiles.begin();
144     while (iter != extraFiles.end())
145     {
146         if (!tmpReg.open( convertToFileUrl(*iter), REG_READONLY))
147             m_pImpl->m_extra_registries.push_back(new Registry(tmpReg));
148         else
149         {
150             freeRegistries();
151             return sal_False;
152         }
153         ++iter;
154     }
155 
156     return sal_True;
157 }
158 
getTypeName(RegistryKey & rTypeKey) const159 ::rtl::OString RegistryTypeManager::getTypeName(RegistryKey& rTypeKey) const
160 {
161     OString typeName = OUStringToOString(rTypeKey.getName(), RTL_TEXTENCODING_UTF8);
162 
163     if (m_pImpl->m_base.getLength() > 1)
164         typeName = typeName.copy(typeName.indexOf('/', 1) + 1);
165     else
166         typeName = typeName.copy(1);
167 
168     return typeName;
169 }
170 
getTypeReader(const OString & name,sal_Bool * pIsExtraType) const171 typereg::Reader RegistryTypeManager::getTypeReader(
172     const OString& name, sal_Bool * pIsExtraType ) const
173 {
174     typereg::Reader reader;
175     RegistryKey key(searchTypeKey(name, pIsExtraType));
176 
177     if (key.isValid())
178     {
179         RegValueType    valueType;
180         sal_uInt32      valueSize;
181 
182         if (!key.getValueInfo(OUString(), &valueType, &valueSize))
183         {
184             sal_uInt8*  pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
185             if (!key.getValue(OUString(), pBuffer))
186             {
187                 reader = typereg::Reader(
188                     pBuffer, valueSize, true, TYPEREG_VERSION_1);
189             }
190             rtl_freeMemory(pBuffer);
191         }
192     }
193     return reader;
194 }
195 
getTypeReader(RegistryKey & rTypeKey) const196 typereg::Reader RegistryTypeManager::getTypeReader(RegistryKey& rTypeKey) const
197 {
198     typereg::Reader reader;
199 
200     if (rTypeKey.isValid())
201     {
202         RegValueType    valueType;
203         sal_uInt32      valueSize;
204 
205         if (!rTypeKey.getValueInfo(OUString(), &valueType, &valueSize))
206         {
207             sal_uInt8*  pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
208             if (!rTypeKey.getValue(OUString(), pBuffer))
209             {
210                 reader = typereg::Reader(
211                     pBuffer, valueSize, true, TYPEREG_VERSION_1);
212             }
213             rtl_freeMemory(pBuffer);
214         }
215     }
216     return reader;
217 }
218 
219 
getTypeClass(const OString & name) const220 RTTypeClass RegistryTypeManager::getTypeClass(const OString& name) const
221 {
222     if (m_pImpl->m_t2TypeClass.count(name) > 0)
223     {
224         return m_pImpl->m_t2TypeClass[name];
225     } else
226     {
227         RegistryKey key(searchTypeKey(name));
228 
229         if (key.isValid())
230         {
231             RegValueType    valueType;
232             sal_uInt32      valueSize;
233 
234             if (!key.getValueInfo(OUString(), &valueType, &valueSize))
235             {
236                 sal_uInt8*  pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
237                 if (!key.getValue(OUString(), pBuffer))
238                 {
239                     typereg::Reader reader(
240                         pBuffer, valueSize, false, TYPEREG_VERSION_1);
241 
242                     RTTypeClass ret = reader.getTypeClass();
243 
244                     rtl_freeMemory(pBuffer);
245 
246                     m_pImpl->m_t2TypeClass[name] = ret;
247                     return ret;
248                 }
249                 rtl_freeMemory(pBuffer);
250             }
251         }
252     }
253 
254     return RT_TYPE_INVALID;
255 }
256 
getTypeClass(RegistryKey & rTypeKey) const257 RTTypeClass RegistryTypeManager::getTypeClass(RegistryKey& rTypeKey) const
258 {
259     OString name = getTypeName(rTypeKey);
260 
261     if (m_pImpl->m_t2TypeClass.count(name) > 0)
262     {
263         return m_pImpl->m_t2TypeClass[name];
264     } else
265     {
266         if (rTypeKey.isValid())
267         {
268             RegValueType    valueType;
269             sal_uInt32      valueSize;
270 
271             if (!rTypeKey.getValueInfo(OUString(), &valueType, &valueSize))
272             {
273                 sal_uInt8*  pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
274                 if (!rTypeKey.getValue(OUString(), pBuffer))
275                 {
276                     typereg::Reader reader(
277                         pBuffer, valueSize, false, TYPEREG_VERSION_1);
278 
279                     RTTypeClass ret = reader.getTypeClass();
280 
281                     rtl_freeMemory(pBuffer);
282 
283                     m_pImpl->m_t2TypeClass[name] = ret;
284                     return ret;
285                 }
286                 rtl_freeMemory(pBuffer);
287             }
288         }
289     }
290 
291     return RT_TYPE_INVALID;
292 }
293 
setBase(const OString & base)294 void RegistryTypeManager::setBase(const OString& base)
295 {
296 
297     if (base.lastIndexOf('/') == (base.getLength() - 1))
298         m_pImpl->m_base += base.copy(0, base.lastIndexOf('/') - 1);
299     else
300         m_pImpl->m_base += base;
301 }
302 
freeRegistries()303 void RegistryTypeManager::freeRegistries()
304 {
305     RegistryList::const_iterator iter = m_pImpl->m_registries.begin();
306     while (iter != m_pImpl->m_registries.end())
307     {
308         delete *iter;
309         ++iter;
310     }
311     iter = m_pImpl->m_extra_registries.begin();
312     while (iter != m_pImpl->m_extra_registries.end())
313     {
314         delete *iter;
315         ++iter;
316     }
317 }
318 
searchTypeKey(const OString & name_,sal_Bool * pIsExtraType) const319 RegistryKey RegistryTypeManager::searchTypeKey(const OString& name_, sal_Bool * pIsExtraType )
320     const
321 {
322     OUString name( OStringToOUString(m_pImpl->m_base + "/" + name_, RTL_TEXTENCODING_UTF8) );
323     RegistryKey key, rootKey;
324 
325     RegistryList::const_iterator iter = m_pImpl->m_registries.begin();
326     while (iter != m_pImpl->m_registries.end())
327     {
328         if (!(*iter)->openRootKey(rootKey))
329         {
330             if (!rootKey.openKey(name, key))
331             {
332                 if (pIsExtraType)
333                     *pIsExtraType = sal_False;
334                 return key;
335             }
336         }
337         ++iter;
338     }
339     iter = m_pImpl->m_extra_registries.begin();
340     while (iter != m_pImpl->m_extra_registries.end())
341     {
342         if (!(*iter)->openRootKey(rootKey))
343         {
344             if (!rootKey.openKey(name, key))
345             {
346                 if (pIsExtraType)
347                     *pIsExtraType = sal_True;
348                 break;
349             }
350         }
351         ++iter;
352     }
353 
354     return key;
355 }
356 
getTypeKeys(const::rtl::OString & name_) const357 RegistryKeyList RegistryTypeManager::getTypeKeys(const ::rtl::OString& name_) const
358 {
359     RegistryKeyList keyList= RegistryKeyList();
360     OString tmpName;
361     if ( name_.equals("/") || name_.equals(m_pImpl->m_base) ) {
362         tmpName = m_pImpl->m_base;
363     } else {
364         if ( m_pImpl->m_base.equals("/") )
365             tmpName = name_;
366         else
367             tmpName = m_pImpl->m_base + "/" + name_;
368     }
369 
370     OUString name( OStringToOUString(tmpName, RTL_TEXTENCODING_UTF8) );
371     RegistryKey key, rootKey;
372 
373     RegistryList::const_iterator iter = m_pImpl->m_registries.begin();
374     while (iter != m_pImpl->m_registries.end())
375     {
376         if (!(*iter)->openRootKey(rootKey))
377         {
378             if (!rootKey.openKey(name, key))
379             {
380                 keyList.push_back(KeyPair(key, sal_False));
381             }
382         }
383         ++iter;
384     }
385     iter = m_pImpl->m_extra_registries.begin();
386     while (iter != m_pImpl->m_extra_registries.end())
387     {
388         if (!(*iter)->openRootKey(rootKey))
389         {
390             if (!rootKey.openKey(name, key))
391             {
392                 keyList.push_back(KeyPair(key, sal_True));
393             }
394         }
395         ++iter;
396     }
397 
398     return keyList;
399 }
400