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