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 #include <rtl/alloc.h>
25 #include <osl/file.hxx>
26 #include <codemaker/typemanager.hxx>
27
28 using namespace rtl;
29
TypeManager()30 TypeManager::TypeManager()
31 {
32 m_pImpl = new TypeManagerImpl();
33 acquire();
34 }
35
~TypeManager()36 TypeManager::~TypeManager()
37 {
38 release();
39 }
40
acquire()41 sal_Int32 TypeManager::acquire()
42 {
43 return osl_incrementInterlockedCount(&m_pImpl->m_refCount);
44 }
45
release()46 sal_Int32 TypeManager::release()
47 {
48 sal_Int32 refCount = 0;
49 if (0 == (refCount = osl_decrementInterlockedCount(&m_pImpl->m_refCount)) )
50 {
51 delete m_pImpl;
52 }
53 return refCount;;
54 }
55
RegistryTypeManager()56 RegistryTypeManager::RegistryTypeManager()
57 {
58 m_pImpl = new RegistryTypeManagerImpl();
59 acquire();
60 }
61
~RegistryTypeManager()62 RegistryTypeManager::~RegistryTypeManager()
63 {
64 release();
65 }
66
acquire()67 void RegistryTypeManager::acquire()
68 {
69 TypeManager::acquire();
70 }
71
release()72 void RegistryTypeManager::release()
73 {
74 if (0 == TypeManager::release())
75 {
76 if (m_pImpl->m_pMergedRegistry)
77 {
78 if (m_pImpl->m_pMergedRegistry->isValid())
79 {
80 m_pImpl->m_pMergedRegistry->destroy(OUString());
81 }
82
83 delete m_pImpl->m_pMergedRegistry;
84 }
85
86 if (m_pImpl->m_registries.size() > 0)
87 {
88 freeRegistries();
89 }
90
91 delete m_pImpl;
92 }
93 }
94
init(sal_Bool bMerged,const StringVector & regFiles)95 sal_Bool RegistryTypeManager::init(sal_Bool bMerged, const StringVector& regFiles)
96 {
97 m_pImpl->m_isMerged = bMerged && (regFiles.size() > 1);
98
99 if (regFiles.empty())
100 return sal_False;
101
102 StringVector::const_iterator iter = regFiles.begin();
103
104 Registry tmpReg;
105 while (iter != regFiles.end())
106 {
107 if (!tmpReg.open( convertToFileUrl(*iter), REG_READONLY))
108 m_pImpl->m_registries.push_back(new Registry(tmpReg));
109 else
110 {
111 freeRegistries();
112 return sal_False;
113 }
114 iter++;
115 }
116
117 if (m_pImpl->m_isMerged)
118 {
119 Registry *pTmpReg = new Registry;
120 OUString tmpName;
121 osl::FileBase::createTempFile(0, 0, &tmpName);
122 if (!pTmpReg->create(tmpName))
123 {
124 RegistryKey rootKey;
125 RegError ret = REG_NO_ERROR;
126 OUString aRoot( RTL_CONSTASCII_USTRINGPARAM("/") );
127 iter = regFiles.begin();
128 pTmpReg->openRootKey(rootKey);
129
130 while (iter != regFiles.end())
131 {
132 if ( (ret = pTmpReg->mergeKey(rootKey, aRoot, convertToFileUrl( *iter ))) )
133 {
134 if (ret != REG_MERGE_CONFLICT)
135 {
136 freeRegistries();
137 rootKey.closeKey();
138 pTmpReg->destroy( OUString() );
139 delete pTmpReg;
140 return sal_False;
141 }
142 }
143 iter++;
144 }
145
146 m_pImpl->m_pMergedRegistry = pTmpReg;
147 freeRegistries();
148 } else
149 {
150 delete pTmpReg;
151 freeRegistries();
152 return sal_False;
153 }
154 }
155
156 return sal_True;
157 }
158
getTypeReader(const OString & name)159 TypeReader RegistryTypeManager::getTypeReader(const OString& name)
160 {
161 TypeReader reader;
162 RegistryKey key(searchTypeKey(name));
163
164 if (key.isValid())
165 {
166 RegValueType valueType;
167 sal_uInt32 valueSize;
168
169 if (!key.getValueInfo(OUString(), &valueType, &valueSize))
170 {
171 sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
172 if (!key.getValue(OUString(), pBuffer))
173 {
174 reader = TypeReader(pBuffer, valueSize, sal_True);
175 }
176 rtl_freeMemory(pBuffer);
177 }
178 }
179 return reader;
180 }
181
getTypeClass(const OString & name)182 RTTypeClass RegistryTypeManager::getTypeClass(const OString& name)
183 {
184 if (m_pImpl->m_t2TypeClass.count(name) > 0)
185 {
186 return m_pImpl->m_t2TypeClass[name];
187 } else
188 {
189 RegistryKey key(searchTypeKey(name));
190
191 if (key.isValid())
192 {
193 RegValueType valueType;
194 sal_uInt32 valueSize;
195
196 if (!key.getValueInfo(OUString(), &valueType, &valueSize))
197 {
198 sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
199 if (!key.getValue(OUString(), pBuffer))
200 {
201 TypeReader reader(pBuffer, valueSize, sal_False);
202
203 RTTypeClass ret = reader.getTypeClass();
204
205 rtl_freeMemory(pBuffer);
206
207 m_pImpl->m_t2TypeClass[name] = ret;
208 return ret;
209 }
210 rtl_freeMemory(pBuffer);
211 }
212 }
213 }
214
215 return RT_TYPE_INVALID;
216 }
217
setBase(const OString & base)218 void RegistryTypeManager::setBase(const OString& base)
219 {
220 m_pImpl->m_base = base;
221
222 if (base.lastIndexOf('/') != (base.getLength() - 1))
223 {
224 m_pImpl->m_base += "/";
225 }
226 }
227
freeRegistries()228 void RegistryTypeManager::freeRegistries()
229 {
230 RegistryList::const_iterator iter = m_pImpl->m_registries.begin();
231
232 while (iter != m_pImpl->m_registries.end())
233 {
234 delete *iter;
235
236 iter++;
237 }
238
239 }
240
searchTypeKey(const OString & name)241 RegistryKey RegistryTypeManager::searchTypeKey(const OString& name)
242 {
243 RegistryKey key, rootKey;
244
245 if (m_pImpl->m_isMerged)
246 {
247 if (!m_pImpl->m_pMergedRegistry->openRootKey(rootKey))
248 {
249 rootKey.openKey(OStringToOUString(m_pImpl->m_base + name, RTL_TEXTENCODING_UTF8), key);
250 }
251 } else
252 {
253 RegistryList::const_iterator iter = m_pImpl->m_registries.begin();
254
255 while (iter != m_pImpl->m_registries.end())
256 {
257 if (!(*iter)->openRootKey(rootKey))
258 {
259 if (!rootKey.openKey(OStringToOUString(m_pImpl->m_base + name, RTL_TEXTENCODING_UTF8), key))
260 break;
261 }
262
263 iter++;
264 }
265 }
266
267 return key;
268 }
269
270