1*40df464eSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*40df464eSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*40df464eSAndrew Rist * or more contributor license agreements. See the NOTICE file
5*40df464eSAndrew Rist * distributed with this work for additional information
6*40df464eSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*40df464eSAndrew Rist * to you under the Apache License, Version 2.0 (the
8*40df464eSAndrew Rist * "License"); you may not use this file except in compliance
9*40df464eSAndrew Rist * with the License. You may obtain a copy of the License at
10*40df464eSAndrew Rist *
11*40df464eSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*40df464eSAndrew Rist *
13*40df464eSAndrew Rist * Unless required by applicable law or agreed to in writing,
14*40df464eSAndrew Rist * software distributed under the License is distributed on an
15*40df464eSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*40df464eSAndrew Rist * KIND, either express or implied. See the License for the
17*40df464eSAndrew Rist * specific language governing permissions and limitations
18*40df464eSAndrew Rist * under the License.
19*40df464eSAndrew Rist *
20*40df464eSAndrew Rist *************************************************************/
21*40df464eSAndrew Rist
22*40df464eSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svl.hxx"
26cdf0e10cSrcweir #include <svl/urihelper.hxx>
27cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
28cdf0e10cSrcweir #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
29cdf0e10cSrcweir #include "com/sun/star/lang/XMultiComponentFactory.hpp"
30cdf0e10cSrcweir #include "com/sun/star/ucb/Command.hpp"
31cdf0e10cSrcweir #include <com/sun/star/ucb/FileSystemNotation.hpp>
32cdf0e10cSrcweir #include "com/sun/star/ucb/IllegalIdentifierException.hpp"
33cdf0e10cSrcweir #include "com/sun/star/ucb/UnsupportedCommandException.hpp"
34cdf0e10cSrcweir #include "com/sun/star/ucb/XCommandEnvironment.hpp"
35cdf0e10cSrcweir #include "com/sun/star/ucb/XCommandProcessor.hpp"
36cdf0e10cSrcweir #include "com/sun/star/ucb/XContent.hpp"
37cdf0e10cSrcweir #include "com/sun/star/ucb/XContentIdentifierFactory.hpp"
38cdf0e10cSrcweir #include "com/sun/star/ucb/XContentProvider.hpp"
39cdf0e10cSrcweir #include <com/sun/star/ucb/XContentProviderManager.hpp>
40cdf0e10cSrcweir #include "com/sun/star/uno/Any.hxx"
41cdf0e10cSrcweir #include "com/sun/star/uno/Exception.hpp"
42cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx"
43cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
44cdf0e10cSrcweir #include "com/sun/star/uno/Sequence.hxx"
45cdf0e10cSrcweir #include "com/sun/star/uno/XComponentContext.hpp"
46cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp"
47cdf0e10cSrcweir #include "com/sun/star/uri/UriReferenceFactory.hpp"
48cdf0e10cSrcweir #include "com/sun/star/uri/XUriReference.hpp"
49cdf0e10cSrcweir #include "com/sun/star/uri/XUriReferenceFactory.hpp"
50cdf0e10cSrcweir #include "cppuhelper/exc_hlp.hxx"
51cdf0e10cSrcweir #include "comphelper/processfactory.hxx"
52cdf0e10cSrcweir #include "osl/diagnose.h"
53cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
54cdf0e10cSrcweir #include "rtl/ustring.h"
55cdf0e10cSrcweir #include "rtl/ustring.hxx"
56cdf0e10cSrcweir #include "sal/types.h"
57cdf0e10cSrcweir #include <tools/debug.hxx>
58cdf0e10cSrcweir #include <tools/inetmime.hxx>
59cdf0e10cSrcweir #include <ucbhelper/contentbroker.hxx>
60cdf0e10cSrcweir #include <unotools/charclass.hxx>
61cdf0e10cSrcweir #include "rtl/instance.hxx"
62cdf0e10cSrcweir
63cdf0e10cSrcweir namespace unnamed_svl_urihelper {}
64cdf0e10cSrcweir using namespace unnamed_svl_urihelper;
65cdf0e10cSrcweir // unnamed namespaces don't work well yet...
66cdf0e10cSrcweir
67cdf0e10cSrcweir namespace css = com::sun::star;
68cdf0e10cSrcweir using namespace com::sun::star;
69cdf0e10cSrcweir
70cdf0e10cSrcweir //============================================================================
71cdf0e10cSrcweir //
72cdf0e10cSrcweir // SmartRel2Abs
73cdf0e10cSrcweir //
74cdf0e10cSrcweir //============================================================================
75cdf0e10cSrcweir
76cdf0e10cSrcweir namespace unnamed_svl_urihelper {
77cdf0e10cSrcweir
toUniString(ByteString const & rString)78cdf0e10cSrcweir inline UniString toUniString(ByteString const & rString)
79cdf0e10cSrcweir {
80cdf0e10cSrcweir return UniString(rString, RTL_TEXTENCODING_ISO_8859_1);
81cdf0e10cSrcweir }
82cdf0e10cSrcweir
toUniString(UniString const & rString)83cdf0e10cSrcweir inline UniString toUniString(UniString const & rString)
84cdf0e10cSrcweir {
85cdf0e10cSrcweir return rString;
86cdf0e10cSrcweir }
87cdf0e10cSrcweir
88cdf0e10cSrcweir template< typename Str >
SmartRel2Abs_Impl(INetURLObject const & rTheBaseURIRef,Str const & rTheRelURIRef,Link const & rMaybeFileHdl,bool bCheckFileExists,bool bIgnoreFragment,INetURLObject::EncodeMechanism eEncodeMechanism,INetURLObject::DecodeMechanism eDecodeMechanism,rtl_TextEncoding eCharset,bool bRelativeNonURIs,INetURLObject::FSysStyle eStyle)89cdf0e10cSrcweir inline UniString SmartRel2Abs_Impl(INetURLObject const & rTheBaseURIRef,
90cdf0e10cSrcweir Str const & rTheRelURIRef,
91cdf0e10cSrcweir Link const & rMaybeFileHdl,
92cdf0e10cSrcweir bool bCheckFileExists,
93cdf0e10cSrcweir bool bIgnoreFragment,
94cdf0e10cSrcweir INetURLObject::EncodeMechanism
95cdf0e10cSrcweir eEncodeMechanism,
96cdf0e10cSrcweir INetURLObject::DecodeMechanism
97cdf0e10cSrcweir eDecodeMechanism,
98cdf0e10cSrcweir rtl_TextEncoding eCharset,
99cdf0e10cSrcweir bool bRelativeNonURIs,
100cdf0e10cSrcweir INetURLObject::FSysStyle eStyle)
101cdf0e10cSrcweir {
102cdf0e10cSrcweir // Backwards compatibility:
103cdf0e10cSrcweir if (rTheRelURIRef.Len() != 0 && rTheRelURIRef.GetChar(0) == '#')
104cdf0e10cSrcweir return toUniString(rTheRelURIRef);
105cdf0e10cSrcweir
106cdf0e10cSrcweir INetURLObject aAbsURIRef;
107cdf0e10cSrcweir if (rTheBaseURIRef.HasError())
108cdf0e10cSrcweir aAbsURIRef.
109cdf0e10cSrcweir SetSmartURL(rTheRelURIRef, eEncodeMechanism, eCharset, eStyle);
110cdf0e10cSrcweir else
111cdf0e10cSrcweir {
112cdf0e10cSrcweir bool bWasAbsolute;
113cdf0e10cSrcweir aAbsURIRef = rTheBaseURIRef.smartRel2Abs(rTheRelURIRef,
114cdf0e10cSrcweir bWasAbsolute,
115cdf0e10cSrcweir bIgnoreFragment,
116cdf0e10cSrcweir eEncodeMechanism,
117cdf0e10cSrcweir eCharset,
118cdf0e10cSrcweir bRelativeNonURIs,
119cdf0e10cSrcweir eStyle);
120cdf0e10cSrcweir if (bCheckFileExists
121cdf0e10cSrcweir && !bWasAbsolute
122cdf0e10cSrcweir && (aAbsURIRef.GetProtocol() == INET_PROT_FILE))
123cdf0e10cSrcweir {
124cdf0e10cSrcweir INetURLObject aNonFileURIRef;
125cdf0e10cSrcweir aNonFileURIRef.SetSmartURL(rTheRelURIRef,
126cdf0e10cSrcweir eEncodeMechanism,
127cdf0e10cSrcweir eCharset,
128cdf0e10cSrcweir eStyle);
129cdf0e10cSrcweir if (!aNonFileURIRef.HasError()
130cdf0e10cSrcweir && aNonFileURIRef.GetProtocol() != INET_PROT_FILE)
131cdf0e10cSrcweir {
132cdf0e10cSrcweir bool bMaybeFile = false;
133cdf0e10cSrcweir if (rMaybeFileHdl.IsSet())
134cdf0e10cSrcweir {
135cdf0e10cSrcweir UniString aFilePath(toUniString(rTheRelURIRef));
136cdf0e10cSrcweir bMaybeFile = rMaybeFileHdl.Call(&aFilePath) != 0;
137cdf0e10cSrcweir }
138cdf0e10cSrcweir if (!bMaybeFile)
139cdf0e10cSrcweir aAbsURIRef = aNonFileURIRef;
140cdf0e10cSrcweir }
141cdf0e10cSrcweir }
142cdf0e10cSrcweir }
143cdf0e10cSrcweir return aAbsURIRef.GetMainURL(eDecodeMechanism, eCharset);
144cdf0e10cSrcweir }
145cdf0e10cSrcweir
146cdf0e10cSrcweir }
147cdf0e10cSrcweir
148cdf0e10cSrcweir UniString
SmartRel2Abs(INetURLObject const & rTheBaseURIRef,ByteString const & rTheRelURIRef,Link const & rMaybeFileHdl,bool bCheckFileExists,bool bIgnoreFragment,INetURLObject::EncodeMechanism eEncodeMechanism,INetURLObject::DecodeMechanism eDecodeMechanism,rtl_TextEncoding eCharset,bool bRelativeNonURIs,INetURLObject::FSysStyle eStyle)149cdf0e10cSrcweir URIHelper::SmartRel2Abs(INetURLObject const & rTheBaseURIRef,
150cdf0e10cSrcweir ByteString const & rTheRelURIRef,
151cdf0e10cSrcweir Link const & rMaybeFileHdl,
152cdf0e10cSrcweir bool bCheckFileExists,
153cdf0e10cSrcweir bool bIgnoreFragment,
154cdf0e10cSrcweir INetURLObject::EncodeMechanism eEncodeMechanism,
155cdf0e10cSrcweir INetURLObject::DecodeMechanism eDecodeMechanism,
156cdf0e10cSrcweir rtl_TextEncoding eCharset,
157cdf0e10cSrcweir bool bRelativeNonURIs,
158cdf0e10cSrcweir INetURLObject::FSysStyle eStyle)
159cdf0e10cSrcweir {
160cdf0e10cSrcweir return SmartRel2Abs_Impl(rTheBaseURIRef, rTheRelURIRef, rMaybeFileHdl,
161cdf0e10cSrcweir bCheckFileExists, bIgnoreFragment,
162cdf0e10cSrcweir eEncodeMechanism, eDecodeMechanism, eCharset,
163cdf0e10cSrcweir bRelativeNonURIs, eStyle);
164cdf0e10cSrcweir }
165cdf0e10cSrcweir
166cdf0e10cSrcweir UniString
SmartRel2Abs(INetURLObject const & rTheBaseURIRef,UniString const & rTheRelURIRef,Link const & rMaybeFileHdl,bool bCheckFileExists,bool bIgnoreFragment,INetURLObject::EncodeMechanism eEncodeMechanism,INetURLObject::DecodeMechanism eDecodeMechanism,rtl_TextEncoding eCharset,bool bRelativeNonURIs,INetURLObject::FSysStyle eStyle)167cdf0e10cSrcweir URIHelper::SmartRel2Abs(INetURLObject const & rTheBaseURIRef,
168cdf0e10cSrcweir UniString const & rTheRelURIRef,
169cdf0e10cSrcweir Link const & rMaybeFileHdl,
170cdf0e10cSrcweir bool bCheckFileExists,
171cdf0e10cSrcweir bool bIgnoreFragment,
172cdf0e10cSrcweir INetURLObject::EncodeMechanism eEncodeMechanism,
173cdf0e10cSrcweir INetURLObject::DecodeMechanism eDecodeMechanism,
174cdf0e10cSrcweir rtl_TextEncoding eCharset,
175cdf0e10cSrcweir bool bRelativeNonURIs,
176cdf0e10cSrcweir INetURLObject::FSysStyle eStyle)
177cdf0e10cSrcweir {
178cdf0e10cSrcweir return SmartRel2Abs_Impl(rTheBaseURIRef, rTheRelURIRef, rMaybeFileHdl,
179cdf0e10cSrcweir bCheckFileExists, bIgnoreFragment,
180cdf0e10cSrcweir eEncodeMechanism, eDecodeMechanism, eCharset,
181cdf0e10cSrcweir bRelativeNonURIs, eStyle);
182cdf0e10cSrcweir }
183cdf0e10cSrcweir
184cdf0e10cSrcweir //============================================================================
185cdf0e10cSrcweir //
186cdf0e10cSrcweir // SetMaybeFileHdl
187cdf0e10cSrcweir //
188cdf0e10cSrcweir //============================================================================
189cdf0e10cSrcweir
190cdf0e10cSrcweir namespace { struct MaybeFileHdl : public rtl::Static< Link, MaybeFileHdl > {}; }
191cdf0e10cSrcweir
SetMaybeFileHdl(Link const & rTheMaybeFileHdl)192cdf0e10cSrcweir void URIHelper::SetMaybeFileHdl(Link const & rTheMaybeFileHdl)
193cdf0e10cSrcweir {
194cdf0e10cSrcweir MaybeFileHdl::get() = rTheMaybeFileHdl;
195cdf0e10cSrcweir }
196cdf0e10cSrcweir
197cdf0e10cSrcweir //============================================================================
198cdf0e10cSrcweir //
199cdf0e10cSrcweir // GetMaybeFileHdl
200cdf0e10cSrcweir //
201cdf0e10cSrcweir //============================================================================
202cdf0e10cSrcweir
GetMaybeFileHdl()203cdf0e10cSrcweir Link URIHelper::GetMaybeFileHdl()
204cdf0e10cSrcweir {
205cdf0e10cSrcweir return MaybeFileHdl::get();
206cdf0e10cSrcweir }
207cdf0e10cSrcweir
208cdf0e10cSrcweir namespace {
209cdf0e10cSrcweir
isAbsoluteHierarchicalUriReference(css::uno::Reference<css::uri::XUriReference> const & uriReference)210cdf0e10cSrcweir bool isAbsoluteHierarchicalUriReference(
211cdf0e10cSrcweir css::uno::Reference< css::uri::XUriReference > const & uriReference)
212cdf0e10cSrcweir {
213cdf0e10cSrcweir return uriReference.is() && uriReference->isAbsolute()
214cdf0e10cSrcweir && uriReference->isHierarchical() && !uriReference->hasRelativePath();
215cdf0e10cSrcweir }
216cdf0e10cSrcweir
217cdf0e10cSrcweir // To improve performance, assume that if for any prefix URL of a given
218cdf0e10cSrcweir // hierarchical URL either a UCB content cannot be created, or the UCB content
219cdf0e10cSrcweir // does not support the getCasePreservingURL command, then this will hold for
220cdf0e10cSrcweir // any other prefix URL of the given URL, too:
221cdf0e10cSrcweir enum Result { Success, GeneralFailure, SpecificFailure };
222cdf0e10cSrcweir
normalizePrefix(css::uno::Reference<css::ucb::XContentProvider> const & broker,rtl::OUString const & uri,rtl::OUString * normalized)223cdf0e10cSrcweir Result normalizePrefix(
224cdf0e10cSrcweir css::uno::Reference< css::ucb::XContentProvider > const & broker,
225cdf0e10cSrcweir rtl::OUString const & uri, rtl::OUString * normalized)
226cdf0e10cSrcweir {
227cdf0e10cSrcweir OSL_ASSERT(broker.is() && normalized != 0);
228cdf0e10cSrcweir css::uno::Reference< css::ucb::XContent > content;
229cdf0e10cSrcweir try {
230cdf0e10cSrcweir content = broker->queryContent(
231cdf0e10cSrcweir css::uno::Reference< css::ucb::XContentIdentifierFactory >(
232cdf0e10cSrcweir broker, css::uno::UNO_QUERY_THROW)->createContentIdentifier(
233cdf0e10cSrcweir uri));
234cdf0e10cSrcweir } catch (css::ucb::IllegalIdentifierException &) {}
235cdf0e10cSrcweir if (!content.is()) {
236cdf0e10cSrcweir return GeneralFailure;
237cdf0e10cSrcweir }
238cdf0e10cSrcweir try {
239cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
240cdf0e10cSrcweir bool ok =
241cdf0e10cSrcweir #endif
242cdf0e10cSrcweir (css::uno::Reference< css::ucb::XCommandProcessor >(
243cdf0e10cSrcweir content, css::uno::UNO_QUERY_THROW)->execute(
244cdf0e10cSrcweir css::ucb::Command(
245cdf0e10cSrcweir rtl::OUString(
246cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
247cdf0e10cSrcweir "getCasePreservingURL")),
248cdf0e10cSrcweir -1, css::uno::Any()),
249cdf0e10cSrcweir 0,
250cdf0e10cSrcweir css::uno::Reference< css::ucb::XCommandEnvironment >())
251cdf0e10cSrcweir >>= *normalized);
252cdf0e10cSrcweir OSL_ASSERT(ok);
253cdf0e10cSrcweir } catch (css::uno::RuntimeException &) {
254cdf0e10cSrcweir throw;
255cdf0e10cSrcweir } catch (css::ucb::UnsupportedCommandException &) {
256cdf0e10cSrcweir return GeneralFailure;
257cdf0e10cSrcweir } catch (css::uno::Exception &) {
258cdf0e10cSrcweir return SpecificFailure;
259cdf0e10cSrcweir }
260cdf0e10cSrcweir return Success;
261cdf0e10cSrcweir }
262cdf0e10cSrcweir
normalize(css::uno::Reference<css::ucb::XContentProvider> const & broker,css::uno::Reference<css::uri::XUriReferenceFactory> const & uriFactory,rtl::OUString const & uriReference)263cdf0e10cSrcweir rtl::OUString normalize(
264cdf0e10cSrcweir css::uno::Reference< css::ucb::XContentProvider > const & broker,
265cdf0e10cSrcweir css::uno::Reference< css::uri::XUriReferenceFactory > const & uriFactory,
266cdf0e10cSrcweir rtl::OUString const & uriReference)
267cdf0e10cSrcweir {
268cdf0e10cSrcweir // normalizePrefix can potentially fail (a typically example being a file
269cdf0e10cSrcweir // URL that denotes a non-existing resource); in such a case, try to
270cdf0e10cSrcweir // normalize as long a prefix of the given URL as possible (i.e., normalize
271cdf0e10cSrcweir // all the existing directories within the path):
272cdf0e10cSrcweir rtl::OUString normalized;
273cdf0e10cSrcweir sal_Int32 n = uriReference.indexOf('#');
274cdf0e10cSrcweir normalized = n == -1 ? uriReference : uriReference.copy(0, n);
275cdf0e10cSrcweir switch (normalizePrefix(broker, normalized, &normalized)) {
276cdf0e10cSrcweir case Success:
277cdf0e10cSrcweir return n == -1 ? normalized : normalized + uriReference.copy(n);
278cdf0e10cSrcweir case GeneralFailure:
279cdf0e10cSrcweir return uriReference;
280cdf0e10cSrcweir case SpecificFailure:
281cdf0e10cSrcweir default:
282cdf0e10cSrcweir break;
283cdf0e10cSrcweir }
284cdf0e10cSrcweir css::uno::Reference< css::uri::XUriReference > ref(
285cdf0e10cSrcweir uriFactory->parse(uriReference));
286cdf0e10cSrcweir if (!isAbsoluteHierarchicalUriReference(ref)) {
287cdf0e10cSrcweir return uriReference;
288cdf0e10cSrcweir }
289cdf0e10cSrcweir sal_Int32 count = ref->getPathSegmentCount();
290cdf0e10cSrcweir if (count < 2) {
291cdf0e10cSrcweir return uriReference;
292cdf0e10cSrcweir }
293cdf0e10cSrcweir rtl::OUStringBuffer head(ref->getScheme());
294cdf0e10cSrcweir head.append(static_cast< sal_Unicode >(':'));
295cdf0e10cSrcweir if (ref->hasAuthority()) {
296cdf0e10cSrcweir head.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
297cdf0e10cSrcweir head.append(ref->getAuthority());
298cdf0e10cSrcweir }
299cdf0e10cSrcweir for (sal_Int32 i = count - 1; i > 0; --i) {
300cdf0e10cSrcweir rtl::OUStringBuffer buf(head);
301cdf0e10cSrcweir for (sal_Int32 j = 0; j < i; ++j) {
302cdf0e10cSrcweir buf.append(static_cast< sal_Unicode >('/'));
303cdf0e10cSrcweir buf.append(ref->getPathSegment(j));
304cdf0e10cSrcweir }
305cdf0e10cSrcweir normalized = buf.makeStringAndClear();
306cdf0e10cSrcweir if (normalizePrefix(broker, normalized, &normalized) != SpecificFailure)
307cdf0e10cSrcweir {
308cdf0e10cSrcweir buf.append(normalized);
309cdf0e10cSrcweir css::uno::Reference< css::uri::XUriReference > preRef(
310cdf0e10cSrcweir uriFactory->parse(normalized));
311cdf0e10cSrcweir if (!isAbsoluteHierarchicalUriReference(preRef)) {
312cdf0e10cSrcweir // This could only happen if something is inconsistent:
313cdf0e10cSrcweir break;
314cdf0e10cSrcweir }
315cdf0e10cSrcweir sal_Int32 preCount = preRef->getPathSegmentCount();
316cdf0e10cSrcweir // normalizePrefix may have added or removed a final slash:
317cdf0e10cSrcweir if (preCount != i) {
318cdf0e10cSrcweir if (preCount == i - 1) {
319cdf0e10cSrcweir buf.append(static_cast< sal_Unicode >('/'));
320cdf0e10cSrcweir } else if (preCount - 1 == i && buf.getLength() > 0
321cdf0e10cSrcweir && buf.charAt(buf.getLength() - 1) == '/')
322cdf0e10cSrcweir {
323cdf0e10cSrcweir buf.setLength(buf.getLength() - 1);
324cdf0e10cSrcweir } else {
325cdf0e10cSrcweir // This could only happen if something is inconsistent:
326cdf0e10cSrcweir break;
327cdf0e10cSrcweir }
328cdf0e10cSrcweir }
329cdf0e10cSrcweir for (sal_Int32 j = i; j < count; ++j) {
330cdf0e10cSrcweir buf.append(static_cast< sal_Unicode >('/'));
331cdf0e10cSrcweir buf.append(ref->getPathSegment(j));
332cdf0e10cSrcweir }
333cdf0e10cSrcweir if (ref->hasQuery()) {
334cdf0e10cSrcweir buf.append(static_cast< sal_Unicode >('?'));
335cdf0e10cSrcweir buf.append(ref->getQuery());
336cdf0e10cSrcweir }
337cdf0e10cSrcweir if (ref->hasFragment()) {
338cdf0e10cSrcweir buf.append(static_cast< sal_Unicode >('#'));
339cdf0e10cSrcweir buf.append(ref->getFragment());
340cdf0e10cSrcweir }
341cdf0e10cSrcweir return buf.makeStringAndClear();
342cdf0e10cSrcweir }
343cdf0e10cSrcweir }
344cdf0e10cSrcweir return uriReference;
345cdf0e10cSrcweir }
346cdf0e10cSrcweir
347cdf0e10cSrcweir }
348cdf0e10cSrcweir
349cdf0e10cSrcweir css::uno::Reference< css::uri::XUriReference >
normalizedMakeRelative(css::uno::Reference<css::uno::XComponentContext> const & context,rtl::OUString const & baseUriReference,rtl::OUString const & uriReference)350cdf0e10cSrcweir URIHelper::normalizedMakeRelative(
351cdf0e10cSrcweir css::uno::Reference< css::uno::XComponentContext > const & context,
352cdf0e10cSrcweir rtl::OUString const & baseUriReference, rtl::OUString const & uriReference)
353cdf0e10cSrcweir {
354cdf0e10cSrcweir OSL_ASSERT(context.is());
355cdf0e10cSrcweir css::uno::Reference< css::lang::XMultiComponentFactory > componentFactory(
356cdf0e10cSrcweir context->getServiceManager());
357cdf0e10cSrcweir if (!componentFactory.is()) {
358cdf0e10cSrcweir throw css::uno::RuntimeException(
359cdf0e10cSrcweir rtl::OUString(
360cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
361cdf0e10cSrcweir "component context has no service manager")),
362cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
363cdf0e10cSrcweir }
364cdf0e10cSrcweir css::uno::Sequence< css::uno::Any > args(2);
365cdf0e10cSrcweir args[0] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Local"));
366cdf0e10cSrcweir args[1] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office"));
367cdf0e10cSrcweir css::uno::Reference< css::ucb::XContentProvider > broker;
368cdf0e10cSrcweir try {
369cdf0e10cSrcweir broker = css::uno::Reference< css::ucb::XContentProvider >(
370cdf0e10cSrcweir componentFactory->createInstanceWithArgumentsAndContext(
371cdf0e10cSrcweir rtl::OUString(
372cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
373cdf0e10cSrcweir "com.sun.star.ucb.UniversalContentBroker")),
374cdf0e10cSrcweir args, context),
375cdf0e10cSrcweir css::uno::UNO_QUERY_THROW);
376cdf0e10cSrcweir } catch (css::uno::RuntimeException &) {
377cdf0e10cSrcweir throw;
378cdf0e10cSrcweir } catch (css::uno::Exception &) {
379cdf0e10cSrcweir css::uno::Any exception(cppu::getCaughtException());
380cdf0e10cSrcweir throw css::lang::WrappedTargetRuntimeException(
381cdf0e10cSrcweir rtl::OUString(
382cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
383cdf0e10cSrcweir "creating com.sun.star.ucb.UniversalContentBroker failed")),
384cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >(),
385cdf0e10cSrcweir exception);
386cdf0e10cSrcweir }
387cdf0e10cSrcweir css::uno::Reference< css::uri::XUriReferenceFactory > uriFactory(
388cdf0e10cSrcweir css::uri::UriReferenceFactory::create(context));
389cdf0e10cSrcweir return uriFactory->makeRelative(
390cdf0e10cSrcweir uriFactory->parse(normalize(broker, uriFactory, baseUriReference)),
391cdf0e10cSrcweir uriFactory->parse(normalize(broker, uriFactory, uriReference)), true,
392cdf0e10cSrcweir true, false);
393cdf0e10cSrcweir }
394cdf0e10cSrcweir
simpleNormalizedMakeRelative(rtl::OUString const & baseUriReference,rtl::OUString const & uriReference)395cdf0e10cSrcweir rtl::OUString URIHelper::simpleNormalizedMakeRelative(
396cdf0e10cSrcweir rtl::OUString const & baseUriReference, rtl::OUString const & uriReference)
397cdf0e10cSrcweir {
398cdf0e10cSrcweir com::sun::star::uno::Reference< com::sun::star::uri::XUriReference > rel(
399cdf0e10cSrcweir URIHelper::normalizedMakeRelative(
400cdf0e10cSrcweir com::sun::star::uno::Reference<
401cdf0e10cSrcweir com::sun::star::uno::XComponentContext >(
402cdf0e10cSrcweir (com::sun::star::uno::Reference<
403cdf0e10cSrcweir com::sun::star::beans::XPropertySet >(
404cdf0e10cSrcweir comphelper::getProcessServiceFactory(),
405cdf0e10cSrcweir com::sun::star::uno::UNO_QUERY_THROW)->
406cdf0e10cSrcweir getPropertyValue(
407cdf0e10cSrcweir rtl::OUString(
408cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("DefaultContext")))),
409cdf0e10cSrcweir com::sun::star::uno::UNO_QUERY_THROW),
410cdf0e10cSrcweir baseUriReference, uriReference));
411cdf0e10cSrcweir return rel.is() ? rel->getUriReference() : uriReference;
412cdf0e10cSrcweir }
413cdf0e10cSrcweir
414cdf0e10cSrcweir //============================================================================
415cdf0e10cSrcweir //
416cdf0e10cSrcweir // FindFirstURLInText
417cdf0e10cSrcweir //
418cdf0e10cSrcweir //============================================================================
419cdf0e10cSrcweir
420cdf0e10cSrcweir namespace unnamed_svl_urihelper {
421cdf0e10cSrcweir
nextChar(UniString const & rStr,xub_StrLen nPos)422cdf0e10cSrcweir inline xub_StrLen nextChar(UniString const & rStr, xub_StrLen nPos)
423cdf0e10cSrcweir {
424cdf0e10cSrcweir return INetMIME::isHighSurrogate(rStr.GetChar(nPos))
425cdf0e10cSrcweir && rStr.Len() - nPos >= 2
426cdf0e10cSrcweir && INetMIME::isLowSurrogate(rStr.GetChar(nPos + 1)) ?
427cdf0e10cSrcweir nPos + 2 : nPos + 1;
428cdf0e10cSrcweir }
429cdf0e10cSrcweir
isBoundary1(CharClass const & rCharClass,UniString const & rStr,xub_StrLen nPos,xub_StrLen nEnd)430cdf0e10cSrcweir bool isBoundary1(CharClass const & rCharClass, UniString const & rStr,
431cdf0e10cSrcweir xub_StrLen nPos, xub_StrLen nEnd)
432cdf0e10cSrcweir {
433cdf0e10cSrcweir if (nPos == nEnd)
434cdf0e10cSrcweir return true;
435cdf0e10cSrcweir if (rCharClass.isLetterNumeric(rStr, nPos))
436cdf0e10cSrcweir return false;
437cdf0e10cSrcweir switch (rStr.GetChar(nPos))
438cdf0e10cSrcweir {
439cdf0e10cSrcweir case '$':
440cdf0e10cSrcweir case '%':
441cdf0e10cSrcweir case '&':
442cdf0e10cSrcweir case '-':
443cdf0e10cSrcweir case '/':
444cdf0e10cSrcweir case '@':
445cdf0e10cSrcweir case '\\':
446cdf0e10cSrcweir return false;
447cdf0e10cSrcweir default:
448cdf0e10cSrcweir return true;
449cdf0e10cSrcweir }
450cdf0e10cSrcweir }
451cdf0e10cSrcweir
isBoundary2(CharClass const & rCharClass,UniString const & rStr,xub_StrLen nPos,xub_StrLen nEnd)452cdf0e10cSrcweir bool isBoundary2(CharClass const & rCharClass, UniString const & rStr,
453cdf0e10cSrcweir xub_StrLen nPos, xub_StrLen nEnd)
454cdf0e10cSrcweir {
455cdf0e10cSrcweir if (nPos == nEnd)
456cdf0e10cSrcweir return true;
457cdf0e10cSrcweir if (rCharClass.isLetterNumeric(rStr, nPos))
458cdf0e10cSrcweir return false;
459cdf0e10cSrcweir switch (rStr.GetChar(nPos))
460cdf0e10cSrcweir {
461cdf0e10cSrcweir case '!':
462cdf0e10cSrcweir case '#':
463cdf0e10cSrcweir case '$':
464cdf0e10cSrcweir case '%':
465cdf0e10cSrcweir case '&':
466cdf0e10cSrcweir case '\'':
467cdf0e10cSrcweir case '*':
468cdf0e10cSrcweir case '+':
469cdf0e10cSrcweir case '-':
470cdf0e10cSrcweir case '/':
471cdf0e10cSrcweir case '=':
472cdf0e10cSrcweir case '?':
473cdf0e10cSrcweir case '@':
474cdf0e10cSrcweir case '^':
475cdf0e10cSrcweir case '_':
476cdf0e10cSrcweir case '`':
477cdf0e10cSrcweir case '{':
478cdf0e10cSrcweir case '|':
479cdf0e10cSrcweir case '}':
480cdf0e10cSrcweir case '~':
481cdf0e10cSrcweir return false;
482cdf0e10cSrcweir default:
483cdf0e10cSrcweir return true;
484cdf0e10cSrcweir }
485cdf0e10cSrcweir }
486cdf0e10cSrcweir
checkWChar(CharClass const & rCharClass,UniString const & rStr,xub_StrLen * pPos,xub_StrLen * pEnd,bool bBackslash=false,bool bPipe=false)487cdf0e10cSrcweir bool checkWChar(CharClass const & rCharClass, UniString const & rStr,
488cdf0e10cSrcweir xub_StrLen * pPos, xub_StrLen * pEnd, bool bBackslash = false,
489cdf0e10cSrcweir bool bPipe = false)
490cdf0e10cSrcweir {
491cdf0e10cSrcweir sal_Unicode c = rStr.GetChar(*pPos);
492cdf0e10cSrcweir if (INetMIME::isUSASCII(c))
493cdf0e10cSrcweir {
494cdf0e10cSrcweir static sal_uInt8 const aMap[128]
495cdf0e10cSrcweir = { 0, 0, 0, 0, 0, 0, 0, 0,
496cdf0e10cSrcweir 0, 0, 0, 0, 0, 0, 0, 0,
497cdf0e10cSrcweir 0, 0, 0, 0, 0, 0, 0, 0,
498cdf0e10cSrcweir 0, 0, 0, 0, 0, 0, 0, 0,
499cdf0e10cSrcweir 0, 1, 0, 0, 4, 4, 4, 1, // !"#$%&'
500cdf0e10cSrcweir 1, 1, 1, 1, 1, 4, 1, 4, // ()*+,-./
501cdf0e10cSrcweir 4, 4, 4, 4, 4, 4, 4, 4, // 01234567
502cdf0e10cSrcweir 4, 4, 1, 1, 0, 1, 0, 1, // 89:;<=>?
503cdf0e10cSrcweir 4, 4, 4, 4, 4, 4, 4, 4, // @ABCDEFG
504cdf0e10cSrcweir 4, 4, 4, 4, 4, 4, 4, 4, // HIJKLMNO
505cdf0e10cSrcweir 4, 4, 4, 4, 4, 4, 4, 4, // PQRSTUVW
506cdf0e10cSrcweir 4, 4, 4, 1, 2, 1, 0, 1, // XYZ[\]^_
507cdf0e10cSrcweir 0, 4, 4, 4, 4, 4, 4, 4, // `abcdefg
508cdf0e10cSrcweir 4, 4, 4, 4, 4, 4, 4, 4, // hijklmno
509cdf0e10cSrcweir 4, 4, 4, 4, 4, 4, 4, 4, // pqrstuvw
510cdf0e10cSrcweir 4, 4, 4, 0, 3, 0, 1, 0 }; // xyz{|}~
511cdf0e10cSrcweir switch (aMap[c])
512cdf0e10cSrcweir {
513cdf0e10cSrcweir default: // not uric
514cdf0e10cSrcweir return false;
515cdf0e10cSrcweir
516cdf0e10cSrcweir case 1: // uric
517cdf0e10cSrcweir ++(*pPos);
518cdf0e10cSrcweir return true;
519cdf0e10cSrcweir
520cdf0e10cSrcweir case 2: // "\"
521cdf0e10cSrcweir if (bBackslash)
522cdf0e10cSrcweir {
523cdf0e10cSrcweir *pEnd = ++(*pPos);
524cdf0e10cSrcweir return true;
525cdf0e10cSrcweir }
526cdf0e10cSrcweir else
527cdf0e10cSrcweir return false;
528cdf0e10cSrcweir
529cdf0e10cSrcweir case 3: // "|"
530cdf0e10cSrcweir if (bPipe)
531cdf0e10cSrcweir {
532cdf0e10cSrcweir *pEnd = ++(*pPos);
533cdf0e10cSrcweir return true;
534cdf0e10cSrcweir }
535cdf0e10cSrcweir else
536cdf0e10cSrcweir return false;
537cdf0e10cSrcweir
538cdf0e10cSrcweir case 4: // alpha, digit, "$", "%", "&", "-", "/", "@" (see
539cdf0e10cSrcweir // isBoundary1)
540cdf0e10cSrcweir *pEnd = ++(*pPos);
541cdf0e10cSrcweir return true;
542cdf0e10cSrcweir }
543cdf0e10cSrcweir }
544cdf0e10cSrcweir else if (rCharClass.isLetterNumeric(rStr, *pPos))
545cdf0e10cSrcweir {
546cdf0e10cSrcweir *pEnd = *pPos = nextChar(rStr, *pPos);
547cdf0e10cSrcweir return true;
548cdf0e10cSrcweir }
549cdf0e10cSrcweir else
550cdf0e10cSrcweir return false;
551cdf0e10cSrcweir }
552cdf0e10cSrcweir
scanDomain(UniString const & rStr,xub_StrLen * pPos,xub_StrLen nEnd)553cdf0e10cSrcweir sal_uInt32 scanDomain(UniString const & rStr, xub_StrLen * pPos,
554cdf0e10cSrcweir xub_StrLen nEnd)
555cdf0e10cSrcweir {
556cdf0e10cSrcweir sal_Unicode const * pBuffer = rStr.GetBuffer();
557cdf0e10cSrcweir sal_Unicode const * p = pBuffer + *pPos;
558cdf0e10cSrcweir sal_uInt32 nLabels = INetURLObject::scanDomain(p, pBuffer + nEnd, false);
559cdf0e10cSrcweir *pPos = sal::static_int_cast< xub_StrLen >(p - pBuffer);
560cdf0e10cSrcweir return nLabels;
561cdf0e10cSrcweir }
562cdf0e10cSrcweir
563cdf0e10cSrcweir }
564cdf0e10cSrcweir
565cdf0e10cSrcweir UniString
FindFirstURLInText(UniString const & rText,xub_StrLen & rBegin,xub_StrLen & rEnd,CharClass const & rCharClass,INetURLObject::EncodeMechanism eMechanism,rtl_TextEncoding eCharset,INetURLObject::FSysStyle eStyle)566cdf0e10cSrcweir URIHelper::FindFirstURLInText(UniString const & rText,
567cdf0e10cSrcweir xub_StrLen & rBegin,
568cdf0e10cSrcweir xub_StrLen & rEnd,
569cdf0e10cSrcweir CharClass const & rCharClass,
570cdf0e10cSrcweir INetURLObject::EncodeMechanism eMechanism,
571cdf0e10cSrcweir rtl_TextEncoding eCharset,
572cdf0e10cSrcweir INetURLObject::FSysStyle eStyle)
573cdf0e10cSrcweir {
574cdf0e10cSrcweir if (!(rBegin <= rEnd && rEnd <= rText.Len()))
575cdf0e10cSrcweir return UniString();
576cdf0e10cSrcweir
577cdf0e10cSrcweir // Search for the first substring of [rBegin..rEnd[ that matches any of the
578cdf0e10cSrcweir // following productions (for which the appropriate style bit is set in
579cdf0e10cSrcweir // eStyle, if applicable).
580cdf0e10cSrcweir //
581cdf0e10cSrcweir // 1st Production (known scheme):
582cdf0e10cSrcweir // \B1 <one of the known schemes, except file> ":" 1*wchar ["#" 1*wchar]
583cdf0e10cSrcweir // \B1
584cdf0e10cSrcweir //
585cdf0e10cSrcweir // 2nd Production (file):
586cdf0e10cSrcweir // \B1 "FILE:" 1*(wchar / "\" / "|") ["#" 1*wchar] \B1
587cdf0e10cSrcweir //
588cdf0e10cSrcweir // 3rd Production (ftp):
589cdf0e10cSrcweir // \B1 "FTP" 2*("." label) ["/" *wchar] ["#" 1*wchar] \B1
590cdf0e10cSrcweir //
591cdf0e10cSrcweir // 4th Production (http):
592cdf0e10cSrcweir // \B1 "WWW" 2*("." label) ["/" *wchar] ["#" 1*wchar] \B1
593cdf0e10cSrcweir //
594cdf0e10cSrcweir // 5th Production (mailto):
595cdf0e10cSrcweir // \B2 local-part "@" domain \B1
596cdf0e10cSrcweir //
597cdf0e10cSrcweir // 6th Production (UNC file):
598cdf0e10cSrcweir // \B1 "\\" domain "\" *(wchar / "\") \B1
599cdf0e10cSrcweir //
600cdf0e10cSrcweir // 7th Production (DOS file):
601cdf0e10cSrcweir // \B1 ALPHA ":\" *(wchar / "\") \B1
602cdf0e10cSrcweir //
603cdf0e10cSrcweir // 8th Production (Unix-like DOS file):
604cdf0e10cSrcweir // \B1 ALPHA ":/" *(wchar / "\") \B1
605cdf0e10cSrcweir //
606cdf0e10cSrcweir // The productions use the following auxiliary rules.
607cdf0e10cSrcweir //
608cdf0e10cSrcweir // local-part = atom *("." atom)
609cdf0e10cSrcweir // atom = 1*(alphanum / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+"
610cdf0e10cSrcweir // / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}"
611cdf0e10cSrcweir // / "~")
612cdf0e10cSrcweir // domain = label *("." label)
613cdf0e10cSrcweir // label = alphanum [*(alphanum / "-") alphanum]
614cdf0e10cSrcweir // alphanum = ALPHA / DIGIT
615cdf0e10cSrcweir // wchar = <any uric character (ignoring the escaped rule), or "%", or
616cdf0e10cSrcweir // a letter or digit (according to rCharClass)>
617cdf0e10cSrcweir //
618cdf0e10cSrcweir // "\B1" (boundary 1) stands for the beginning or end of the block of text,
619cdf0e10cSrcweir // or a character that is neither (a) a letter or digit (according to
620cdf0e10cSrcweir // rCharClass), nor (b) any of "$", "%", "&", "-", "/", "@", or "\".
621cdf0e10cSrcweir // (FIXME: What was the rationale for this set of punctuation characters?)
622cdf0e10cSrcweir //
623cdf0e10cSrcweir // "\B2" (boundary 2) stands for the beginning or end of the block of text,
624cdf0e10cSrcweir // or a character that is neither (a) a letter or digit (according to
625cdf0e10cSrcweir // rCharClass), nor (b) any of "!", "#", "$", "%", "&", "'", "*", "+", "-",
626cdf0e10cSrcweir // "/", "=", "?", "@", "^", "_", "`", "{", "|", "}", or "~" (i.e., an RFC
627cdf0e10cSrcweir // 822 <atom> character, or "@" from \B1's set above).
628cdf0e10cSrcweir //
629cdf0e10cSrcweir // Productions 1--4, and 6--8 try to find a maximum-length match, but they
630cdf0e10cSrcweir // stop at the first <wchar> character that is a "\B1" character which is
631cdf0e10cSrcweir // only followed by "\B1" characters (taking "\" and "|" characters into
632cdf0e10cSrcweir // account appropriately). Production 5 simply tries to find a maximum-
633cdf0e10cSrcweir // length match.
634cdf0e10cSrcweir //
635cdf0e10cSrcweir // Productions 1--4 use the given eMechanism and eCharset. Productions 5--9
636cdf0e10cSrcweir // use ENCODE_ALL.
637cdf0e10cSrcweir //
638cdf0e10cSrcweir // Productions 6--9 are only applicable if the FSYS_DOS bit is set in
639cdf0e10cSrcweir // eStyle.
640cdf0e10cSrcweir
641cdf0e10cSrcweir bool bBoundary1 = true;
642cdf0e10cSrcweir bool bBoundary2 = true;
643cdf0e10cSrcweir for (xub_StrLen nPos = rBegin; nPos != rEnd; nPos = nextChar(rText, nPos))
644cdf0e10cSrcweir {
645cdf0e10cSrcweir sal_Unicode c = rText.GetChar(nPos);
646cdf0e10cSrcweir if (bBoundary1)
647cdf0e10cSrcweir {
648cdf0e10cSrcweir if (INetMIME::isAlpha(c))
649cdf0e10cSrcweir {
650cdf0e10cSrcweir xub_StrLen i = nPos;
651cdf0e10cSrcweir INetProtocol eScheme
652cdf0e10cSrcweir = INetURLObject::CompareProtocolScheme(UniString(rText, i,
653cdf0e10cSrcweir rEnd));
654cdf0e10cSrcweir if (eScheme == INET_PROT_FILE) // 2nd
655cdf0e10cSrcweir {
656cdf0e10cSrcweir while (rText.GetChar(i++) != ':') ;
657cdf0e10cSrcweir xub_StrLen nPrefixEnd = i;
658cdf0e10cSrcweir xub_StrLen nUriEnd = i;
659cdf0e10cSrcweir while (i != rEnd
660cdf0e10cSrcweir && checkWChar(rCharClass, rText, &i, &nUriEnd, true,
661cdf0e10cSrcweir true)) ;
662cdf0e10cSrcweir if (i != nPrefixEnd && rText.GetChar(i) == '#')
663cdf0e10cSrcweir {
664cdf0e10cSrcweir ++i;
665cdf0e10cSrcweir while (i != rEnd
666cdf0e10cSrcweir && checkWChar(rCharClass, rText, &i, &nUriEnd)) ;
667cdf0e10cSrcweir }
668cdf0e10cSrcweir if (nUriEnd != nPrefixEnd
669cdf0e10cSrcweir && isBoundary1(rCharClass, rText, nUriEnd, rEnd))
670cdf0e10cSrcweir {
671cdf0e10cSrcweir INetURLObject aUri(UniString(rText, nPos,
672cdf0e10cSrcweir nUriEnd - nPos),
673cdf0e10cSrcweir INET_PROT_FILE, eMechanism, eCharset,
674cdf0e10cSrcweir eStyle);
675cdf0e10cSrcweir if (!aUri.HasError())
676cdf0e10cSrcweir {
677cdf0e10cSrcweir rBegin = nPos;
678cdf0e10cSrcweir rEnd = nUriEnd;
679cdf0e10cSrcweir return
680cdf0e10cSrcweir aUri.GetMainURL(INetURLObject::DECODE_TO_IURI);
681cdf0e10cSrcweir }
682cdf0e10cSrcweir }
683cdf0e10cSrcweir }
684cdf0e10cSrcweir else if (eScheme != INET_PROT_NOT_VALID) // 1st
685cdf0e10cSrcweir {
686cdf0e10cSrcweir while (rText.GetChar(i++) != ':') ;
687cdf0e10cSrcweir xub_StrLen nPrefixEnd = i;
688cdf0e10cSrcweir xub_StrLen nUriEnd = i;
689cdf0e10cSrcweir while (i != rEnd
690cdf0e10cSrcweir && checkWChar(rCharClass, rText, &i, &nUriEnd)) ;
691cdf0e10cSrcweir if (i != nPrefixEnd && rText.GetChar(i) == '#')
692cdf0e10cSrcweir {
693cdf0e10cSrcweir ++i;
694cdf0e10cSrcweir while (i != rEnd
695cdf0e10cSrcweir && checkWChar(rCharClass, rText, &i, &nUriEnd)) ;
696cdf0e10cSrcweir }
697cdf0e10cSrcweir if (nUriEnd != nPrefixEnd
698cdf0e10cSrcweir && (isBoundary1(rCharClass, rText, nUriEnd, rEnd)
699cdf0e10cSrcweir || rText.GetChar(nUriEnd) == '\\'))
700cdf0e10cSrcweir {
701cdf0e10cSrcweir INetURLObject aUri(UniString(rText, nPos,
702cdf0e10cSrcweir nUriEnd - nPos),
703cdf0e10cSrcweir INET_PROT_HTTP, eMechanism,
704cdf0e10cSrcweir eCharset);
705cdf0e10cSrcweir if (!aUri.HasError())
706cdf0e10cSrcweir {
707cdf0e10cSrcweir rBegin = nPos;
708cdf0e10cSrcweir rEnd = nUriEnd;
709cdf0e10cSrcweir return
710cdf0e10cSrcweir aUri.GetMainURL(INetURLObject::DECODE_TO_IURI);
711cdf0e10cSrcweir }
712cdf0e10cSrcweir }
713cdf0e10cSrcweir }
714cdf0e10cSrcweir
715cdf0e10cSrcweir // 3rd, 4th:
716cdf0e10cSrcweir i = nPos;
717cdf0e10cSrcweir sal_uInt32 nLabels = scanDomain(rText, &i, rEnd);
718cdf0e10cSrcweir if (nLabels >= 3
719cdf0e10cSrcweir && rText.GetChar(nPos + 3) == '.'
720cdf0e10cSrcweir && (((rText.GetChar(nPos) == 'w'
721cdf0e10cSrcweir || rText.GetChar(nPos) == 'W')
722cdf0e10cSrcweir && (rText.GetChar(nPos + 1) == 'w'
723cdf0e10cSrcweir || rText.GetChar(nPos + 1) == 'W')
724cdf0e10cSrcweir && (rText.GetChar(nPos + 2) == 'w'
725cdf0e10cSrcweir || rText.GetChar(nPos + 2) == 'W'))
726cdf0e10cSrcweir || ((rText.GetChar(nPos) == 'f'
727cdf0e10cSrcweir || rText.GetChar(nPos) == 'F')
728cdf0e10cSrcweir && (rText.GetChar(nPos + 1) == 't'
729cdf0e10cSrcweir || rText.GetChar(nPos + 1) == 'T')
730cdf0e10cSrcweir && (rText.GetChar(nPos + 2) == 'p'
731cdf0e10cSrcweir || rText.GetChar(nPos + 2) == 'P'))))
732cdf0e10cSrcweir // (note that rText.GetChar(nPos + 3) is guaranteed to be
733cdf0e10cSrcweir // valid)
734cdf0e10cSrcweir {
735cdf0e10cSrcweir xub_StrLen nUriEnd = i;
736cdf0e10cSrcweir if (i != rEnd && rText.GetChar(i) == '/')
737cdf0e10cSrcweir {
738cdf0e10cSrcweir nUriEnd = ++i;
739cdf0e10cSrcweir while (i != rEnd
740cdf0e10cSrcweir && checkWChar(rCharClass, rText, &i, &nUriEnd)) ;
741cdf0e10cSrcweir }
742cdf0e10cSrcweir if (i != rEnd && rText.GetChar(i) == '#')
743cdf0e10cSrcweir {
744cdf0e10cSrcweir ++i;
745cdf0e10cSrcweir while (i != rEnd
746cdf0e10cSrcweir && checkWChar(rCharClass, rText, &i, &nUriEnd)) ;
747cdf0e10cSrcweir }
748cdf0e10cSrcweir if (isBoundary1(rCharClass, rText, nUriEnd, rEnd)
749cdf0e10cSrcweir || rText.GetChar(nUriEnd) == '\\')
750cdf0e10cSrcweir {
751cdf0e10cSrcweir INetURLObject aUri(UniString(rText, nPos,
752cdf0e10cSrcweir nUriEnd - nPos),
753cdf0e10cSrcweir INET_PROT_HTTP, eMechanism,
754cdf0e10cSrcweir eCharset);
755cdf0e10cSrcweir if (!aUri.HasError())
756cdf0e10cSrcweir {
757cdf0e10cSrcweir rBegin = nPos;
758cdf0e10cSrcweir rEnd = nUriEnd;
759cdf0e10cSrcweir return
760cdf0e10cSrcweir aUri.GetMainURL(INetURLObject::DECODE_TO_IURI);
761cdf0e10cSrcweir }
762cdf0e10cSrcweir }
763cdf0e10cSrcweir }
764cdf0e10cSrcweir
765cdf0e10cSrcweir if ((eStyle & INetURLObject::FSYS_DOS) != 0 && rEnd - nPos >= 3
766cdf0e10cSrcweir && rText.GetChar(nPos + 1) == ':'
767cdf0e10cSrcweir && (rText.GetChar(nPos + 2) == '/'
768cdf0e10cSrcweir || rText.GetChar(nPos + 2) == '\\')) // 7th, 8th
769cdf0e10cSrcweir {
770cdf0e10cSrcweir i = nPos + 3;
771cdf0e10cSrcweir xub_StrLen nUriEnd = i;
772cdf0e10cSrcweir while (i != rEnd
773cdf0e10cSrcweir && checkWChar(rCharClass, rText, &i, &nUriEnd)) ;
774cdf0e10cSrcweir if (isBoundary1(rCharClass, rText, nUriEnd, rEnd))
775cdf0e10cSrcweir {
776cdf0e10cSrcweir INetURLObject aUri(UniString(rText, nPos,
777cdf0e10cSrcweir nUriEnd - nPos),
778cdf0e10cSrcweir INET_PROT_FILE,
779cdf0e10cSrcweir INetURLObject::ENCODE_ALL,
780cdf0e10cSrcweir RTL_TEXTENCODING_UTF8,
781cdf0e10cSrcweir INetURLObject::FSYS_DOS);
782cdf0e10cSrcweir if (!aUri.HasError())
783cdf0e10cSrcweir {
784cdf0e10cSrcweir rBegin = nPos;
785cdf0e10cSrcweir rEnd = nUriEnd;
786cdf0e10cSrcweir return
787cdf0e10cSrcweir aUri.GetMainURL(INetURLObject::DECODE_TO_IURI);
788cdf0e10cSrcweir }
789cdf0e10cSrcweir }
790cdf0e10cSrcweir }
791cdf0e10cSrcweir }
792cdf0e10cSrcweir else if ((eStyle & INetURLObject::FSYS_DOS) != 0 && rEnd - nPos >= 2
793cdf0e10cSrcweir && rText.GetChar(nPos) == '\\'
794cdf0e10cSrcweir && rText.GetChar(nPos + 1) == '\\') // 6th
795cdf0e10cSrcweir {
796cdf0e10cSrcweir xub_StrLen i = nPos + 2;
797cdf0e10cSrcweir sal_uInt32 nLabels = scanDomain(rText, &i, rEnd);
798cdf0e10cSrcweir if (nLabels >= 1 && i != rEnd && rText.GetChar(i) == '\\')
799cdf0e10cSrcweir {
800cdf0e10cSrcweir xub_StrLen nUriEnd = ++i;
801cdf0e10cSrcweir while (i != rEnd
802cdf0e10cSrcweir && checkWChar(rCharClass, rText, &i, &nUriEnd,
803cdf0e10cSrcweir true)) ;
804cdf0e10cSrcweir if (isBoundary1(rCharClass, rText, nUriEnd, rEnd))
805cdf0e10cSrcweir {
806cdf0e10cSrcweir INetURLObject aUri(UniString(rText, nPos,
807cdf0e10cSrcweir nUriEnd - nPos),
808cdf0e10cSrcweir INET_PROT_FILE,
809cdf0e10cSrcweir INetURLObject::ENCODE_ALL,
810cdf0e10cSrcweir RTL_TEXTENCODING_UTF8,
811cdf0e10cSrcweir INetURLObject::FSYS_DOS);
812cdf0e10cSrcweir if (!aUri.HasError())
813cdf0e10cSrcweir {
814cdf0e10cSrcweir rBegin = nPos;
815cdf0e10cSrcweir rEnd = nUriEnd;
816cdf0e10cSrcweir return
817cdf0e10cSrcweir aUri.GetMainURL(INetURLObject::DECODE_TO_IURI);
818cdf0e10cSrcweir }
819cdf0e10cSrcweir }
820cdf0e10cSrcweir }
821cdf0e10cSrcweir }
822cdf0e10cSrcweir }
823cdf0e10cSrcweir if (bBoundary2 && INetMIME::isAtomChar(c)) // 5th
824cdf0e10cSrcweir {
825cdf0e10cSrcweir bool bDot = false;
826cdf0e10cSrcweir for (xub_StrLen i = nPos + 1; i != rEnd; ++i)
827cdf0e10cSrcweir {
828cdf0e10cSrcweir sal_Unicode c2 = rText.GetChar(i);
829cdf0e10cSrcweir if (INetMIME::isAtomChar(c2))
830cdf0e10cSrcweir bDot = false;
831cdf0e10cSrcweir else if (bDot)
832cdf0e10cSrcweir break;
833cdf0e10cSrcweir else if (c2 == '.')
834cdf0e10cSrcweir bDot = true;
835cdf0e10cSrcweir else
836cdf0e10cSrcweir {
837cdf0e10cSrcweir if (c2 == '@')
838cdf0e10cSrcweir {
839cdf0e10cSrcweir ++i;
840cdf0e10cSrcweir sal_uInt32 nLabels = scanDomain(rText, &i, rEnd);
841cdf0e10cSrcweir if (nLabels >= 1
842cdf0e10cSrcweir && isBoundary1(rCharClass, rText, i, rEnd))
843cdf0e10cSrcweir {
844cdf0e10cSrcweir INetURLObject aUri(UniString(rText, nPos, i - nPos),
845cdf0e10cSrcweir INET_PROT_MAILTO,
846cdf0e10cSrcweir INetURLObject::ENCODE_ALL);
847cdf0e10cSrcweir if (!aUri.HasError())
848cdf0e10cSrcweir {
849cdf0e10cSrcweir rBegin = nPos;
850cdf0e10cSrcweir rEnd = i;
851cdf0e10cSrcweir return aUri.GetMainURL(
852cdf0e10cSrcweir INetURLObject::DECODE_TO_IURI);
853cdf0e10cSrcweir }
854cdf0e10cSrcweir }
855cdf0e10cSrcweir }
856cdf0e10cSrcweir break;
857cdf0e10cSrcweir }
858cdf0e10cSrcweir }
859cdf0e10cSrcweir }
860cdf0e10cSrcweir bBoundary1 = isBoundary1(rCharClass, rText, nPos, rEnd);
861cdf0e10cSrcweir bBoundary2 = isBoundary2(rCharClass, rText, nPos, rEnd);
862cdf0e10cSrcweir }
863cdf0e10cSrcweir rBegin = rEnd;
864cdf0e10cSrcweir return UniString();
865cdf0e10cSrcweir }
866cdf0e10cSrcweir
867cdf0e10cSrcweir //============================================================================
868cdf0e10cSrcweir //
869cdf0e10cSrcweir // removePassword
870cdf0e10cSrcweir //
871cdf0e10cSrcweir //============================================================================
872cdf0e10cSrcweir
873cdf0e10cSrcweir UniString
removePassword(UniString const & rURI,INetURLObject::EncodeMechanism eEncodeMechanism,INetURLObject::DecodeMechanism eDecodeMechanism,rtl_TextEncoding eCharset)874cdf0e10cSrcweir URIHelper::removePassword(UniString const & rURI,
875cdf0e10cSrcweir INetURLObject::EncodeMechanism eEncodeMechanism,
876cdf0e10cSrcweir INetURLObject::DecodeMechanism eDecodeMechanism,
877cdf0e10cSrcweir rtl_TextEncoding eCharset)
878cdf0e10cSrcweir {
879cdf0e10cSrcweir INetURLObject aObj(rURI, eEncodeMechanism, eCharset);
880cdf0e10cSrcweir return aObj.HasError() ?
881cdf0e10cSrcweir rURI :
882cdf0e10cSrcweir String(aObj.GetURLNoPass(eDecodeMechanism, eCharset));
883cdf0e10cSrcweir }
884cdf0e10cSrcweir
885cdf0e10cSrcweir //============================================================================
886cdf0e10cSrcweir //
887cdf0e10cSrcweir // queryFSysStyle
888cdf0e10cSrcweir //
889cdf0e10cSrcweir //============================================================================
890cdf0e10cSrcweir
queryFSysStyle(UniString const & rFileUrl,bool bAddConvenienceStyles)891cdf0e10cSrcweir INetURLObject::FSysStyle URIHelper::queryFSysStyle(UniString const & rFileUrl,
892cdf0e10cSrcweir bool bAddConvenienceStyles)
893cdf0e10cSrcweir throw (uno::RuntimeException)
894cdf0e10cSrcweir {
895cdf0e10cSrcweir ::ucbhelper::ContentBroker const * pBroker = ::ucbhelper::ContentBroker::get();
896cdf0e10cSrcweir uno::Reference< ucb::XContentProviderManager > xManager;
897cdf0e10cSrcweir if (pBroker)
898cdf0e10cSrcweir xManager = pBroker->getContentProviderManagerInterface();
899cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xProperties;
900cdf0e10cSrcweir if (xManager.is())
901cdf0e10cSrcweir xProperties
902cdf0e10cSrcweir = uno::Reference< beans::XPropertySet >(
903cdf0e10cSrcweir xManager->queryContentProvider(rFileUrl), uno::UNO_QUERY);
904cdf0e10cSrcweir sal_Int32 nNotation = ucb::FileSystemNotation::UNKNOWN_NOTATION;
905cdf0e10cSrcweir if (xProperties.is())
906cdf0e10cSrcweir try
907cdf0e10cSrcweir {
908cdf0e10cSrcweir xProperties->getPropertyValue(rtl::OUString(
909cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
910cdf0e10cSrcweir "FileSystemNotation")))
911cdf0e10cSrcweir >>= nNotation;
912cdf0e10cSrcweir }
913cdf0e10cSrcweir catch (beans::UnknownPropertyException const &) {}
914cdf0e10cSrcweir catch (lang::WrappedTargetException const &) {}
915cdf0e10cSrcweir
916cdf0e10cSrcweir // The following code depends on the fact that the
917cdf0e10cSrcweir // com::sun::star::ucb::FileSystemNotation constants range from UNKNOWN to
918cdf0e10cSrcweir // MAC, without any holes. The table below has two entries per notation,
919cdf0e10cSrcweir // the first is used if bAddConvenienceStyles == false, while the second
920cdf0e10cSrcweir // is used if bAddConvenienceStyles == true:
921cdf0e10cSrcweir static INetURLObject::FSysStyle const aMap[][2]
922cdf0e10cSrcweir = { { INetURLObject::FSysStyle(0),
923cdf0e10cSrcweir INetURLObject::FSYS_DETECT },
924cdf0e10cSrcweir // UNKNOWN
925cdf0e10cSrcweir { INetURLObject::FSYS_UNX,
926cdf0e10cSrcweir INetURLObject::FSysStyle(INetURLObject::FSYS_VOS
927cdf0e10cSrcweir | INetURLObject::FSYS_UNX) },
928cdf0e10cSrcweir // UNIX
929cdf0e10cSrcweir { INetURLObject::FSYS_DOS,
930cdf0e10cSrcweir INetURLObject::FSysStyle(INetURLObject::FSYS_VOS
931cdf0e10cSrcweir | INetURLObject::FSYS_UNX
932cdf0e10cSrcweir | INetURLObject::FSYS_DOS) },
933cdf0e10cSrcweir // DOS
934cdf0e10cSrcweir { INetURLObject::FSYS_MAC,
935cdf0e10cSrcweir INetURLObject::FSysStyle(INetURLObject::FSYS_VOS
936cdf0e10cSrcweir | INetURLObject::FSYS_UNX
937cdf0e10cSrcweir | INetURLObject::FSYS_MAC) } };
938cdf0e10cSrcweir return aMap[nNotation < ucb::FileSystemNotation::UNKNOWN_NOTATION
939cdf0e10cSrcweir || nNotation > ucb::FileSystemNotation::MAC_NOTATION ?
940cdf0e10cSrcweir 0 :
941cdf0e10cSrcweir nNotation
942cdf0e10cSrcweir - ucb::FileSystemNotation::UNKNOWN_NOTATION]
943cdf0e10cSrcweir [bAddConvenienceStyles];
944cdf0e10cSrcweir }
945