xref: /AOO41X/main/rdbmaker/source/codemaker/typemanager.cxx (revision 9f73e17b5d6c8e71740f4303348ff699be6c9e18)
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