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