1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: urihelper.cxx,v $
10 * $Revision: 1.22.136.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include <urihelper.hxx>
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
36 #include "com/sun/star/lang/XMultiComponentFactory.hpp"
37 #include "com/sun/star/ucb/Command.hpp"
38 #include <com/sun/star/ucb/FileSystemNotation.hpp>
39 #include "com/sun/star/ucb/IllegalIdentifierException.hpp"
40 #include "com/sun/star/ucb/UnsupportedCommandException.hpp"
41 #include "com/sun/star/ucb/XCommandEnvironment.hpp"
42 #include "com/sun/star/ucb/XCommandProcessor.hpp"
43 #include "com/sun/star/ucb/XContent.hpp"
44 #include "com/sun/star/ucb/XContentIdentifierFactory.hpp"
45 #include "com/sun/star/ucb/XContentProvider.hpp"
46 #include <com/sun/star/ucb/XContentProviderManager.hpp>
47 #include "com/sun/star/uno/Any.hxx"
48 #include "com/sun/star/uno/Exception.hpp"
49 #include "com/sun/star/uno/Reference.hxx"
50 #include "com/sun/star/uno/RuntimeException.hpp"
51 #include "com/sun/star/uno/Sequence.hxx"
52 #include "com/sun/star/uno/XComponentContext.hpp"
53 #include "com/sun/star/uno/XInterface.hpp"
54 #include "com/sun/star/uri/UriReferenceFactory.hpp"
55 #include "com/sun/star/uri/XUriReference.hpp"
56 #include "com/sun/star/uri/XUriReferenceFactory.hpp"
57 #include "cppuhelper/exc_hlp.hxx"
58 #include "comphelper/processfactory.hxx"
59 #include "osl/diagnose.h"
60 #include "rtl/ustrbuf.hxx"
61 #include "rtl/ustring.h"
62 #include "rtl/ustring.hxx"
63 #include "sal/types.h"
64 #include <tools/debug.hxx>
65 #include <tools/inetmime.hxx>
66 #include <ucbhelper/contentbroker.hxx>
67 #include <unotools/charclass.hxx>
68 #include "rtl/instance.hxx"
70 namespace unnamed_svtools_urihelper
{}
71 using namespace unnamed_svtools_urihelper
;
72 // unnamed namespaces don't work well yet...
74 namespace css
= com::sun::star
;
75 using namespace com::sun::star
;
77 //============================================================================
81 //============================================================================
83 namespace unnamed_svtools_urihelper
{
85 inline UniString
toUniString(ByteString
const & rString
)
87 return UniString(rString
, RTL_TEXTENCODING_ISO_8859_1
);
90 inline UniString
toUniString(UniString
const & rString
)
95 template< typename Str
>
96 inline UniString
SmartRel2Abs_Impl(INetURLObject
const & rTheBaseURIRef
,
97 Str
const & rTheRelURIRef
,
98 Link
const & rMaybeFileHdl
,
99 bool bCheckFileExists
,
100 bool bIgnoreFragment
,
101 INetURLObject::EncodeMechanism
103 INetURLObject::DecodeMechanism
105 rtl_TextEncoding eCharset
,
106 bool bRelativeNonURIs
,
107 INetURLObject::FSysStyle eStyle
)
109 // Backwards compatibility:
110 if (rTheRelURIRef
.Len() != 0 && rTheRelURIRef
.GetChar(0) == '#')
111 return toUniString(rTheRelURIRef
);
113 INetURLObject aAbsURIRef
;
114 if (rTheBaseURIRef
.HasError())
116 SetSmartURL(rTheRelURIRef
, eEncodeMechanism
, eCharset
, eStyle
);
120 aAbsURIRef
= rTheBaseURIRef
.smartRel2Abs(rTheRelURIRef
,
129 && (aAbsURIRef
.GetProtocol() == INET_PROT_FILE
130 || aAbsURIRef
.GetProtocol() == INET_PROT_VND_SUN_STAR_WFS
))
132 INetURLObject aNonFileURIRef
;
133 aNonFileURIRef
.SetSmartURL(rTheRelURIRef
,
137 if (!aNonFileURIRef
.HasError()
138 && aNonFileURIRef
.GetProtocol() != INET_PROT_FILE
)
140 bool bMaybeFile
= false;
141 if (rMaybeFileHdl
.IsSet())
143 UniString
aFilePath(toUniString(rTheRelURIRef
));
144 bMaybeFile
= rMaybeFileHdl
.Call(&aFilePath
) != 0;
147 aAbsURIRef
= aNonFileURIRef
;
151 return aAbsURIRef
.GetMainURL(eDecodeMechanism
, eCharset
);
157 URIHelper::SmartRel2Abs(INetURLObject
const & rTheBaseURIRef
,
158 ByteString
const & rTheRelURIRef
,
159 Link
const & rMaybeFileHdl
,
160 bool bCheckFileExists
,
161 bool bIgnoreFragment
,
162 INetURLObject::EncodeMechanism eEncodeMechanism
,
163 INetURLObject::DecodeMechanism eDecodeMechanism
,
164 rtl_TextEncoding eCharset
,
165 bool bRelativeNonURIs
,
166 INetURLObject::FSysStyle eStyle
)
168 return SmartRel2Abs_Impl(rTheBaseURIRef
, rTheRelURIRef
, rMaybeFileHdl
,
169 bCheckFileExists
, bIgnoreFragment
,
170 eEncodeMechanism
, eDecodeMechanism
, eCharset
,
171 bRelativeNonURIs
, eStyle
);
175 URIHelper::SmartRel2Abs(INetURLObject
const & rTheBaseURIRef
,
176 UniString
const & rTheRelURIRef
,
177 Link
const & rMaybeFileHdl
,
178 bool bCheckFileExists
,
179 bool bIgnoreFragment
,
180 INetURLObject::EncodeMechanism eEncodeMechanism
,
181 INetURLObject::DecodeMechanism eDecodeMechanism
,
182 rtl_TextEncoding eCharset
,
183 bool bRelativeNonURIs
,
184 INetURLObject::FSysStyle eStyle
)
186 return SmartRel2Abs_Impl(rTheBaseURIRef
, rTheRelURIRef
, rMaybeFileHdl
,
187 bCheckFileExists
, bIgnoreFragment
,
188 eEncodeMechanism
, eDecodeMechanism
, eCharset
,
189 bRelativeNonURIs
, eStyle
);
192 //============================================================================
196 //============================================================================
198 namespace { struct MaybeFileHdl
: public rtl::Static
< Link
, MaybeFileHdl
> {}; }
200 void URIHelper::SetMaybeFileHdl(Link
const & rTheMaybeFileHdl
)
202 MaybeFileHdl::get() = rTheMaybeFileHdl
;
205 //============================================================================
209 //============================================================================
211 Link
URIHelper::GetMaybeFileHdl()
213 return MaybeFileHdl::get();
218 bool isAbsoluteHierarchicalUriReference(
219 css::uno::Reference
< css::uri::XUriReference
> const & uriReference
)
221 return uriReference
.is() && uriReference
->isAbsolute()
222 && uriReference
->isHierarchical() && !uriReference
->hasRelativePath();
225 // To improve performance, assume that if for any prefix URL of a given
226 // hierarchical URL either a UCB content cannot be created, or the UCB content
227 // does not support the getCasePreservingURL command, then this will hold for
228 // any other prefix URL of the given URL, too:
229 enum Result
{ Success
, GeneralFailure
, SpecificFailure
};
231 Result
normalizePrefix(
232 css::uno::Reference
< css::ucb::XContentProvider
> const & broker
,
233 rtl::OUString
const & uri
, rtl::OUString
* normalized
)
235 OSL_ASSERT(broker
.is() && normalized
!= 0);
236 css::uno::Reference
< css::ucb::XContent
> content
;
238 content
= broker
->queryContent(
239 css::uno::Reference
< css::ucb::XContentIdentifierFactory
>(
240 broker
, css::uno::UNO_QUERY_THROW
)->createContentIdentifier(
242 } catch (css::ucb::IllegalIdentifierException
&) {}
244 return GeneralFailure
;
247 #if OSL_DEBUG_LEVEL > 0
250 (css::uno::Reference
< css::ucb::XCommandProcessor
>(
251 content
, css::uno::UNO_QUERY_THROW
)->execute(
254 RTL_CONSTASCII_USTRINGPARAM(
255 "getCasePreservingURL")),
256 -1, css::uno::Any()),
258 css::uno::Reference
< css::ucb::XCommandEnvironment
>())
261 } catch (css::uno::RuntimeException
&) {
263 } catch (css::ucb::UnsupportedCommandException
&) {
264 return GeneralFailure
;
265 } catch (css::uno::Exception
&) {
266 return SpecificFailure
;
271 rtl::OUString
normalize(
272 css::uno::Reference
< css::ucb::XContentProvider
> const & broker
,
273 css::uno::Reference
< css::uri::XUriReferenceFactory
> const & uriFactory
,
274 rtl::OUString
const & uriReference
)
276 // normalizePrefix can potentially fail (a typically example being a file
277 // URL that denotes a non-existing resource); in such a case, try to
278 // normalize as long a prefix of the given URL as possible (i.e., normalize
279 // all the existing directories within the path):
280 rtl::OUString normalized
;
281 sal_Int32 n
= uriReference
.indexOf('#');
282 normalized
= n
== -1 ? uriReference
: uriReference
.copy(0, n
);
283 switch (normalizePrefix(broker
, normalized
, &normalized
)) {
285 return n
== -1 ? normalized
: normalized
+ uriReference
.copy(n
);
288 case SpecificFailure
:
292 css::uno::Reference
< css::uri::XUriReference
> ref(
293 uriFactory
->parse(uriReference
));
294 if (!isAbsoluteHierarchicalUriReference(ref
)) {
297 sal_Int32 count
= ref
->getPathSegmentCount();
301 rtl::OUStringBuffer
head(ref
->getScheme());
302 head
.append(static_cast< sal_Unicode
>(':'));
303 if (ref
->hasAuthority()) {
304 head
.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
305 head
.append(ref
->getAuthority());
307 for (sal_Int32 i
= count
- 1; i
> 0; --i
) {
308 rtl::OUStringBuffer
buf(head
);
309 for (sal_Int32 j
= 0; j
< i
; ++j
) {
310 buf
.append(static_cast< sal_Unicode
>('/'));
311 buf
.append(ref
->getPathSegment(j
));
313 normalized
= buf
.makeStringAndClear();
314 if (normalizePrefix(broker
, normalized
, &normalized
) != SpecificFailure
)
316 buf
.append(normalized
);
317 css::uno::Reference
< css::uri::XUriReference
> preRef(
318 uriFactory
->parse(normalized
));
319 if (!isAbsoluteHierarchicalUriReference(preRef
)) {
320 // This could only happen if something is inconsistent:
323 sal_Int32 preCount
= preRef
->getPathSegmentCount();
324 // normalizePrefix may have added or removed a final slash:
326 if (preCount
== i
- 1) {
327 buf
.append(static_cast< sal_Unicode
>('/'));
328 } else if (preCount
- 1 == i
&& buf
.getLength() > 0
329 && buf
.charAt(buf
.getLength() - 1) == '/')
331 buf
.setLength(buf
.getLength() - 1);
333 // This could only happen if something is inconsistent:
337 for (sal_Int32 j
= i
; j
< count
; ++j
) {
338 buf
.append(static_cast< sal_Unicode
>('/'));
339 buf
.append(ref
->getPathSegment(j
));
341 if (ref
->hasQuery()) {
342 buf
.append(static_cast< sal_Unicode
>('?'));
343 buf
.append(ref
->getQuery());
345 if (ref
->hasFragment()) {
346 buf
.append(static_cast< sal_Unicode
>('#'));
347 buf
.append(ref
->getFragment());
349 return buf
.makeStringAndClear();
357 css::uno::Reference
< css::uri::XUriReference
>
358 URIHelper::normalizedMakeRelative(
359 css::uno::Reference
< css::uno::XComponentContext
> const & context
,
360 rtl::OUString
const & baseUriReference
, rtl::OUString
const & uriReference
)
362 OSL_ASSERT(context
.is());
363 css::uno::Reference
< css::lang::XMultiComponentFactory
> componentFactory(
364 context
->getServiceManager());
365 if (!componentFactory
.is()) {
366 throw css::uno::RuntimeException(
368 RTL_CONSTASCII_USTRINGPARAM(
369 "component context has no service manager")),
370 css::uno::Reference
< css::uno::XInterface
>());
372 css::uno::Sequence
< css::uno::Any
> args(2);
373 args
[0] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Local"));
374 args
[1] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office"));
375 css::uno::Reference
< css::ucb::XContentProvider
> broker
;
377 broker
= css::uno::Reference
< css::ucb::XContentProvider
>(
378 componentFactory
->createInstanceWithArgumentsAndContext(
380 RTL_CONSTASCII_USTRINGPARAM(
381 "com.sun.star.ucb.UniversalContentBroker")),
383 css::uno::UNO_QUERY_THROW
);
384 } catch (css::uno::RuntimeException
&) {
386 } catch (css::uno::Exception
&) {
387 css::uno::Any
exception(cppu::getCaughtException());
388 throw css::lang::WrappedTargetRuntimeException(
390 RTL_CONSTASCII_USTRINGPARAM(
391 "creating com.sun.star.ucb.UniversalContentBroker failed")),
392 css::uno::Reference
< css::uno::XInterface
>(),
395 css::uno::Reference
< css::uri::XUriReferenceFactory
> uriFactory(
396 css::uri::UriReferenceFactory::create(context
));
397 return uriFactory
->makeRelative(
398 uriFactory
->parse(normalize(broker
, uriFactory
, baseUriReference
)),
399 uriFactory
->parse(normalize(broker
, uriFactory
, uriReference
)), true,
403 rtl::OUString
URIHelper::simpleNormalizedMakeRelative(
404 rtl::OUString
const & baseUriReference
, rtl::OUString
const & uriReference
)
406 com::sun::star::uno::Reference
< com::sun::star::uri::XUriReference
> rel(
407 URIHelper::normalizedMakeRelative(
408 com::sun::star::uno::Reference
<
409 com::sun::star::uno::XComponentContext
>(
410 (com::sun::star::uno::Reference
<
411 com::sun::star::beans::XPropertySet
>(
412 comphelper::getProcessServiceFactory(),
413 com::sun::star::uno::UNO_QUERY_THROW
)->
416 RTL_CONSTASCII_USTRINGPARAM("DefaultContext")))),
417 com::sun::star::uno::UNO_QUERY_THROW
),
418 baseUriReference
, uriReference
));
419 return rel
.is() ? rel
->getUriReference() : uriReference
;
422 //============================================================================
424 // FindFirstURLInText
426 //============================================================================
428 namespace unnamed_svtools_urihelper
{
430 inline xub_StrLen
nextChar(UniString
const & rStr
, xub_StrLen nPos
)
432 return INetMIME::isHighSurrogate(rStr
.GetChar(nPos
))
433 && rStr
.Len() - nPos
>= 2
434 && INetMIME::isLowSurrogate(rStr
.GetChar(nPos
+ 1)) ?
438 bool isBoundary1(CharClass
const & rCharClass
, UniString
const & rStr
,
439 xub_StrLen nPos
, xub_StrLen nEnd
)
443 if (rCharClass
.isLetterNumeric(rStr
, nPos
))
445 switch (rStr
.GetChar(nPos
))
460 bool isBoundary2(CharClass
const & rCharClass
, UniString
const & rStr
,
461 xub_StrLen nPos
, xub_StrLen nEnd
)
465 if (rCharClass
.isLetterNumeric(rStr
, nPos
))
467 switch (rStr
.GetChar(nPos
))
495 bool checkWChar(CharClass
const & rCharClass
, UniString
const & rStr
,
496 xub_StrLen
* pPos
, xub_StrLen
* pEnd
, bool bBackslash
= false,
499 sal_Unicode c
= rStr
.GetChar(*pPos
);
500 if (INetMIME::isUSASCII(c
))
502 static sal_uInt8
const aMap
[128]
503 = { 0, 0, 0, 0, 0, 0, 0, 0,
504 0, 0, 0, 0, 0, 0, 0, 0,
505 0, 0, 0, 0, 0, 0, 0, 0,
506 0, 0, 0, 0, 0, 0, 0, 0,
507 0, 1, 0, 0, 4, 4, 4, 1, // !"#$%&'
508 1, 1, 1, 1, 1, 4, 1, 4, // ()*+,-./
509 4, 4, 4, 4, 4, 4, 4, 4, // 01234567
510 4, 4, 1, 1, 0, 1, 0, 1, // 89:;<=>?
511 4, 4, 4, 4, 4, 4, 4, 4, // @ABCDEFG
512 4, 4, 4, 4, 4, 4, 4, 4, // HIJKLMNO
513 4, 4, 4, 4, 4, 4, 4, 4, // PQRSTUVW
514 4, 4, 4, 1, 2, 1, 0, 1, // XYZ[\]^_
515 0, 4, 4, 4, 4, 4, 4, 4, // `abcdefg
516 4, 4, 4, 4, 4, 4, 4, 4, // hijklmno
517 4, 4, 4, 4, 4, 4, 4, 4, // pqrstuvw
518 4, 4, 4, 0, 3, 0, 1, 0 }; // xyz{|}~
546 case 4: // alpha, digit, "$", "%", "&", "-", "/", "@" (see
552 else if (rCharClass
.isLetterNumeric(rStr
, *pPos
))
554 *pEnd
= *pPos
= nextChar(rStr
, *pPos
);
561 sal_uInt32
scanDomain(UniString
const & rStr
, xub_StrLen
* pPos
,
564 sal_Unicode
const * pBuffer
= rStr
.GetBuffer();
565 sal_Unicode
const * p
= pBuffer
+ *pPos
;
566 sal_uInt32 nLabels
= INetURLObject::scanDomain(p
, pBuffer
+ nEnd
, false);
567 *pPos
= sal::static_int_cast
< xub_StrLen
>(p
- pBuffer
);
574 URIHelper::FindFirstURLInText(UniString
const & rText
,
577 CharClass
const & rCharClass
,
578 INetURLObject::EncodeMechanism eMechanism
,
579 rtl_TextEncoding eCharset
,
580 INetURLObject::FSysStyle eStyle
)
582 if (!(rBegin
<= rEnd
&& rEnd
<= rText
.Len()))
585 // Search for the first substring of [rBegin..rEnd[ that matches any of the
586 // following productions (for which the appropriate style bit is set in
587 // eStyle, if applicable).
589 // 1st Production (known scheme):
590 // \B1 <one of the known schemes, except file> ":" 1*wchar ["#" 1*wchar]
593 // 2nd Production (file):
594 // \B1 "FILE:" 1*(wchar / "\" / "|") ["#" 1*wchar] \B1
596 // 3rd Production (ftp):
597 // \B1 "FTP" 2*("." label) ["/" *wchar] ["#" 1*wchar] \B1
599 // 4th Production (http):
600 // \B1 "WWW" 2*("." label) ["/" *wchar] ["#" 1*wchar] \B1
602 // 5th Production (mailto):
603 // \B2 local-part "@" domain \B1
605 // 6th Production (UNC file):
606 // \B1 "\\" domain "\" *(wchar / "\") \B1
608 // 7th Production (DOS file):
609 // \B1 ALPHA ":\" *(wchar / "\") \B1
611 // 8th Production (Unix-like DOS file):
612 // \B1 ALPHA ":/" *(wchar / "\") \B1
614 // The productions use the following auxiliary rules.
616 // local-part = atom *("." atom)
617 // atom = 1*(alphanum / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+"
618 // / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}"
620 // domain = label *("." label)
621 // label = alphanum [*(alphanum / "-") alphanum]
622 // alphanum = ALPHA / DIGIT
623 // wchar = <any uric character (ignoring the escaped rule), or "%", or
624 // a letter or digit (according to rCharClass)>
626 // "\B1" (boundary 1) stands for the beginning or end of the block of text,
627 // or a character that is neither (a) a letter or digit (according to
628 // rCharClass), nor (b) any of "$", "%", "&", "-", "/", "@", or "\".
629 // (FIXME: What was the rationale for this set of punctuation characters?)
631 // "\B2" (boundary 2) stands for the beginning or end of the block of text,
632 // or a character that is neither (a) a letter or digit (according to
633 // rCharClass), nor (b) any of "!", "#", "$", "%", "&", "'", "*", "+", "-",
634 // "/", "=", "?", "@", "^", "_", "`", "{", "|", "}", or "~" (i.e., an RFC
635 // 822 <atom> character, or "@" from \B1's set above).
637 // Productions 1--4, and 6--8 try to find a maximum-length match, but they
638 // stop at the first <wchar> character that is a "\B1" character which is
639 // only followed by "\B1" characters (taking "\" and "|" characters into
640 // account appropriately). Production 5 simply tries to find a maximum-
643 // Productions 1--4 use the given eMechanism and eCharset. Productions 5--9
646 // Productions 6--9 are only applicable if the FSYS_DOS bit is set in
649 bool bBoundary1
= true;
650 bool bBoundary2
= true;
651 for (xub_StrLen nPos
= rBegin
; nPos
!= rEnd
; nPos
= nextChar(rText
, nPos
))
653 sal_Unicode c
= rText
.GetChar(nPos
);
656 if (INetMIME::isAlpha(c
))
660 = INetURLObject::CompareProtocolScheme(UniString(rText
, i
,
662 if (eScheme
== INET_PROT_FILE
) // 2nd
664 while (rText
.GetChar(i
++) != ':') ;
665 xub_StrLen nPrefixEnd
= i
;
666 xub_StrLen nUriEnd
= i
;
668 && checkWChar(rCharClass
, rText
, &i
, &nUriEnd
, true,
670 if (i
!= nPrefixEnd
&& rText
.GetChar(i
) == '#')
674 && checkWChar(rCharClass
, rText
, &i
, &nUriEnd
)) ;
676 if (nUriEnd
!= nPrefixEnd
677 && isBoundary1(rCharClass
, rText
, nUriEnd
, rEnd
))
679 INetURLObject
aUri(UniString(rText
, nPos
,
681 INET_PROT_FILE
, eMechanism
, eCharset
,
683 if (!aUri
.HasError())
688 aUri
.GetMainURL(INetURLObject::DECODE_TO_IURI
);
692 else if (eScheme
!= INET_PROT_NOT_VALID
) // 1st
694 while (rText
.GetChar(i
++) != ':') ;
695 xub_StrLen nPrefixEnd
= i
;
696 xub_StrLen nUriEnd
= i
;
698 && checkWChar(rCharClass
, rText
, &i
, &nUriEnd
)) ;
699 if (i
!= nPrefixEnd
&& rText
.GetChar(i
) == '#')
703 && checkWChar(rCharClass
, rText
, &i
, &nUriEnd
)) ;
705 if (nUriEnd
!= nPrefixEnd
706 && (isBoundary1(rCharClass
, rText
, nUriEnd
, rEnd
)
707 || rText
.GetChar(nUriEnd
) == '\\'))
709 INetURLObject
aUri(UniString(rText
, nPos
,
711 INET_PROT_HTTP
, eMechanism
,
713 if (!aUri
.HasError())
718 aUri
.GetMainURL(INetURLObject::DECODE_TO_IURI
);
725 sal_uInt32 nLabels
= scanDomain(rText
, &i
, rEnd
);
727 && rText
.GetChar(nPos
+ 3) == '.'
728 && (((rText
.GetChar(nPos
) == 'w'
729 || rText
.GetChar(nPos
) == 'W')
730 && (rText
.GetChar(nPos
+ 1) == 'w'
731 || rText
.GetChar(nPos
+ 1) == 'W')
732 && (rText
.GetChar(nPos
+ 2) == 'w'
733 || rText
.GetChar(nPos
+ 2) == 'W'))
734 || ((rText
.GetChar(nPos
) == 'f'
735 || rText
.GetChar(nPos
) == 'F')
736 && (rText
.GetChar(nPos
+ 1) == 't'
737 || rText
.GetChar(nPos
+ 1) == 'T')
738 && (rText
.GetChar(nPos
+ 2) == 'p'
739 || rText
.GetChar(nPos
+ 2) == 'P'))))
740 // (note that rText.GetChar(nPos + 3) is guaranteed to be
743 xub_StrLen nUriEnd
= i
;
744 if (i
!= rEnd
&& rText
.GetChar(i
) == '/')
748 && checkWChar(rCharClass
, rText
, &i
, &nUriEnd
)) ;
750 if (i
!= rEnd
&& rText
.GetChar(i
) == '#')
754 && checkWChar(rCharClass
, rText
, &i
, &nUriEnd
)) ;
756 if (isBoundary1(rCharClass
, rText
, nUriEnd
, rEnd
)
757 || rText
.GetChar(nUriEnd
) == '\\')
759 INetURLObject
aUri(UniString(rText
, nPos
,
761 INET_PROT_HTTP
, eMechanism
,
763 if (!aUri
.HasError())
768 aUri
.GetMainURL(INetURLObject::DECODE_TO_IURI
);
773 if ((eStyle
& INetURLObject::FSYS_DOS
) != 0 && rEnd
- nPos
>= 3
774 && rText
.GetChar(nPos
+ 1) == ':'
775 && (rText
.GetChar(nPos
+ 2) == '/'
776 || rText
.GetChar(nPos
+ 2) == '\\')) // 7th, 8th
779 xub_StrLen nUriEnd
= i
;
781 && checkWChar(rCharClass
, rText
, &i
, &nUriEnd
)) ;
782 if (isBoundary1(rCharClass
, rText
, nUriEnd
, rEnd
))
784 INetURLObject
aUri(UniString(rText
, nPos
,
787 INetURLObject::ENCODE_ALL
,
788 RTL_TEXTENCODING_UTF8
,
789 INetURLObject::FSYS_DOS
);
790 if (!aUri
.HasError())
795 aUri
.GetMainURL(INetURLObject::DECODE_TO_IURI
);
800 else if ((eStyle
& INetURLObject::FSYS_DOS
) != 0 && rEnd
- nPos
>= 2
801 && rText
.GetChar(nPos
) == '\\'
802 && rText
.GetChar(nPos
+ 1) == '\\') // 6th
804 xub_StrLen i
= nPos
+ 2;
805 sal_uInt32 nLabels
= scanDomain(rText
, &i
, rEnd
);
806 if (nLabels
>= 1 && i
!= rEnd
&& rText
.GetChar(i
) == '\\')
808 xub_StrLen nUriEnd
= ++i
;
810 && checkWChar(rCharClass
, rText
, &i
, &nUriEnd
,
812 if (isBoundary1(rCharClass
, rText
, nUriEnd
, rEnd
))
814 INetURLObject
aUri(UniString(rText
, nPos
,
817 INetURLObject::ENCODE_ALL
,
818 RTL_TEXTENCODING_UTF8
,
819 INetURLObject::FSYS_DOS
);
820 if (!aUri
.HasError())
825 aUri
.GetMainURL(INetURLObject::DECODE_TO_IURI
);
831 if (bBoundary2
&& INetMIME::isAtomChar(c
)) // 5th
834 for (xub_StrLen i
= nPos
+ 1; i
!= rEnd
; ++i
)
836 sal_Unicode c2
= rText
.GetChar(i
);
837 if (INetMIME::isAtomChar(c2
))
848 sal_uInt32 nLabels
= scanDomain(rText
, &i
, rEnd
);
850 && isBoundary1(rCharClass
, rText
, i
, rEnd
))
852 INetURLObject
aUri(UniString(rText
, nPos
, i
- nPos
),
854 INetURLObject::ENCODE_ALL
);
855 if (!aUri
.HasError())
859 return aUri
.GetMainURL(
860 INetURLObject::DECODE_TO_IURI
);
868 bBoundary1
= isBoundary1(rCharClass
, rText
, nPos
, rEnd
);
869 bBoundary2
= isBoundary2(rCharClass
, rText
, nPos
, rEnd
);
875 //============================================================================
879 //============================================================================
882 URIHelper::removePassword(UniString
const & rURI
,
883 INetURLObject::EncodeMechanism eEncodeMechanism
,
884 INetURLObject::DecodeMechanism eDecodeMechanism
,
885 rtl_TextEncoding eCharset
)
887 INetURLObject
aObj(rURI
, eEncodeMechanism
, eCharset
);
888 return aObj
.HasError() ?
890 String(aObj
.GetURLNoPass(eDecodeMechanism
, eCharset
));
893 //============================================================================
897 //============================================================================
899 INetURLObject::FSysStyle
URIHelper::queryFSysStyle(UniString
const & rFileUrl
,
900 bool bAddConvenienceStyles
)
901 throw (uno::RuntimeException
)
903 ::ucbhelper::ContentBroker
const * pBroker
= ::ucbhelper::ContentBroker::get();
904 uno::Reference
< ucb::XContentProviderManager
> xManager
;
906 xManager
= pBroker
->getContentProviderManagerInterface();
907 uno::Reference
< beans::XPropertySet
> xProperties
;
910 = uno::Reference
< beans::XPropertySet
>(
911 xManager
->queryContentProvider(rFileUrl
), uno::UNO_QUERY
);
912 sal_Int32 nNotation
= ucb::FileSystemNotation::UNKNOWN_NOTATION
;
913 if (xProperties
.is())
916 xProperties
->getPropertyValue(rtl::OUString(
917 RTL_CONSTASCII_USTRINGPARAM(
918 "FileSystemNotation")))
921 catch (beans::UnknownPropertyException
const &) {}
922 catch (lang::WrappedTargetException
const &) {}
924 // The following code depends on the fact that the
925 // com::sun::star::ucb::FileSystemNotation constants range from UNKNOWN to
926 // MAC, without any holes. The table below has two entries per notation,
927 // the first is used if bAddConvenienceStyles == false, while the second
928 // is used if bAddConvenienceStyles == true:
929 static INetURLObject::FSysStyle
const aMap
[][2]
930 = { { INetURLObject::FSysStyle(0),
931 INetURLObject::FSYS_DETECT
},
933 { INetURLObject::FSYS_UNX
,
934 INetURLObject::FSysStyle(INetURLObject::FSYS_VOS
935 | INetURLObject::FSYS_UNX
) },
937 { INetURLObject::FSYS_DOS
,
938 INetURLObject::FSysStyle(INetURLObject::FSYS_VOS
939 | INetURLObject::FSYS_UNX
940 | INetURLObject::FSYS_DOS
) },
942 { INetURLObject::FSYS_MAC
,
943 INetURLObject::FSysStyle(INetURLObject::FSYS_VOS
944 | INetURLObject::FSYS_UNX
945 | INetURLObject::FSYS_MAC
) } };
946 return aMap
[nNotation
< ucb::FileSystemNotation::UNKNOWN_NOTATION
947 || nNotation
> ucb::FileSystemNotation::MAC_NOTATION
?
950 - ucb::FileSystemNotation::UNKNOWN_NOTATION
]
951 [bAddConvenienceStyles
];