1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir 
29*cdf0e10cSrcweir #include "sal/main.h"
30*cdf0e10cSrcweir #include "osl/file.hxx"
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir #include "typelib/typedescription.hxx"
33*cdf0e10cSrcweir 
34*cdf0e10cSrcweir #include "cppuhelper/bootstrap.hxx"
35*cdf0e10cSrcweir #include "cppuhelper/shlib.hxx"
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #include <com/sun/star/lang/XComponent.hpp>
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir #include "uno/environment.hxx"
40*cdf0e10cSrcweir #include "cppu/EnvDcp.hxx"
41*cdf0e10cSrcweir #include "cppu/EnvGuards.hxx"
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir #include <iostream>
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir #ifndef SAL_DLLPREFIX
47*cdf0e10cSrcweir # define SAL_DLLPREFIX  ""
48*cdf0e10cSrcweir #endif
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir using namespace com::sun::star;
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir static rtl::OUString s_comment;
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir static bool s_check_object_is_in(void * pObject)
57*cdf0e10cSrcweir {
58*cdf0e10cSrcweir 	uno::Environment currentEnv(uno::Environment::getCurrent());
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir 	rtl_uString * pOId = NULL;
61*cdf0e10cSrcweir 	currentEnv.get()->pExtEnv->getObjectIdentifier(currentEnv.get()->pExtEnv, &pOId, pObject);
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir 	uno::TypeDescription typeDescription(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface")));
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir 	void * pRegisteredObject = NULL;
67*cdf0e10cSrcweir 	currentEnv.get()->pExtEnv->getRegisteredInterface(currentEnv.get()->pExtEnv,
68*cdf0e10cSrcweir 													  &pRegisteredObject,
69*cdf0e10cSrcweir 													  pOId,
70*cdf0e10cSrcweir 													  (typelib_InterfaceTypeDescription *)typeDescription.get());
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir 	if (pOId) rtl_uString_release(pOId);
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir 	bool result = pRegisteredObject != NULL;
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir 	if (result)
78*cdf0e10cSrcweir 		currentEnv.get()->pExtEnv->releaseInterface(currentEnv.get()->pExtEnv, pRegisteredObject);
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir  	return result;
81*cdf0e10cSrcweir }
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir static void s_test__loadSharedLibComponentFactory(rtl::OUString const & clientPurpose,
84*cdf0e10cSrcweir 												  rtl::OUString const & servicePurpose)
85*cdf0e10cSrcweir {
86*cdf0e10cSrcweir     cppu::EnvGuard envGuard(uno::Environment(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO))
87*cdf0e10cSrcweir                                                + clientPurpose, NULL));
88*cdf0e10cSrcweir     if (clientPurpose.getLength() && !envGuard.is())
89*cdf0e10cSrcweir     {
90*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\t\tcouldn't get purpose env: \""));
91*cdf0e10cSrcweir         s_comment += clientPurpose;
92*cdf0e10cSrcweir         s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\" - FAILURE\n"));
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir         return;
95*cdf0e10cSrcweir     }
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir 	rtl::OString os_clientPurpose(rtl::OUStringToOString(clientPurpose, RTL_TEXTENCODING_ASCII_US));
98*cdf0e10cSrcweir 
99*cdf0e10cSrcweir 	uno::Reference<uno::XInterface> xItf(
100*cdf0e10cSrcweir 		cppu::loadSharedLibComponentFactory(
101*cdf0e10cSrcweir 			rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SAL_DLLPREFIX "TestComponent.uno" SAL_DLLEXTENSION)),
102*cdf0e10cSrcweir #ifdef WIN32
103*cdf0e10cSrcweir 			rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("")),
104*cdf0e10cSrcweir #else
105*cdf0e10cSrcweir 			rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file://../lib/")),
106*cdf0e10cSrcweir #endif
107*cdf0e10cSrcweir 			rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("impl.test.TestComponent")) + servicePurpose,
108*cdf0e10cSrcweir 			uno::Reference<lang::XMultiServiceFactory>(),
109*cdf0e10cSrcweir 			uno::Reference<registry::XRegistryKey>()
110*cdf0e10cSrcweir 			)
111*cdf0e10cSrcweir 		);
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir 	if (!xItf.is())
114*cdf0e10cSrcweir 	{
115*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\t\tgot no object - FAILURE\n"));
116*cdf0e10cSrcweir 		return;
117*cdf0e10cSrcweir 	}
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir 	if (!clientPurpose.equals(servicePurpose) && !s_check_object_is_in(xItf.get()))
120*cdf0e10cSrcweir 	{
121*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\t\tcouldn't find object in current purpose \""));
122*cdf0e10cSrcweir 		s_comment += clientPurpose;
123*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\" - FAILURE\n"));
124*cdf0e10cSrcweir 	}
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir 	if (!cppu::EnvDcp::getPurpose(uno::Environment::getCurrent().getTypeName()).equals(clientPurpose))
127*cdf0e10cSrcweir 	{
128*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\t\tdid not enter client purpose \""));
129*cdf0e10cSrcweir 		s_comment += clientPurpose;
130*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\" - FAILURE\n"));
131*cdf0e10cSrcweir 	}
132*cdf0e10cSrcweir }
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir static void s_test__loadSharedLibComponentFactory__free_free()
135*cdf0e10cSrcweir {
136*cdf0e10cSrcweir 	s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\ts_test__loadSharedLibComponentFactory__free_free\n"));
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir 	s_test__loadSharedLibComponentFactory(rtl::OUString(), rtl::OUString());
139*cdf0e10cSrcweir }
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir static void s_test__loadSharedLibComponentFactory__free_purpose()
142*cdf0e10cSrcweir {
143*cdf0e10cSrcweir 	s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\ts_test__loadSharedLibComponentFactory__free_purpose\n"));
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir 	s_test__loadSharedLibComponentFactory(rtl::OUString(),
146*cdf0e10cSrcweir 										  rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":testenv")));
147*cdf0e10cSrcweir }
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir static void s_test__loadSharedLibComponentFactory__purpose_free()
150*cdf0e10cSrcweir {
151*cdf0e10cSrcweir 	s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\ts_test__loadSharedLibComponentFactory__purpose_free\n"));
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir 	s_test__loadSharedLibComponentFactory(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":testenv")),
154*cdf0e10cSrcweir 										  rtl::OUString());
155*cdf0e10cSrcweir }
156*cdf0e10cSrcweir 
157*cdf0e10cSrcweir static void s_test__loadSharedLibComponentFactory__purpose_purpose()
158*cdf0e10cSrcweir {
159*cdf0e10cSrcweir 	s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\ts_test__loadSharedLibComponentFactory__purpose_purpose\n"));
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir 	s_test__loadSharedLibComponentFactory(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":testenv")),
162*cdf0e10cSrcweir 										  rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":testenv")));
163*cdf0e10cSrcweir }
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir static rtl::OUString s_getSDrive(void)
166*cdf0e10cSrcweir {
167*cdf0e10cSrcweir 	rtl::OUString path;//(RTL_CONSTASCII_USTRINGPARAM("file://"));
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir 	char const * tmp = getenv("SOLARVER");
170*cdf0e10cSrcweir 	path += rtl::OUString(tmp, rtl_str_getLength(tmp), RTL_TEXTENCODING_ASCII_US);
171*cdf0e10cSrcweir 	path += rtl::OUString(SAL_PATHDELIMITER);
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir 	tmp = getenv("INPATH");
174*cdf0e10cSrcweir 	path += rtl::OUString(tmp, rtl_str_getLength(tmp), RTL_TEXTENCODING_ASCII_US);
175*cdf0e10cSrcweir 	path += rtl::OUString(SAL_PATHDELIMITER);
176*cdf0e10cSrcweir #ifdef WIN32
177*cdf0e10cSrcweir 	path += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bin"));
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir #else
180*cdf0e10cSrcweir 	path += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("lib"));
181*cdf0e10cSrcweir #endif
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir 	tmp = getenv("UPDMINOREXT");
184*cdf0e10cSrcweir     if (tmp)
185*cdf0e10cSrcweir         path += rtl::OUString(tmp, rtl_str_getLength(tmp), RTL_TEXTENCODING_ASCII_US);
186*cdf0e10cSrcweir 
187*cdf0e10cSrcweir     osl::FileBase::getFileURLFromSystemPath(path, path);
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir 	return path;
190*cdf0e10cSrcweir }
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir static void s_test__createSimpleRegistry(rtl::OUString const & clientPurpose)
193*cdf0e10cSrcweir {
194*cdf0e10cSrcweir     cppu::EnvGuard envGuard(uno::Environment(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO))
195*cdf0e10cSrcweir                                                + clientPurpose, NULL));
196*cdf0e10cSrcweir     if (clientPurpose.getLength() && !envGuard.is())
197*cdf0e10cSrcweir     {
198*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\t\tcouldn't get purpose env: \""));
199*cdf0e10cSrcweir         s_comment += clientPurpose;
200*cdf0e10cSrcweir         s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\" - FAILURE\n"));
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir         return;
203*cdf0e10cSrcweir     }
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir 	uno::Reference<registry::XSimpleRegistry> registry(cppu::createSimpleRegistry(
206*cdf0e10cSrcweir 														   s_getSDrive()));
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir 	if (!registry.is())
209*cdf0e10cSrcweir 	{
210*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\t\tgot no object - FAILURE\n"));
211*cdf0e10cSrcweir 		return;
212*cdf0e10cSrcweir 	}
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir 	if (clientPurpose.getLength() != 0 && !s_check_object_is_in(registry.get()))
215*cdf0e10cSrcweir 	{
216*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\t\tcouldn't find object in current purpose \""));
217*cdf0e10cSrcweir 		s_comment += clientPurpose;
218*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\" - FAILURE\n"));
219*cdf0e10cSrcweir 	}
220*cdf0e10cSrcweir }
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir static void s_test__createSimpleRegistry__free(void)
223*cdf0e10cSrcweir {
224*cdf0e10cSrcweir 	s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\ts_test__createSimpleRegistry__free\n"));
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir 	s_test__createSimpleRegistry(rtl::OUString());
227*cdf0e10cSrcweir }
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir static void s_test__createSimpleRegistry__purpose(void)
230*cdf0e10cSrcweir {
231*cdf0e10cSrcweir 	s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\ts_test__createSimpleRegistry__purpose\n"));
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir 	s_test__createSimpleRegistry(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":testenv")));
234*cdf0e10cSrcweir }
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir 
237*cdf0e10cSrcweir static void s_test__bootstrap_InitialComponentContext(rtl::OUString const & clientPurpose)
238*cdf0e10cSrcweir {
239*cdf0e10cSrcweir     cppu::EnvGuard envGuard(uno::Environment(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO))
240*cdf0e10cSrcweir                                                + clientPurpose, NULL));
241*cdf0e10cSrcweir     if (clientPurpose.getLength() && !envGuard.is())
242*cdf0e10cSrcweir     {
243*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\t\tcouldn't get purpose env: \""));
244*cdf0e10cSrcweir         s_comment += clientPurpose;
245*cdf0e10cSrcweir         s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\" - FAILURE\n"));
246*cdf0e10cSrcweir 
247*cdf0e10cSrcweir         return;
248*cdf0e10cSrcweir     }
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir 	uno::Reference<uno::XComponentContext> xContext(
251*cdf0e10cSrcweir 		cppu::bootstrap_InitialComponentContext(
252*cdf0e10cSrcweir 			uno::Reference<registry::XSimpleRegistry>(),
253*cdf0e10cSrcweir 			s_getSDrive())
254*cdf0e10cSrcweir 		);
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir 	if (!xContext.is())
257*cdf0e10cSrcweir 	{
258*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\t\tgot no object - FAILURE\n"));
259*cdf0e10cSrcweir 		return;
260*cdf0e10cSrcweir 	}
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir 	if (clientPurpose.getLength() != 0 && !s_check_object_is_in(xContext.get()))
263*cdf0e10cSrcweir 	{
264*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\t\tcouldn't find object in current purpose \""));
265*cdf0e10cSrcweir 		s_comment += clientPurpose;
266*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\" - FAILURE\n"));
267*cdf0e10cSrcweir 	}
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir 	uno::Reference<lang::XComponent> xComponent(xContext, uno::UNO_QUERY_THROW);
270*cdf0e10cSrcweir 	xComponent->dispose();
271*cdf0e10cSrcweir }
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir static void s_test__bootstrap_InitialComponentContext__free(void)
274*cdf0e10cSrcweir {
275*cdf0e10cSrcweir 	s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\ts_test__bootstrap_InitialComponentContext__free\n"));
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir 	s_test__bootstrap_InitialComponentContext(rtl::OUString());
278*cdf0e10cSrcweir }
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir static void s_test__bootstrap_InitialComponentContext__purpose(void)
281*cdf0e10cSrcweir {
282*cdf0e10cSrcweir 	s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\ts_test__bootstrap_InitialComponentContext__purpose\n"));
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir 	s_test__bootstrap_InitialComponentContext(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":testenv")));
285*cdf0e10cSrcweir }
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir SAL_IMPLEMENT_MAIN_WITH_ARGS(/*argc*/, argv)
289*cdf0e10cSrcweir {
290*cdf0e10cSrcweir 	s_test__createSimpleRegistry__free();
291*cdf0e10cSrcweir 	s_test__createSimpleRegistry__purpose();
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir 	s_test__loadSharedLibComponentFactory__free_free();
294*cdf0e10cSrcweir 	s_test__loadSharedLibComponentFactory__free_purpose();
295*cdf0e10cSrcweir 	s_test__loadSharedLibComponentFactory__purpose_free();
296*cdf0e10cSrcweir 	s_test__loadSharedLibComponentFactory__purpose_purpose();
297*cdf0e10cSrcweir 
298*cdf0e10cSrcweir 	s_test__bootstrap_InitialComponentContext__free();
299*cdf0e10cSrcweir 	s_test__bootstrap_InitialComponentContext__purpose();
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir 	int ret;
302*cdf0e10cSrcweir 	if (s_comment.indexOf(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FAILURE"))) == -1)
303*cdf0e10cSrcweir 	{
304*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TESTS PASSED\n"));
305*cdf0e10cSrcweir 		ret = 0;
306*cdf0e10cSrcweir 	}
307*cdf0e10cSrcweir 	else
308*cdf0e10cSrcweir 	{
309*cdf0e10cSrcweir 		s_comment += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TESTS _NOT_ PASSED\n"));
310*cdf0e10cSrcweir 		ret = -1;
311*cdf0e10cSrcweir 	}
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir 	std::cerr
314*cdf0e10cSrcweir 		<< argv[0]
315*cdf0e10cSrcweir 		<< std::endl
316*cdf0e10cSrcweir 		<< rtl::OUStringToOString(s_comment, RTL_TEXTENCODING_ASCII_US).getStr()
317*cdf0e10cSrcweir 		<< std::endl;
318*cdf0e10cSrcweir 
319*cdf0e10cSrcweir 	return ret;
320*cdf0e10cSrcweir }
321