1*647a425cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*647a425cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*647a425cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*647a425cSAndrew Rist  * distributed with this work for additional information
6*647a425cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*647a425cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*647a425cSAndrew Rist  * "License"); you may not use this file except in compliance
9*647a425cSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*647a425cSAndrew Rist  *
11*647a425cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*647a425cSAndrew Rist  *
13*647a425cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*647a425cSAndrew Rist  * software distributed under the License is distributed on an
15*647a425cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*647a425cSAndrew Rist  * KIND, either express or implied.  See the License for the
17*647a425cSAndrew Rist  * specific language governing permissions and limitations
18*647a425cSAndrew Rist  * under the License.
19*647a425cSAndrew Rist  *
20*647a425cSAndrew Rist  *************************************************************/
21*647a425cSAndrew Rist 
22*647a425cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_stoc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "stocservices.hxx"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include "UriReference.hxx"
30cdf0e10cSrcweir #include "supportsService.hxx"
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
33cdf0e10cSrcweir #include "com/sun/star/lang/XMultiComponentFactory.hpp"
34cdf0e10cSrcweir #include "com/sun/star/lang/XServiceInfo.hpp"
35cdf0e10cSrcweir #include "com/sun/star/uno/Any.hxx"
36cdf0e10cSrcweir #include "com/sun/star/uno/Exception.hpp"
37cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx"
38cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
39cdf0e10cSrcweir #include "com/sun/star/uno/Sequence.hxx"
40cdf0e10cSrcweir #include "com/sun/star/uno/XComponentContext.hpp"
41cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp"
42cdf0e10cSrcweir #include "com/sun/star/uri/RelativeUriExcessParentSegments.hpp"
43cdf0e10cSrcweir #include "com/sun/star/uri/XUriReference.hpp"
44cdf0e10cSrcweir #include "com/sun/star/uri/XUriReferenceFactory.hpp"
45cdf0e10cSrcweir #include "com/sun/star/uri/XUriSchemeParser.hpp"
46cdf0e10cSrcweir #include "cppuhelper/implbase1.hxx"
47cdf0e10cSrcweir #include "cppuhelper/implbase2.hxx"
48cdf0e10cSrcweir #include "cppuhelper/weak.hxx"
49cdf0e10cSrcweir #include "osl/diagnose.h"
50cdf0e10cSrcweir #include "rtl/string.h"
51cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
52cdf0e10cSrcweir #include "rtl/ustring.hxx"
53cdf0e10cSrcweir #include "sal/types.h"
54cdf0e10cSrcweir 
55cdf0e10cSrcweir #include <algorithm>
56cdf0e10cSrcweir #include /*MSVC trouble: <cstdlib>*/ <stdlib.h>
57cdf0e10cSrcweir #include <new>
58cdf0e10cSrcweir #include <vector>
59cdf0e10cSrcweir 
60cdf0e10cSrcweir namespace css = com::sun::star;
61cdf0e10cSrcweir 
62cdf0e10cSrcweir namespace {
63cdf0e10cSrcweir 
isDigit(sal_Unicode c)64cdf0e10cSrcweir bool isDigit(sal_Unicode c) { //TODO: generally available?
65cdf0e10cSrcweir     return c >= '0' && c <= '9';
66cdf0e10cSrcweir }
67cdf0e10cSrcweir 
isUpperCase(sal_Unicode c)68cdf0e10cSrcweir bool isUpperCase(sal_Unicode c) { //TODO: generally available?
69cdf0e10cSrcweir     return c >= 'A' && c <= 'Z';
70cdf0e10cSrcweir }
71cdf0e10cSrcweir 
isLowerCase(sal_Unicode c)72cdf0e10cSrcweir bool isLowerCase(sal_Unicode c) { //TODO: generally available?
73cdf0e10cSrcweir     return c >= 'a' && c <= 'z';
74cdf0e10cSrcweir }
75cdf0e10cSrcweir 
isAlpha(sal_Unicode c)76cdf0e10cSrcweir bool isAlpha(sal_Unicode c) { //TODO: generally available?
77cdf0e10cSrcweir     return isUpperCase(c) || isLowerCase(c);
78cdf0e10cSrcweir }
79cdf0e10cSrcweir 
isHexDigit(sal_Unicode c)80cdf0e10cSrcweir bool isHexDigit(sal_Unicode c) { //TODO: generally available?
81cdf0e10cSrcweir     return isDigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
82cdf0e10cSrcweir }
83cdf0e10cSrcweir 
toLowerCase(sal_Unicode c)84cdf0e10cSrcweir sal_Unicode toLowerCase(sal_Unicode c) { //TODO: generally available?
85cdf0e10cSrcweir     return isUpperCase(c) ? c + ('a' - 'A') : c;
86cdf0e10cSrcweir }
87cdf0e10cSrcweir 
equalIgnoreCase(sal_Unicode c1,sal_Unicode c2)88cdf0e10cSrcweir bool equalIgnoreCase(sal_Unicode c1, sal_Unicode c2) {
89cdf0e10cSrcweir     //TODO: generally available?
90cdf0e10cSrcweir     return toLowerCase(c1) == toLowerCase(c2);
91cdf0e10cSrcweir }
92cdf0e10cSrcweir 
equalIgnoreEscapeCase(rtl::OUString const & s1,rtl::OUString const & s2)93cdf0e10cSrcweir bool equalIgnoreEscapeCase(rtl::OUString const & s1, rtl::OUString const & s2) {
94cdf0e10cSrcweir     if (s1.getLength() == s2.getLength()) {
95cdf0e10cSrcweir         for (sal_Int32 i = 0; i < s1.getLength();) {
96cdf0e10cSrcweir             if (s1[i] == '%' && s2[i] == '%' && s1.getLength() - i > 2
97cdf0e10cSrcweir                 && isHexDigit(s1[i + 1]) && isHexDigit(s1[i + 2])
98cdf0e10cSrcweir                 && isHexDigit(s2[i + 1]) && isHexDigit(s2[i + 2])
99cdf0e10cSrcweir                 && equalIgnoreCase(s1[i + 1], s2[i + 1])
100cdf0e10cSrcweir                 && equalIgnoreCase(s1[i + 2], s2[i + 2]))
101cdf0e10cSrcweir             {
102cdf0e10cSrcweir                 i += 3;
103cdf0e10cSrcweir             } else if (s1[i] != s2[i]) {
104cdf0e10cSrcweir                 return false;
105cdf0e10cSrcweir             } else {
106cdf0e10cSrcweir                 ++i;
107cdf0e10cSrcweir             }
108cdf0e10cSrcweir         }
109cdf0e10cSrcweir         return true;
110cdf0e10cSrcweir     } else {
111cdf0e10cSrcweir         return false;
112cdf0e10cSrcweir     }
113cdf0e10cSrcweir }
114cdf0e10cSrcweir 
parseScheme(rtl::OUString const & uriReference)115cdf0e10cSrcweir sal_Int32 parseScheme(rtl::OUString const & uriReference) {
116cdf0e10cSrcweir     if (uriReference.getLength() >= 2 && isAlpha(uriReference[0])) {
117cdf0e10cSrcweir         for (sal_Int32 i = 0; i < uriReference.getLength(); ++i) {
118cdf0e10cSrcweir             sal_Unicode c = uriReference[i];
119cdf0e10cSrcweir             if (c == ':') {
120cdf0e10cSrcweir                 return i;
121cdf0e10cSrcweir             } else if (!isAlpha(c) && !isDigit(c) && c != '+' && c != '-'
122cdf0e10cSrcweir                        && c != '.')
123cdf0e10cSrcweir             {
124cdf0e10cSrcweir                 break;
125cdf0e10cSrcweir             }
126cdf0e10cSrcweir         }
127cdf0e10cSrcweir     }
128cdf0e10cSrcweir     return -1;
129cdf0e10cSrcweir }
130cdf0e10cSrcweir 
131cdf0e10cSrcweir class UriReference: public cppu::WeakImplHelper1< css::uri::XUriReference > {
132cdf0e10cSrcweir public:
UriReference(rtl::OUString const & scheme,bool bIsHierarchical,bool bHasAuthority,rtl::OUString const & authority,rtl::OUString const & path,bool bHasQuery,rtl::OUString const & query)133cdf0e10cSrcweir     UriReference(
134cdf0e10cSrcweir         rtl::OUString const & scheme, bool bIsHierarchical, bool bHasAuthority,
135cdf0e10cSrcweir         rtl::OUString const & authority, rtl::OUString const & path,
136cdf0e10cSrcweir         bool bHasQuery, rtl::OUString const & query):
137cdf0e10cSrcweir         m_base(
138cdf0e10cSrcweir             scheme, bIsHierarchical, bHasAuthority, authority, path, bHasQuery,
139cdf0e10cSrcweir             query)
140cdf0e10cSrcweir     {}
141cdf0e10cSrcweir 
getUriReference()142cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getUriReference()
143cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
144cdf0e10cSrcweir     { return m_base.getUriReference(); }
145cdf0e10cSrcweir 
isAbsolute()146cdf0e10cSrcweir     virtual sal_Bool SAL_CALL isAbsolute()
147cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
148cdf0e10cSrcweir     { return m_base.isAbsolute(); }
149cdf0e10cSrcweir 
getScheme()150cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getScheme()
151cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
152cdf0e10cSrcweir     { return m_base.getScheme(); }
153cdf0e10cSrcweir 
getSchemeSpecificPart()154cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getSchemeSpecificPart()
155cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
156cdf0e10cSrcweir     { return m_base.getSchemeSpecificPart(); }
157cdf0e10cSrcweir 
isHierarchical()158cdf0e10cSrcweir     virtual sal_Bool SAL_CALL isHierarchical()
159cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
160cdf0e10cSrcweir     { return m_base.isHierarchical(); }
161cdf0e10cSrcweir 
hasAuthority()162cdf0e10cSrcweir     virtual sal_Bool SAL_CALL hasAuthority()
163cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
164cdf0e10cSrcweir     { return m_base.hasAuthority(); }
165cdf0e10cSrcweir 
getAuthority()166cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getAuthority()
167cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
168cdf0e10cSrcweir     { return m_base.getAuthority(); }
169cdf0e10cSrcweir 
getPath()170cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getPath()
171cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
172cdf0e10cSrcweir     { return m_base.getPath(); }
173cdf0e10cSrcweir 
hasRelativePath()174cdf0e10cSrcweir     virtual sal_Bool SAL_CALL hasRelativePath()
175cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
176cdf0e10cSrcweir     { return m_base.hasRelativePath(); }
177cdf0e10cSrcweir 
getPathSegmentCount()178cdf0e10cSrcweir     virtual sal_Int32 SAL_CALL getPathSegmentCount()
179cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
180cdf0e10cSrcweir     { return m_base.getPathSegmentCount(); }
181cdf0e10cSrcweir 
getPathSegment(sal_Int32 index)182cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getPathSegment(sal_Int32 index)
183cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
184cdf0e10cSrcweir     { return m_base.getPathSegment(index); }
185cdf0e10cSrcweir 
hasQuery()186cdf0e10cSrcweir     virtual sal_Bool SAL_CALL hasQuery()
187cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
188cdf0e10cSrcweir     { return m_base.hasQuery(); }
189cdf0e10cSrcweir 
getQuery()190cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getQuery()
191cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
192cdf0e10cSrcweir     { return m_base.getQuery(); }
193cdf0e10cSrcweir 
hasFragment()194cdf0e10cSrcweir     virtual sal_Bool SAL_CALL hasFragment()
195cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
196cdf0e10cSrcweir     { return m_base.hasFragment(); }
197cdf0e10cSrcweir 
getFragment()198cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getFragment()
199cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
200cdf0e10cSrcweir     { return m_base.getFragment(); }
201cdf0e10cSrcweir 
setFragment(rtl::OUString const & fragment)202cdf0e10cSrcweir     virtual void SAL_CALL setFragment(rtl::OUString const & fragment)
203cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
204cdf0e10cSrcweir     { m_base.setFragment(fragment); }
205cdf0e10cSrcweir 
clearFragment()206cdf0e10cSrcweir     virtual void SAL_CALL clearFragment()
207cdf0e10cSrcweir         throw (com::sun::star::uno::RuntimeException)
208cdf0e10cSrcweir     { m_base.clearFragment(); }
209cdf0e10cSrcweir 
210cdf0e10cSrcweir private:
211cdf0e10cSrcweir     UriReference(UriReference &); // not implemented
212cdf0e10cSrcweir     void operator =(UriReference); // not implemented
213cdf0e10cSrcweir 
~UriReference()214cdf0e10cSrcweir     virtual ~UriReference() {}
215cdf0e10cSrcweir 
216cdf0e10cSrcweir     stoc::uriproc::UriReference m_base;
217cdf0e10cSrcweir };
218cdf0e10cSrcweir 
219cdf0e10cSrcweir // throws std::bad_alloc
parseGeneric(rtl::OUString const & scheme,rtl::OUString const & schemeSpecificPart)220cdf0e10cSrcweir css::uno::Reference< css::uri::XUriReference > parseGeneric(
221cdf0e10cSrcweir     rtl::OUString const & scheme, rtl::OUString const & schemeSpecificPart)
222cdf0e10cSrcweir {
223cdf0e10cSrcweir     bool isAbsolute = scheme.getLength() != 0;
224cdf0e10cSrcweir     bool isHierarchical
225cdf0e10cSrcweir         = !isAbsolute
226cdf0e10cSrcweir         || (schemeSpecificPart.getLength() > 0 && schemeSpecificPart[0] == '/');
227cdf0e10cSrcweir     bool hasAuthority = false;
228cdf0e10cSrcweir     rtl::OUString authority;
229cdf0e10cSrcweir     rtl::OUString path;
230cdf0e10cSrcweir     bool hasQuery = false;
231cdf0e10cSrcweir     rtl::OUString query;
232cdf0e10cSrcweir     if (isHierarchical) {
233cdf0e10cSrcweir         sal_Int32 len = schemeSpecificPart.getLength();
234cdf0e10cSrcweir         sal_Int32 i = 0;
235cdf0e10cSrcweir         if (len - i >= 2 && schemeSpecificPart[i] == '/'
236cdf0e10cSrcweir             && schemeSpecificPart[i + 1] == '/')
237cdf0e10cSrcweir         {
238cdf0e10cSrcweir             i += 2;
239cdf0e10cSrcweir             sal_Int32 n = i;
240cdf0e10cSrcweir             while (i < len && schemeSpecificPart[i] != '/'
241cdf0e10cSrcweir                    && schemeSpecificPart[i] != '?') {
242cdf0e10cSrcweir                 ++i;
243cdf0e10cSrcweir             }
244cdf0e10cSrcweir             hasAuthority = true;
245cdf0e10cSrcweir             authority = schemeSpecificPart.copy(n, i - n);
246cdf0e10cSrcweir         }
247cdf0e10cSrcweir         sal_Int32 n = i;
248cdf0e10cSrcweir         i = schemeSpecificPart.indexOf('?', i);
249cdf0e10cSrcweir         if (i == -1) {
250cdf0e10cSrcweir             i = len;
251cdf0e10cSrcweir         }
252cdf0e10cSrcweir         path = schemeSpecificPart.copy(n, i - n);
253cdf0e10cSrcweir         if (i != len) {
254cdf0e10cSrcweir             hasQuery = true;
255cdf0e10cSrcweir             query = schemeSpecificPart.copy(i + 1);
256cdf0e10cSrcweir         }
257cdf0e10cSrcweir     } else {
258cdf0e10cSrcweir         if (schemeSpecificPart.getLength() == 0) {
259cdf0e10cSrcweir             // The scheme-specific part of an opaque URI must not be empty:
260cdf0e10cSrcweir             return 0;
261cdf0e10cSrcweir         }
262cdf0e10cSrcweir         path = schemeSpecificPart;
263cdf0e10cSrcweir     }
264cdf0e10cSrcweir     return new UriReference(
265cdf0e10cSrcweir         scheme, isHierarchical, hasAuthority, authority, path, hasQuery, query);
266cdf0e10cSrcweir }
267cdf0e10cSrcweir 
268cdf0e10cSrcweir typedef std::vector< sal_Int32 > Segments;
269cdf0e10cSrcweir 
processSegments(Segments & segments,css::uno::Reference<css::uri::XUriReference> const & uriReference,bool base,bool processSpecialSegments)270cdf0e10cSrcweir void processSegments(
271cdf0e10cSrcweir     Segments & segments,
272cdf0e10cSrcweir     css::uno::Reference< css::uri::XUriReference > const & uriReference,
273cdf0e10cSrcweir     bool base, bool processSpecialSegments)
274cdf0e10cSrcweir {
275cdf0e10cSrcweir     sal_Int32 count = uriReference->getPathSegmentCount() - (base ? 1 : 0);
276cdf0e10cSrcweir     OSL_ASSERT(count <= SAL_MAX_INT32 - 1 && -count >= SAL_MIN_INT32 + 1);
277cdf0e10cSrcweir     for (sal_Int32 i = 0; i < count; ++i) {
278cdf0e10cSrcweir         if (processSpecialSegments) {
279cdf0e10cSrcweir             rtl::OUString segment(uriReference->getPathSegment(i));
280cdf0e10cSrcweir             if (segment.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("."))) {
281cdf0e10cSrcweir                 if (!base && i == count - 1) {
282cdf0e10cSrcweir                     segments.push_back(0);
283cdf0e10cSrcweir                 }
284cdf0e10cSrcweir                 continue;
285cdf0e10cSrcweir             } else if (segment.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(".."))) {
286cdf0e10cSrcweir                 if (segments.empty()
287cdf0e10cSrcweir                     || /*MSVC trouble: std::*/abs(segments.back()) == 1)
288cdf0e10cSrcweir                 {
289cdf0e10cSrcweir                     segments.push_back(base ? -1 : 1);
290cdf0e10cSrcweir                 } else {
291cdf0e10cSrcweir                     segments.pop_back();
292cdf0e10cSrcweir                 }
293cdf0e10cSrcweir                 continue;
294cdf0e10cSrcweir             }
295cdf0e10cSrcweir         }
296cdf0e10cSrcweir         segments.push_back(base ? -(i + 2) : i + 2);
297cdf0e10cSrcweir     }
298cdf0e10cSrcweir }
299cdf0e10cSrcweir 
300cdf0e10cSrcweir class Factory: public cppu::WeakImplHelper2<
301cdf0e10cSrcweir     css::lang::XServiceInfo, css::uri::XUriReferenceFactory >
302cdf0e10cSrcweir {
303cdf0e10cSrcweir public:
Factory(css::uno::Reference<css::uno::XComponentContext> const & context)304cdf0e10cSrcweir     explicit Factory(
305cdf0e10cSrcweir         css::uno::Reference< css::uno::XComponentContext > const & context):
306cdf0e10cSrcweir         m_context(context) {}
307cdf0e10cSrcweir 
308cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getImplementationName()
309cdf0e10cSrcweir         throw (css::uno::RuntimeException);
310cdf0e10cSrcweir 
311cdf0e10cSrcweir     virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
312cdf0e10cSrcweir         throw (css::uno::RuntimeException);
313cdf0e10cSrcweir 
314cdf0e10cSrcweir     virtual css::uno::Sequence< rtl::OUString > SAL_CALL
315cdf0e10cSrcweir     getSupportedServiceNames() throw (css::uno::RuntimeException);
316cdf0e10cSrcweir 
317cdf0e10cSrcweir     virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL
318cdf0e10cSrcweir     parse(rtl::OUString const & uriReference)
319cdf0e10cSrcweir         throw (css::uno::RuntimeException);
320cdf0e10cSrcweir 
321cdf0e10cSrcweir     virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL
322cdf0e10cSrcweir     makeAbsolute(
323cdf0e10cSrcweir         css::uno::Reference< css::uri::XUriReference > const & baseUriReference,
324cdf0e10cSrcweir         css::uno::Reference< css::uri::XUriReference > const & uriReference,
325cdf0e10cSrcweir         sal_Bool processSpecialBaseSegments,
326cdf0e10cSrcweir         css::uri::RelativeUriExcessParentSegments excessParentSegments)
327cdf0e10cSrcweir         throw (css::uno::RuntimeException);
328cdf0e10cSrcweir 
329cdf0e10cSrcweir     virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL
330cdf0e10cSrcweir     makeRelative(
331cdf0e10cSrcweir         css::uno::Reference< css::uri::XUriReference > const & baseUriReference,
332cdf0e10cSrcweir         css::uno::Reference< css::uri::XUriReference > const & uriReference,
333cdf0e10cSrcweir         sal_Bool preferAuthorityOverRelativePath,
334cdf0e10cSrcweir         sal_Bool preferAbsoluteOverRelativePath,
335cdf0e10cSrcweir         sal_Bool encodeRetainedSpecialSegments)
336cdf0e10cSrcweir         throw (css::uno::RuntimeException);
337cdf0e10cSrcweir 
338cdf0e10cSrcweir private:
339cdf0e10cSrcweir     Factory(Factory &); // not implemented
340cdf0e10cSrcweir     void operator =(Factory); // not implemented
341cdf0e10cSrcweir 
~Factory()342cdf0e10cSrcweir     virtual ~Factory() {}
343cdf0e10cSrcweir 
clone(css::uno::Reference<css::uri::XUriReference> const & uriReference)344cdf0e10cSrcweir     css::uno::Reference< css::uri::XUriReference > clone(
345cdf0e10cSrcweir         css::uno::Reference< css::uri::XUriReference > const & uriReference)
346cdf0e10cSrcweir     { return parse(uriReference->getUriReference()); }
347cdf0e10cSrcweir 
348cdf0e10cSrcweir     css::uno::Reference< css::uno::XComponentContext > m_context;
349cdf0e10cSrcweir };
350cdf0e10cSrcweir 
getImplementationName()351cdf0e10cSrcweir rtl::OUString Factory::getImplementationName()
352cdf0e10cSrcweir     throw (css::uno::RuntimeException)
353cdf0e10cSrcweir {
354cdf0e10cSrcweir     return stoc_services::UriReferenceFactory::getImplementationName();
355cdf0e10cSrcweir }
356cdf0e10cSrcweir 
supportsService(rtl::OUString const & serviceName)357cdf0e10cSrcweir sal_Bool Factory::supportsService(rtl::OUString const & serviceName)
358cdf0e10cSrcweir     throw (css::uno::RuntimeException)
359cdf0e10cSrcweir {
360cdf0e10cSrcweir     return stoc::uriproc::supportsService(
361cdf0e10cSrcweir         getSupportedServiceNames(), serviceName);
362cdf0e10cSrcweir }
363cdf0e10cSrcweir 
getSupportedServiceNames()364cdf0e10cSrcweir css::uno::Sequence< rtl::OUString > Factory::getSupportedServiceNames()
365cdf0e10cSrcweir     throw (css::uno::RuntimeException)
366cdf0e10cSrcweir {
367cdf0e10cSrcweir     return stoc_services::UriReferenceFactory::getSupportedServiceNames();
368cdf0e10cSrcweir }
369cdf0e10cSrcweir 
parse(rtl::OUString const & uriReference)370cdf0e10cSrcweir css::uno::Reference< css::uri::XUriReference > Factory::parse(
371cdf0e10cSrcweir     rtl::OUString const & uriReference) throw (css::uno::RuntimeException)
372cdf0e10cSrcweir {
373cdf0e10cSrcweir     sal_Int32 fragment = uriReference.indexOf('#');
374cdf0e10cSrcweir     if (fragment == -1) {
375cdf0e10cSrcweir         fragment = uriReference.getLength();
376cdf0e10cSrcweir     }
377cdf0e10cSrcweir     rtl::OUString scheme;
378cdf0e10cSrcweir     rtl::OUString schemeSpecificPart;
379cdf0e10cSrcweir     rtl::OUString serviceName;
380cdf0e10cSrcweir     sal_Int32 n = parseScheme(uriReference);
381cdf0e10cSrcweir     OSL_ASSERT(n < fragment);
382cdf0e10cSrcweir     if (n >= 0) {
383cdf0e10cSrcweir         scheme = uriReference.copy(0, n);
384cdf0e10cSrcweir         schemeSpecificPart = uriReference.copy(n + 1, fragment - (n + 1));
385cdf0e10cSrcweir         rtl::OUStringBuffer buf;
386cdf0e10cSrcweir         buf.appendAscii(
387cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("com.sun.star.uri.UriSchemeParser_"));
388cdf0e10cSrcweir         for (sal_Int32 i = 0; i < scheme.getLength(); ++i) {
389cdf0e10cSrcweir             sal_Unicode c = scheme[i];
390cdf0e10cSrcweir             if (isUpperCase(c)) {
391cdf0e10cSrcweir                 buf.append(toLowerCase(c));
392cdf0e10cSrcweir             } else if (c == '+') {
393cdf0e10cSrcweir                 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("PLUS"));
394cdf0e10cSrcweir             } else if (c == '-') {
395cdf0e10cSrcweir                 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("HYPHEN"));
396cdf0e10cSrcweir             } else if (c == '.') {
397cdf0e10cSrcweir                 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("DOT"));
398cdf0e10cSrcweir             } else {
399cdf0e10cSrcweir                 OSL_ASSERT(isLowerCase(c) || isDigit(c));
400cdf0e10cSrcweir                 buf.append(c);
401cdf0e10cSrcweir             }
402cdf0e10cSrcweir         }
403cdf0e10cSrcweir         serviceName = buf.makeStringAndClear();
404cdf0e10cSrcweir     } else {
405cdf0e10cSrcweir         schemeSpecificPart = uriReference.copy(0, fragment);
406cdf0e10cSrcweir     }
407cdf0e10cSrcweir     css::uno::Reference< css::uri::XUriSchemeParser > parser;
408cdf0e10cSrcweir     if (serviceName.getLength() != 0) {
409cdf0e10cSrcweir         css::uno::Reference< css::lang::XMultiComponentFactory > factory(
410cdf0e10cSrcweir             m_context->getServiceManager());
411cdf0e10cSrcweir         if (factory.is()) {
412cdf0e10cSrcweir             css::uno::Reference< css::uno::XInterface > service;
413cdf0e10cSrcweir             try {
414cdf0e10cSrcweir                 service = factory->createInstanceWithContext(
415cdf0e10cSrcweir                     serviceName, m_context);
416cdf0e10cSrcweir             } catch (css::uno::RuntimeException &) {
417cdf0e10cSrcweir                 throw;
418cdf0e10cSrcweir             } catch (css::uno::Exception & e) {
419cdf0e10cSrcweir                 throw css::lang::WrappedTargetRuntimeException(
420cdf0e10cSrcweir                     rtl::OUString::createFromAscii("creating service ")
421cdf0e10cSrcweir                         + serviceName,
422cdf0e10cSrcweir                     static_cast< cppu::OWeakObject * >(this),
423cdf0e10cSrcweir                     css::uno::makeAny(e)); //TODO: preserve type of e
424cdf0e10cSrcweir             }
425cdf0e10cSrcweir             if (service.is()) {
426cdf0e10cSrcweir                 parser = css::uno::Reference< css::uri::XUriSchemeParser >(
427cdf0e10cSrcweir                     service, css::uno::UNO_QUERY_THROW);
428cdf0e10cSrcweir             }
429cdf0e10cSrcweir         }
430cdf0e10cSrcweir     }
431cdf0e10cSrcweir     css::uno::Reference< css::uri::XUriReference > uriRef;
432cdf0e10cSrcweir     if (parser.is()) {
433cdf0e10cSrcweir         uriRef = parser->parse(scheme, schemeSpecificPart);
434cdf0e10cSrcweir     } else {
435cdf0e10cSrcweir         try {
436cdf0e10cSrcweir             uriRef = parseGeneric(scheme, schemeSpecificPart);
437cdf0e10cSrcweir         } catch (std::bad_alloc &) {
438cdf0e10cSrcweir             throw css::uno::RuntimeException(
439cdf0e10cSrcweir                 rtl::OUString::createFromAscii("std::bad_alloc"),
440cdf0e10cSrcweir                 static_cast< cppu::OWeakObject * >(this));
441cdf0e10cSrcweir         }
442cdf0e10cSrcweir     }
443cdf0e10cSrcweir     if (uriRef.is() && fragment != uriReference.getLength()) {
444cdf0e10cSrcweir         uriRef->setFragment(uriReference.copy(fragment + 1));
445cdf0e10cSrcweir     }
446cdf0e10cSrcweir     return uriRef;
447cdf0e10cSrcweir }
448cdf0e10cSrcweir 
makeAbsolute(css::uno::Reference<css::uri::XUriReference> const & baseUriReference,css::uno::Reference<css::uri::XUriReference> const & uriReference,sal_Bool processSpecialBaseSegments,css::uri::RelativeUriExcessParentSegments excessParentSegments)449cdf0e10cSrcweir css::uno::Reference< css::uri::XUriReference > Factory::makeAbsolute(
450cdf0e10cSrcweir     css::uno::Reference< css::uri::XUriReference > const & baseUriReference,
451cdf0e10cSrcweir     css::uno::Reference< css::uri::XUriReference > const & uriReference,
452cdf0e10cSrcweir     sal_Bool processSpecialBaseSegments,
453cdf0e10cSrcweir     css::uri::RelativeUriExcessParentSegments excessParentSegments)
454cdf0e10cSrcweir     throw (css::uno::RuntimeException)
455cdf0e10cSrcweir {
456cdf0e10cSrcweir     if (!baseUriReference.is() || !baseUriReference->isAbsolute()
457cdf0e10cSrcweir         || !baseUriReference->isHierarchical() || !uriReference.is()) {
458cdf0e10cSrcweir         return 0;
459cdf0e10cSrcweir     } else if (uriReference->isAbsolute()) {
460cdf0e10cSrcweir         return clone(uriReference);
461cdf0e10cSrcweir     } else if (!uriReference->hasAuthority()
462cdf0e10cSrcweir                && uriReference->getPath().getLength() == 0
463cdf0e10cSrcweir                && !uriReference->hasQuery()) {
464cdf0e10cSrcweir         css::uno::Reference< css::uri::XUriReference > abs(
465cdf0e10cSrcweir             clone(baseUriReference));
466cdf0e10cSrcweir         if (uriReference->hasFragment()) {
467cdf0e10cSrcweir             abs->setFragment(uriReference->getFragment());
468cdf0e10cSrcweir         } else {
469cdf0e10cSrcweir             abs->clearFragment();
470cdf0e10cSrcweir         }
471cdf0e10cSrcweir         return abs;
472cdf0e10cSrcweir     } else {
473cdf0e10cSrcweir         rtl::OUStringBuffer abs(baseUriReference->getScheme());
474cdf0e10cSrcweir         abs.append(static_cast< sal_Unicode >(':'));
475cdf0e10cSrcweir         if (uriReference->hasAuthority()) {
476cdf0e10cSrcweir             abs.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
477cdf0e10cSrcweir             abs.append(uriReference->getAuthority());
478cdf0e10cSrcweir         } else if (baseUriReference->hasAuthority()) {
479cdf0e10cSrcweir             abs.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
480cdf0e10cSrcweir             abs.append(baseUriReference->getAuthority());
481cdf0e10cSrcweir         }
482cdf0e10cSrcweir         if (uriReference->hasRelativePath()) {
483cdf0e10cSrcweir             Segments segments;
484cdf0e10cSrcweir             processSegments(
485cdf0e10cSrcweir                 segments, baseUriReference, true, processSpecialBaseSegments);
486cdf0e10cSrcweir             processSegments(segments, uriReference, false, true);
487cdf0e10cSrcweir             // If the path component of the base URI reference is empty (which
488cdf0e10cSrcweir             // implies that the base URI reference denotes a "root entity"), and
489cdf0e10cSrcweir             // the resulting URI reference denotes the same root entity, make
490cdf0e10cSrcweir             // sure the path component of the resulting URI reference is also
491cdf0e10cSrcweir             // empty (and not "/").  RFC 2396 is unclear about this, and I chose
492cdf0e10cSrcweir             // these rules for consistent results.
493cdf0e10cSrcweir             bool slash = baseUriReference->getPath().getLength() != 0;
494cdf0e10cSrcweir             if (slash) {
495cdf0e10cSrcweir                 abs.append(static_cast< sal_Unicode >('/'));
496cdf0e10cSrcweir             }
497cdf0e10cSrcweir             for (Segments::iterator i(segments.begin()); i != segments.end();
498cdf0e10cSrcweir                  ++i)
499cdf0e10cSrcweir             {
500cdf0e10cSrcweir                 if (*i < -1) {
501cdf0e10cSrcweir                     rtl::OUString segment(
502cdf0e10cSrcweir                         baseUriReference->getPathSegment(-(*i + 2)));
503cdf0e10cSrcweir                     if (segment.getLength() != 0 || segments.size() > 1) {
504cdf0e10cSrcweir                         if (!slash) {
505cdf0e10cSrcweir                             abs.append(static_cast< sal_Unicode >('/'));
506cdf0e10cSrcweir                         }
507cdf0e10cSrcweir                         abs.append(segment);
508cdf0e10cSrcweir                         slash = true;
509cdf0e10cSrcweir                         abs.append(static_cast< sal_Unicode >('/'));
510cdf0e10cSrcweir                     }
511cdf0e10cSrcweir                 } else if (*i > 1) {
512cdf0e10cSrcweir                     rtl::OUString segment(uriReference->getPathSegment(*i - 2));
513cdf0e10cSrcweir                     if (segment.getLength() != 0 || segments.size() > 1) {
514cdf0e10cSrcweir                         if (!slash) {
515cdf0e10cSrcweir                             abs.append(static_cast< sal_Unicode >('/'));
516cdf0e10cSrcweir                         }
517cdf0e10cSrcweir                         abs.append(segment);
518cdf0e10cSrcweir                         slash = false;
519cdf0e10cSrcweir                     }
520cdf0e10cSrcweir                 } else if (*i == 0) {
521cdf0e10cSrcweir                     if (segments.size() > 1 && !slash) {
522cdf0e10cSrcweir                         abs.append(static_cast< sal_Unicode >('/'));
523cdf0e10cSrcweir                     }
524cdf0e10cSrcweir                 } else {
525cdf0e10cSrcweir                     switch (excessParentSegments) {
526cdf0e10cSrcweir                     case css::uri::RelativeUriExcessParentSegments_ERROR:
527cdf0e10cSrcweir                         return 0;
528cdf0e10cSrcweir 
529cdf0e10cSrcweir                     case css::uri::RelativeUriExcessParentSegments_RETAIN:
530cdf0e10cSrcweir                         if (!slash) {
531cdf0e10cSrcweir                             abs.append(static_cast< sal_Unicode >('/'));
532cdf0e10cSrcweir                         }
533cdf0e10cSrcweir                         abs.appendAscii(RTL_CONSTASCII_STRINGPARAM(".."));
534cdf0e10cSrcweir                         slash = *i < 0;
535cdf0e10cSrcweir                         if (slash) {
536cdf0e10cSrcweir                             abs.append(static_cast< sal_Unicode >('/'));
537cdf0e10cSrcweir                         }
538cdf0e10cSrcweir                         break;
539cdf0e10cSrcweir 
540cdf0e10cSrcweir                     case css::uri::RelativeUriExcessParentSegments_REMOVE:
541cdf0e10cSrcweir                         break;
542cdf0e10cSrcweir 
543cdf0e10cSrcweir                     default:
544cdf0e10cSrcweir                         OSL_ASSERT(false);
545cdf0e10cSrcweir                         break;
546cdf0e10cSrcweir                     }
547cdf0e10cSrcweir                 }
548cdf0e10cSrcweir             }
549cdf0e10cSrcweir         } else {
550cdf0e10cSrcweir             abs.append(uriReference->getPath());
551cdf0e10cSrcweir         }
552cdf0e10cSrcweir         if (uriReference->hasQuery()) {
553cdf0e10cSrcweir             abs.append(static_cast< sal_Unicode >('?'));
554cdf0e10cSrcweir             abs.append(uriReference->getQuery());
555cdf0e10cSrcweir         }
556cdf0e10cSrcweir         if (uriReference->hasFragment()) {
557cdf0e10cSrcweir             abs.append(static_cast< sal_Unicode >('#'));
558cdf0e10cSrcweir             abs.append(uriReference->getFragment());
559cdf0e10cSrcweir         }
560cdf0e10cSrcweir         return parse(abs.makeStringAndClear());
561cdf0e10cSrcweir     }
562cdf0e10cSrcweir }
563cdf0e10cSrcweir 
makeRelative(css::uno::Reference<css::uri::XUriReference> const & baseUriReference,css::uno::Reference<css::uri::XUriReference> const & uriReference,sal_Bool preferAuthorityOverRelativePath,sal_Bool preferAbsoluteOverRelativePath,sal_Bool encodeRetainedSpecialSegments)564cdf0e10cSrcweir css::uno::Reference< css::uri::XUriReference > Factory::makeRelative(
565cdf0e10cSrcweir     css::uno::Reference< css::uri::XUriReference > const & baseUriReference,
566cdf0e10cSrcweir     css::uno::Reference< css::uri::XUriReference > const & uriReference,
567cdf0e10cSrcweir     sal_Bool preferAuthorityOverRelativePath,
568cdf0e10cSrcweir     sal_Bool preferAbsoluteOverRelativePath,
569cdf0e10cSrcweir     sal_Bool encodeRetainedSpecialSegments)
570cdf0e10cSrcweir     throw (css::uno::RuntimeException)
571cdf0e10cSrcweir {
572cdf0e10cSrcweir     if (!baseUriReference.is() || !baseUriReference->isAbsolute()
573cdf0e10cSrcweir         || !baseUriReference->isHierarchical() || !uriReference.is()) {
574cdf0e10cSrcweir         return 0;
575cdf0e10cSrcweir     } else if (!uriReference->isAbsolute() || !uriReference->isHierarchical()
576cdf0e10cSrcweir                || !baseUriReference->getScheme().equalsIgnoreAsciiCase(
577cdf0e10cSrcweir                    uriReference->getScheme())) {
578cdf0e10cSrcweir         return clone(uriReference);
579cdf0e10cSrcweir     } else {
580cdf0e10cSrcweir         rtl::OUStringBuffer rel;
581cdf0e10cSrcweir         bool omitQuery = false;
582cdf0e10cSrcweir         if ((baseUriReference->hasAuthority() != uriReference->hasAuthority())
583cdf0e10cSrcweir             || !equalIgnoreEscapeCase(
584cdf0e10cSrcweir                 baseUriReference->getAuthority(),
585cdf0e10cSrcweir                 uriReference->getAuthority()))
586cdf0e10cSrcweir         {
587cdf0e10cSrcweir             if (uriReference->hasAuthority()) {
588cdf0e10cSrcweir                 rel.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
589cdf0e10cSrcweir                 rel.append(uriReference->getAuthority());
590cdf0e10cSrcweir             }
591cdf0e10cSrcweir             rel.append(uriReference->getPath());
592cdf0e10cSrcweir         } else if ((equalIgnoreEscapeCase(
593cdf0e10cSrcweir                         baseUriReference->getPath(), uriReference->getPath())
594cdf0e10cSrcweir                     || (baseUriReference->getPath().getLength() <= 1
595cdf0e10cSrcweir                         && uriReference->getPath().getLength() <= 1))
596cdf0e10cSrcweir                    && baseUriReference->hasQuery() == uriReference->hasQuery()
597cdf0e10cSrcweir                    && equalIgnoreEscapeCase(
598cdf0e10cSrcweir                        baseUriReference->getQuery(), uriReference->getQuery()))
599cdf0e10cSrcweir         {
600cdf0e10cSrcweir             omitQuery = true;
601cdf0e10cSrcweir         } else {
602cdf0e10cSrcweir             sal_Int32 count1 = std::max< sal_Int32 >(
603cdf0e10cSrcweir                 baseUriReference->getPathSegmentCount(), 1);
604cdf0e10cSrcweir             sal_Int32 count2 = std::max< sal_Int32 >(
605cdf0e10cSrcweir                 uriReference->getPathSegmentCount(), 1);
606cdf0e10cSrcweir             sal_Int32 i = 0;
607cdf0e10cSrcweir             for (; i < std::min(count1, count2) - 1; ++i) {
608cdf0e10cSrcweir                 if (!equalIgnoreEscapeCase(
609cdf0e10cSrcweir                         baseUriReference->getPathSegment(i),
610cdf0e10cSrcweir                         uriReference->getPathSegment(i)))
611cdf0e10cSrcweir                 {
612cdf0e10cSrcweir                     break;
613cdf0e10cSrcweir                 }
614cdf0e10cSrcweir             }
615cdf0e10cSrcweir             if (i == 0 && preferAbsoluteOverRelativePath
616cdf0e10cSrcweir                 && (preferAuthorityOverRelativePath
617cdf0e10cSrcweir                     || !uriReference->getPath().matchAsciiL(
618cdf0e10cSrcweir                         RTL_CONSTASCII_STRINGPARAM("//"))))
619cdf0e10cSrcweir             {
620cdf0e10cSrcweir                 if (baseUriReference->getPath().getLength() > 1
621cdf0e10cSrcweir                     || uriReference->getPath().getLength() > 1)
622cdf0e10cSrcweir                 {
623cdf0e10cSrcweir                     if (uriReference->getPath().getLength() == 0) {
624cdf0e10cSrcweir                         rel.append(static_cast< sal_Unicode >('/'));
625cdf0e10cSrcweir                     } else {
626cdf0e10cSrcweir                         OSL_ASSERT(uriReference->getPath()[0] == '/');
627cdf0e10cSrcweir                         if (uriReference->getPath().matchAsciiL(
628cdf0e10cSrcweir                                 RTL_CONSTASCII_STRINGPARAM("//"))) {
629cdf0e10cSrcweir                             OSL_ASSERT(uriReference->hasAuthority());
630cdf0e10cSrcweir                             rel.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
631cdf0e10cSrcweir                             rel.append(uriReference->getAuthority());
632cdf0e10cSrcweir                         }
633cdf0e10cSrcweir                         rel.append(uriReference->getPath());
634cdf0e10cSrcweir                     }
635cdf0e10cSrcweir                 }
636cdf0e10cSrcweir             } else {
637cdf0e10cSrcweir                 bool segments = false;
638cdf0e10cSrcweir                 for (sal_Int32 j = i; j < count1 - 1; ++j) {
639cdf0e10cSrcweir                     if (segments) {
640cdf0e10cSrcweir                         rel.append(static_cast< sal_Unicode >('/'));
641cdf0e10cSrcweir                     }
642cdf0e10cSrcweir                     rel.appendAscii(RTL_CONSTASCII_STRINGPARAM(".."));
643cdf0e10cSrcweir                     segments = true;
644cdf0e10cSrcweir                 }
645cdf0e10cSrcweir                 if (i < count2 - 1
646cdf0e10cSrcweir                     || (uriReference->getPathSegment(count2 - 1).getLength()
647cdf0e10cSrcweir                         != 0))
648cdf0e10cSrcweir                 {
649cdf0e10cSrcweir                     if (!segments
650cdf0e10cSrcweir                         && (uriReference->getPathSegment(i).getLength() == 0
651cdf0e10cSrcweir                             || (parseScheme(uriReference->getPathSegment(i))
652cdf0e10cSrcweir                                 >= 0)))
653cdf0e10cSrcweir                     {
654cdf0e10cSrcweir                         rel.append(static_cast< sal_Unicode >('.'));
655cdf0e10cSrcweir                         segments = true;
656cdf0e10cSrcweir                     }
657cdf0e10cSrcweir                     for (; i < count2; ++i) {
658cdf0e10cSrcweir                         if (segments) {
659cdf0e10cSrcweir                             rel.append(static_cast< sal_Unicode >('/'));
660cdf0e10cSrcweir                         }
661cdf0e10cSrcweir                         rtl::OUString s(uriReference->getPathSegment(i));
662cdf0e10cSrcweir                         if (encodeRetainedSpecialSegments
663cdf0e10cSrcweir                             && s.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(".")))
664cdf0e10cSrcweir                         {
665cdf0e10cSrcweir                             rel.appendAscii(RTL_CONSTASCII_STRINGPARAM("%2E"));
666cdf0e10cSrcweir                         } else if (encodeRetainedSpecialSegments
667cdf0e10cSrcweir                                    && s.equalsAsciiL(
668cdf0e10cSrcweir                                        RTL_CONSTASCII_STRINGPARAM("..")))
669cdf0e10cSrcweir                         {
670cdf0e10cSrcweir                             rel.appendAscii(
671cdf0e10cSrcweir                                 RTL_CONSTASCII_STRINGPARAM("%2E%2E"));
672cdf0e10cSrcweir                         } else {
673cdf0e10cSrcweir                             rel.append(s);
674cdf0e10cSrcweir                         }
675cdf0e10cSrcweir                         segments = true;
676cdf0e10cSrcweir                     }
677cdf0e10cSrcweir                 }
678cdf0e10cSrcweir             }
679cdf0e10cSrcweir         }
680cdf0e10cSrcweir         if (!omitQuery && uriReference->hasQuery()) {
681cdf0e10cSrcweir             rel.append(static_cast< sal_Unicode >('?'));
682cdf0e10cSrcweir             rel.append(uriReference->getQuery());
683cdf0e10cSrcweir         }
684cdf0e10cSrcweir         if (uriReference->hasFragment()) {
685cdf0e10cSrcweir             rel.append(static_cast< sal_Unicode >('#'));
686cdf0e10cSrcweir             rel.append(uriReference->getFragment());
687cdf0e10cSrcweir         }
688cdf0e10cSrcweir         return parse(rel.makeStringAndClear());
689cdf0e10cSrcweir     }
690cdf0e10cSrcweir }
691cdf0e10cSrcweir 
692cdf0e10cSrcweir }
693cdf0e10cSrcweir 
694cdf0e10cSrcweir namespace stoc_services { namespace UriReferenceFactory {
695cdf0e10cSrcweir 
create(css::uno::Reference<css::uno::XComponentContext> const & context)696cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface > create(
697cdf0e10cSrcweir     css::uno::Reference< css::uno::XComponentContext > const & context)
698cdf0e10cSrcweir     SAL_THROW((css::uno::Exception))
699cdf0e10cSrcweir {
700cdf0e10cSrcweir     try {
701cdf0e10cSrcweir         return static_cast< cppu::OWeakObject * >(new Factory(context));
702cdf0e10cSrcweir     } catch (std::bad_alloc &) {
703cdf0e10cSrcweir         throw css::uno::RuntimeException(
704cdf0e10cSrcweir             rtl::OUString::createFromAscii("std::bad_alloc"), 0);
705cdf0e10cSrcweir     }
706cdf0e10cSrcweir }
707cdf0e10cSrcweir 
getImplementationName()708cdf0e10cSrcweir rtl::OUString getImplementationName() {
709cdf0e10cSrcweir     return rtl::OUString::createFromAscii(
710cdf0e10cSrcweir         "com.sun.star.comp.uri.UriReferenceFactory");
711cdf0e10cSrcweir }
712cdf0e10cSrcweir 
getSupportedServiceNames()713cdf0e10cSrcweir css::uno::Sequence< rtl::OUString > getSupportedServiceNames() {
714cdf0e10cSrcweir     css::uno::Sequence< rtl::OUString > s(1);
715cdf0e10cSrcweir     s[0] = rtl::OUString::createFromAscii(
716cdf0e10cSrcweir         "com.sun.star.uri.UriReferenceFactory");
717cdf0e10cSrcweir     return s;
718cdf0e10cSrcweir }
719cdf0e10cSrcweir 
720cdf0e10cSrcweir } }
721