1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: regcomplazy.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
34 #include <osl/diagnose.h>
35 #include <osl/thread.h>
36 #include <osl/file.hxx>
37 #include <rtl/strbuf.hxx>
38 #include <rtl/ustrbuf.hxx>
42 #include <registry/registry.hxx>
45 #define OUSTR(x) ::rtl::OUString::createFromAscii( x )
46 #define OSToOUS(x) ::rtl::OStringToOUString(x, osl_getThreadTextEncoding())
47 #define OUSToOS(x) ::rtl::OUStringToOString(x, osl_getThreadTextEncoding())
48 using namespace ::rtl
;
50 typedef ::std::vector
< ::rtl::OString
> OSVector
;
52 typedef ::std::pair
< ::rtl::OString
, OSVector
> DataPair
;
54 typedef ::std::vector
< DataPair
> DataVector
;
56 struct CompDescriptor
{
57 OString sImplementationName
;
58 OString sComponentName
;
60 OSVector vSupportedServices
;
64 typedef ::std::vector
< CompDescriptor
> CDescrVector
;
66 static void print_options() SAL_THROW( () )
69 "\nusage: regcomplazy [-v]registry_file cmp_descr_file ...\n\n"
70 "Register a cmponent using a comp description file.\n"
71 "Option -v prints verbose output on stdout.\n" );
74 static bool checkImplValue(RegistryValueList
<sal_Char
*>* pValueList
, OString sImplName
) {
75 for (sal_uInt32 i
=0; i
< pValueList
->getLength(); i
++) {
76 if (sImplName
.equals(pValueList
->getElement(i
)))
83 //==================================================================================================
84 SAL_IMPLEMENT_MAIN_WITH_ARGS(argc
, argv
)
92 bool bVerbose
= false;
94 if ('-' == argv
[ nPos
][ 0 ] && 'v' == argv
[ nPos
][ 1 ])
96 if ('\0' != argv
[ nPos
][ 2 ])
105 OUString
sys_path( OUSTR( argv
[ nPos
] ) );
107 oslFileError rc
= osl_getFileURLFromSystemPath( sys_path
.pData
, ®_url
.pData
);
108 if (osl_File_E_None
!= rc
)
111 fprintf( stderr
, "\nERROR: cannot make file url out of %s\n", argv
[nPos
]);
115 FILE* fDescr
= fopen(argv
[ ++nPos
], "r");
116 OStringBuffer
sBuffer(512);
119 size_t totalSize
= 0;
123 while ( !feof(fDescr
) )
125 if ( (readSize
= fread(pBuffer
, 1, 512, fDescr
)) > 0
126 && !ferror(fDescr
) ) {
127 totalSize
+= readSize
;
128 if (totalSize
>= 512)
129 sBuffer
.ensureCapacity(totalSize
* 2);
131 sBuffer
.append(pBuffer
, readSize
);
136 OString sDescr
= sBuffer
.makeStringAndClear();
137 sal_Int32 nTokenIndex
= 0;
140 CompDescriptor descr
;
144 OString sTmp
= sDescr
.getToken(0, '\x0A', nTokenIndex
);
145 OString
sToken(sTmp
);
146 if (sTmp
.pData
->buffer
[sTmp
.getLength()-1] == '\x0D')
147 sToken
= sTmp
.copy(0, sTmp
.getLength()-1);
149 if (sToken
.indexOf("[Data]") >= 0) {
151 OString sTmp2
= sDescr
.getToken(0, '\x0A', nTokenIndex
);
152 OString
sToken2(sTmp2
);
153 if (sTmp2
.pData
->buffer
[sTmp2
.getLength()-1] == '\x0D')
154 sToken2
= sTmp2
.copy(0, sTmp2
.getLength()-1);
156 if ((sToken2
.getLength() > 0) && (sToken2
.pData
->buffer
[0] != '[')) {
157 OString
dataKey(sToken2
.copy(0, sToken2
.indexOf('=')));
158 OString
sValues(sToken2
.copy(sToken2
.indexOf('=')+1));
159 sal_Int32 nVIndex
= 0;
162 OString sValue
= sValues
.getToken(0, ';', nVIndex
);
163 vValues
.push_back(sValue
);
164 } while (nVIndex
>= 0 );
165 descr
.vData
.push_back(DataPair(dataKey
, vValues
));
168 } while (nTokenIndex
>= 0 );
170 if ( sToken
.indexOf("[ComponentDescriptor]") >= 0) {
174 vDescr
.push_back(descr
);
176 descr
= CompDescriptor();
178 else if ( sToken
.indexOf("ImplementationName=") >= 0) {
179 descr
.sImplementationName
= sToken
.copy(19);
181 else if ( sToken
.indexOf("ComponentName=") >= 0) {
182 descr
.sComponentName
= sToken
.copy(14);
184 else if ( sToken
.indexOf("LoaderName=") >= 0) {
185 descr
.sLoaderName
= sToken
.copy(11);
187 else if ( (sToken
.indexOf("[SupportedServices]") < 0) &&
188 (sToken
.getLength() > 0) &&
189 (sToken
.pData
->buffer
[0] != '[') ) {
190 descr
.vSupportedServices
.push_back(sToken
);
192 } while (nTokenIndex
>= 0 );
193 // insert the last descriptor
194 vDescr
.push_back(descr
);
196 Registry
*pReg
= new Registry
;
198 RegistryKey rootKey
, key
, subKey
, serviceKey
;
200 if (pReg
->open(reg_url
, REG_READWRITE
))
202 if (pReg
->create(reg_url
))
205 fprintf(stderr
, "ERROR: open registry \"%s\" failed\n", argv
[1]);
209 if (pReg
->openRootKey(rootKey
)) {
211 fprintf(stderr
, "ERROR: open root key failed\n");
215 CDescrVector::const_iterator comp_iter
= vDescr
.begin();
217 OString sImplName
= (*comp_iter
).sImplementationName
;
218 OUStringBuffer sbImpl
;
219 sbImpl
.appendAscii("/IMPLEMENTATIONS/");
220 sbImpl
.append(OSToOUS(sImplName
));
221 OUString sImplKeyName
= sbImpl
.makeStringAndClear();
223 if (rootKey
.openKey(sImplKeyName
, key
) == REG_NO_ERROR
) {
225 fprintf(stderr
, "WARNING: implementation entry for \"%s\" already exists, existing entries are overwritten\n", sImplName
.getStr());
228 if (rootKey
.createKey(sImplKeyName
, key
)) {
230 fprintf(stderr
, "ERROR: can't create new implementation entry \"%s\".\n", sImplName
.getStr());
236 OString sLoaderName
= (*comp_iter
).sLoaderName
;
237 OUString
usKeyName(OUSTR("UNO/ACTIVATOR"));
238 key
.createKey(usKeyName
, subKey
);
239 subKey
.setValue(OUString(), RG_VALUETYPE_STRING
,
240 (sal_Char
*)sLoaderName
.getStr(), sLoaderName
.getLength()+1);
242 OString sCompName
= (*comp_iter
).sComponentName
;
243 usKeyName
= OUSTR("UNO/LOCATION");
244 key
.createKey(usKeyName
, subKey
);
245 subKey
.setValue(OUString(), RG_VALUETYPE_STRING
,
246 (sal_Char
*)sCompName
.getStr(), sCompName
.getLength()+1);
248 if ((*comp_iter
).vData
.size() > 0) {
249 usKeyName
= OUSTR("DATA");
250 RegistryKey dataKey
, valueKey
;
251 key
.createKey(usKeyName
, dataKey
);
253 DataVector::const_iterator data_iter
= ((*comp_iter
).vData
).begin();
255 OUString
sDataKey(OSToOUS((*data_iter
).first
));
256 dataKey
.createKey(sDataKey
, valueKey
);
258 OSVector::const_iterator value_iter
= ((*data_iter
).second
).begin();
259 int vlen
= (*data_iter
).second
.size();
260 sal_Char
** pValueList
= (sal_Char
**)rtl_allocateZeroMemory(
261 vlen
* sizeof(sal_Char
*));
264 pValueList
[i
] = (sal_Char
*)rtl_allocateZeroMemory(
265 (*value_iter
).getLength()+1 * sizeof(sal_Char
));
266 rtl_copyMemory(pValueList
[i
], (sal_Char
*)(*value_iter
).getStr(),
267 (*value_iter
).getLength()+1);
270 } while (value_iter
!= (*data_iter
).second
.end());
272 valueKey
.setStringListValue(OUString(), pValueList
, vlen
);
275 for (i
=0; i
<vlen
; i
++)
276 rtl_freeMemory(pValueList
[i
]);
277 rtl_freeMemory(pValueList
);
280 } while (data_iter
!= (*comp_iter
).vData
.end());
283 usKeyName
= OUSTR("UNO/SERVICES");
284 key
.createKey(usKeyName
, subKey
);
286 rootKey
.createKey(OUSTR("/SERVICES"), serviceKey
);
288 OSVector::const_iterator serv_iter
= ((*comp_iter
).vSupportedServices
).begin();
289 OUString usServiceKeyName
;
291 usServiceKeyName
= OSToOUS(*serv_iter
);
292 // write service key in impl section
293 subKey
.createKey(usServiceKeyName
, key
);
295 if (serviceKey
.openKey(usServiceKeyName
, key
) == REG_NO_ERROR
) {
296 RegistryValueList
<sal_Char
*> valueList
;
297 serviceKey
.getStringListValue(usServiceKeyName
, valueList
);
298 if ( checkImplValue(&valueList
, sImplName
) ) {
303 sal_uInt32 nServices
= valueList
.getLength()+1;
304 sal_Char
** pImplList
= (sal_Char
**)rtl_allocateZeroMemory(
305 nServices
* sizeof(sal_Char
*));
306 pImplList
[0] = (sal_Char
*)rtl_allocateZeroMemory(
307 sImplName
.getLength()+1 * sizeof(sal_Char
));
308 rtl_copyMemory(pImplList
[0], (sal_Char
*)sImplName
.getStr(),
309 sImplName
.getLength()+1);
310 for (sal_uInt32 i
=0; i
< valueList
.getLength(); i
++) {
311 pImplList
[i
+1]=valueList
.getElement(i
);
313 key
.setStringListValue(OUString(), pImplList
, nServices
);
316 rtl_freeMemory(pImplList
[0]);
317 rtl_freeMemory(pImplList
);
320 serviceKey
.createKey(usServiceKeyName
, key
);
322 sal_Char
* pImplList
[1];
323 pImplList
[0] = (sal_Char
*)rtl_allocateZeroMemory(
324 sImplName
.getLength()+1 * sizeof(sal_Char
));
325 rtl_copyMemory(pImplList
[0], (sal_Char
*)sImplName
.getStr(),
326 sImplName
.getLength()+1);
327 key
.setStringListValue(OUString(), pImplList
, 1);
330 rtl_freeMemory(pImplList
[0]);
333 } while (serv_iter
!= (*comp_iter
).vSupportedServices
.end());
336 } while (comp_iter
!= vDescr
.end());
340 serviceKey
.closeKey();