diff options
Diffstat (limited to 'stoc/source/uriproc/UriReferenceFactory.cxx')
-rw-r--r-- | stoc/source/uriproc/UriReferenceFactory.cxx | 724 |
1 files changed, 724 insertions, 0 deletions
diff --git a/stoc/source/uriproc/UriReferenceFactory.cxx b/stoc/source/uriproc/UriReferenceFactory.cxx new file mode 100644 index 000000000000..89367ade36cf --- /dev/null +++ b/stoc/source/uriproc/UriReferenceFactory.cxx @@ -0,0 +1,724 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_stoc.hxx" + +#include "stocservices.hxx" + +#include "UriReference.hxx" +#include "supportsService.hxx" + +#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp" +#include "com/sun/star/lang/XMultiComponentFactory.hpp" +#include "com/sun/star/lang/XServiceInfo.hpp" +#include "com/sun/star/uno/Any.hxx" +#include "com/sun/star/uno/Exception.hpp" +#include "com/sun/star/uno/Reference.hxx" +#include "com/sun/star/uno/RuntimeException.hpp" +#include "com/sun/star/uno/Sequence.hxx" +#include "com/sun/star/uno/XComponentContext.hpp" +#include "com/sun/star/uno/XInterface.hpp" +#include "com/sun/star/uri/RelativeUriExcessParentSegments.hpp" +#include "com/sun/star/uri/XUriReference.hpp" +#include "com/sun/star/uri/XUriReferenceFactory.hpp" +#include "com/sun/star/uri/XUriSchemeParser.hpp" +#include "cppuhelper/implbase1.hxx" +#include "cppuhelper/implbase2.hxx" +#include "cppuhelper/weak.hxx" +#include "osl/diagnose.h" +#include "rtl/string.h" +#include "rtl/ustrbuf.hxx" +#include "rtl/ustring.hxx" +#include "sal/types.h" + +#include <algorithm> +#include /*MSVC trouble: <cstdlib>*/ <stdlib.h> +#include <new> +#include <vector> + +namespace css = com::sun::star; + +namespace { + +bool isDigit(sal_Unicode c) { //TODO: generally available? + return c >= '0' && c <= '9'; +} + +bool isUpperCase(sal_Unicode c) { //TODO: generally available? + return c >= 'A' && c <= 'Z'; +} + +bool isLowerCase(sal_Unicode c) { //TODO: generally available? + return c >= 'a' && c <= 'z'; +} + +bool isAlpha(sal_Unicode c) { //TODO: generally available? + return isUpperCase(c) || isLowerCase(c); +} + +bool isHexDigit(sal_Unicode c) { //TODO: generally available? + return isDigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); +} + +sal_Unicode toLowerCase(sal_Unicode c) { //TODO: generally available? + return isUpperCase(c) ? c + ('a' - 'A') : c; +} + +bool equalIgnoreCase(sal_Unicode c1, sal_Unicode c2) { + //TODO: generally available? + return toLowerCase(c1) == toLowerCase(c2); +} + +bool equalIgnoreEscapeCase(rtl::OUString const & s1, rtl::OUString const & s2) { + if (s1.getLength() == s2.getLength()) { + for (sal_Int32 i = 0; i < s1.getLength();) { + if (s1[i] == '%' && s2[i] == '%' && s1.getLength() - i > 2 + && isHexDigit(s1[i + 1]) && isHexDigit(s1[i + 2]) + && isHexDigit(s2[i + 1]) && isHexDigit(s2[i + 2]) + && equalIgnoreCase(s1[i + 1], s2[i + 1]) + && equalIgnoreCase(s1[i + 2], s2[i + 2])) + { + i += 3; + } else if (s1[i] != s2[i]) { + return false; + } else { + ++i; + } + } + return true; + } else { + return false; + } +} + +sal_Int32 parseScheme(rtl::OUString const & uriReference) { + if (uriReference.getLength() >= 2 && isAlpha(uriReference[0])) { + for (sal_Int32 i = 0; i < uriReference.getLength(); ++i) { + sal_Unicode c = uriReference[i]; + if (c == ':') { + return i; + } else if (!isAlpha(c) && !isDigit(c) && c != '+' && c != '-' + && c != '.') + { + break; + } + } + } + return -1; +} + +class UriReference: public cppu::WeakImplHelper1< css::uri::XUriReference > { +public: + UriReference( + rtl::OUString const & scheme, bool bIsHierarchical, bool bHasAuthority, + rtl::OUString const & authority, rtl::OUString const & path, + bool bHasQuery, rtl::OUString const & query): + m_base( + scheme, bIsHierarchical, bHasAuthority, authority, path, bHasQuery, + query) + {} + + virtual rtl::OUString SAL_CALL getUriReference() + throw (com::sun::star::uno::RuntimeException) + { return m_base.getUriReference(); } + + virtual sal_Bool SAL_CALL isAbsolute() + throw (com::sun::star::uno::RuntimeException) + { return m_base.isAbsolute(); } + + virtual rtl::OUString SAL_CALL getScheme() + throw (com::sun::star::uno::RuntimeException) + { return m_base.getScheme(); } + + virtual rtl::OUString SAL_CALL getSchemeSpecificPart() + throw (com::sun::star::uno::RuntimeException) + { return m_base.getSchemeSpecificPart(); } + + virtual sal_Bool SAL_CALL isHierarchical() + throw (com::sun::star::uno::RuntimeException) + { return m_base.isHierarchical(); } + + virtual sal_Bool SAL_CALL hasAuthority() + throw (com::sun::star::uno::RuntimeException) + { return m_base.hasAuthority(); } + + virtual rtl::OUString SAL_CALL getAuthority() + throw (com::sun::star::uno::RuntimeException) + { return m_base.getAuthority(); } + + virtual rtl::OUString SAL_CALL getPath() + throw (com::sun::star::uno::RuntimeException) + { return m_base.getPath(); } + + virtual sal_Bool SAL_CALL hasRelativePath() + throw (com::sun::star::uno::RuntimeException) + { return m_base.hasRelativePath(); } + + virtual sal_Int32 SAL_CALL getPathSegmentCount() + throw (com::sun::star::uno::RuntimeException) + { return m_base.getPathSegmentCount(); } + + virtual rtl::OUString SAL_CALL getPathSegment(sal_Int32 index) + throw (com::sun::star::uno::RuntimeException) + { return m_base.getPathSegment(index); } + + virtual sal_Bool SAL_CALL hasQuery() + throw (com::sun::star::uno::RuntimeException) + { return m_base.hasQuery(); } + + virtual rtl::OUString SAL_CALL getQuery() + throw (com::sun::star::uno::RuntimeException) + { return m_base.getQuery(); } + + virtual sal_Bool SAL_CALL hasFragment() + throw (com::sun::star::uno::RuntimeException) + { return m_base.hasFragment(); } + + virtual rtl::OUString SAL_CALL getFragment() + throw (com::sun::star::uno::RuntimeException) + { return m_base.getFragment(); } + + virtual void SAL_CALL setFragment(rtl::OUString const & fragment) + throw (com::sun::star::uno::RuntimeException) + { m_base.setFragment(fragment); } + + virtual void SAL_CALL clearFragment() + throw (com::sun::star::uno::RuntimeException) + { m_base.clearFragment(); } + +private: + UriReference(UriReference &); // not implemented + void operator =(UriReference); // not implemented + + virtual ~UriReference() {} + + stoc::uriproc::UriReference m_base; +}; + +// throws std::bad_alloc +css::uno::Reference< css::uri::XUriReference > parseGeneric( + rtl::OUString const & scheme, rtl::OUString const & schemeSpecificPart) +{ + bool isAbsolute = scheme.getLength() != 0; + bool isHierarchical + = !isAbsolute + || (schemeSpecificPart.getLength() > 0 && schemeSpecificPart[0] == '/'); + bool hasAuthority = false; + rtl::OUString authority; + rtl::OUString path; + bool hasQuery = false; + rtl::OUString query; + if (isHierarchical) { + sal_Int32 len = schemeSpecificPart.getLength(); + sal_Int32 i = 0; + if (len - i >= 2 && schemeSpecificPart[i] == '/' + && schemeSpecificPart[i + 1] == '/') + { + i += 2; + sal_Int32 n = i; + while (i < len && schemeSpecificPart[i] != '/' + && schemeSpecificPart[i] != '?') { + ++i; + } + hasAuthority = true; + authority = schemeSpecificPart.copy(n, i - n); + } + sal_Int32 n = i; + i = schemeSpecificPart.indexOf('?', i); + if (i == -1) { + i = len; + } + path = schemeSpecificPart.copy(n, i - n); + if (i != len) { + hasQuery = true; + query = schemeSpecificPart.copy(i + 1); + } + } else { + if (schemeSpecificPart.getLength() == 0) { + // The scheme-specific part of an opaque URI must not be empty: + return 0; + } + path = schemeSpecificPart; + } + return new UriReference( + scheme, isHierarchical, hasAuthority, authority, path, hasQuery, query); +} + +typedef std::vector< sal_Int32 > Segments; + +void processSegments( + Segments & segments, + css::uno::Reference< css::uri::XUriReference > const & uriReference, + bool base, bool processSpecialSegments) +{ + sal_Int32 count = uriReference->getPathSegmentCount() - (base ? 1 : 0); + OSL_ASSERT(count <= SAL_MAX_INT32 - 1 && -count >= SAL_MIN_INT32 + 1); + for (sal_Int32 i = 0; i < count; ++i) { + if (processSpecialSegments) { + rtl::OUString segment(uriReference->getPathSegment(i)); + if (segment.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("."))) { + if (!base && i == count - 1) { + segments.push_back(0); + } + continue; + } else if (segment.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(".."))) { + if (segments.empty() + || /*MSVC trouble: std::*/abs(segments.back()) == 1) + { + segments.push_back(base ? -1 : 1); + } else { + segments.pop_back(); + } + continue; + } + } + segments.push_back(base ? -(i + 2) : i + 2); + } +} + +class Factory: public cppu::WeakImplHelper2< + css::lang::XServiceInfo, css::uri::XUriReferenceFactory > +{ +public: + explicit Factory( + css::uno::Reference< css::uno::XComponentContext > const & context): + m_context(context) {} + + virtual rtl::OUString SAL_CALL getImplementationName() + throw (css::uno::RuntimeException); + + virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName) + throw (css::uno::RuntimeException); + + virtual css::uno::Sequence< rtl::OUString > SAL_CALL + getSupportedServiceNames() throw (css::uno::RuntimeException); + + virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL + parse(rtl::OUString const & uriReference) + throw (css::uno::RuntimeException); + + virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL + makeAbsolute( + css::uno::Reference< css::uri::XUriReference > const & baseUriReference, + css::uno::Reference< css::uri::XUriReference > const & uriReference, + sal_Bool processSpecialBaseSegments, + css::uri::RelativeUriExcessParentSegments excessParentSegments) + throw (css::uno::RuntimeException); + + virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL + 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) + throw (css::uno::RuntimeException); + +private: + Factory(Factory &); // not implemented + void operator =(Factory); // not implemented + + virtual ~Factory() {} + + css::uno::Reference< css::uri::XUriReference > clone( + css::uno::Reference< css::uri::XUriReference > const & uriReference) + { return parse(uriReference->getUriReference()); } + + css::uno::Reference< css::uno::XComponentContext > m_context; +}; + +rtl::OUString Factory::getImplementationName() + throw (css::uno::RuntimeException) +{ + return stoc_services::UriReferenceFactory::getImplementationName(); +} + +sal_Bool Factory::supportsService(rtl::OUString const & serviceName) + throw (css::uno::RuntimeException) +{ + return stoc::uriproc::supportsService( + getSupportedServiceNames(), serviceName); +} + +css::uno::Sequence< rtl::OUString > Factory::getSupportedServiceNames() + throw (css::uno::RuntimeException) +{ + return stoc_services::UriReferenceFactory::getSupportedServiceNames(); +} + +css::uno::Reference< css::uri::XUriReference > Factory::parse( + rtl::OUString const & uriReference) throw (css::uno::RuntimeException) +{ + sal_Int32 fragment = uriReference.indexOf('#'); + if (fragment == -1) { + fragment = uriReference.getLength(); + } + rtl::OUString scheme; + rtl::OUString schemeSpecificPart; + rtl::OUString serviceName; + sal_Int32 n = parseScheme(uriReference); + OSL_ASSERT(n < fragment); + if (n >= 0) { + scheme = uriReference.copy(0, n); + schemeSpecificPart = uriReference.copy(n + 1, fragment - (n + 1)); + rtl::OUStringBuffer buf; + buf.appendAscii( + RTL_CONSTASCII_STRINGPARAM("com.sun.star.uri.UriSchemeParser_")); + for (sal_Int32 i = 0; i < scheme.getLength(); ++i) { + sal_Unicode c = scheme[i]; + if (isUpperCase(c)) { + buf.append(toLowerCase(c)); + } else if (c == '+') { + buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("PLUS")); + } else if (c == '-') { + buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("HYPHEN")); + } else if (c == '.') { + buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("DOT")); + } else { + OSL_ASSERT(isLowerCase(c) || isDigit(c)); + buf.append(c); + } + } + serviceName = buf.makeStringAndClear(); + } else { + schemeSpecificPart = uriReference.copy(0, fragment); + } + css::uno::Reference< css::uri::XUriSchemeParser > parser; + if (serviceName.getLength() != 0) { + css::uno::Reference< css::lang::XMultiComponentFactory > factory( + m_context->getServiceManager()); + if (factory.is()) { + css::uno::Reference< css::uno::XInterface > service; + try { + service = factory->createInstanceWithContext( + serviceName, m_context); + } catch (css::uno::RuntimeException &) { + throw; + } catch (css::uno::Exception & e) { + throw css::lang::WrappedTargetRuntimeException( + rtl::OUString::createFromAscii("creating service ") + + serviceName, + static_cast< cppu::OWeakObject * >(this), + css::uno::makeAny(e)); //TODO: preserve type of e + } + if (service.is()) { + parser = css::uno::Reference< css::uri::XUriSchemeParser >( + service, css::uno::UNO_QUERY_THROW); + } + } + } + css::uno::Reference< css::uri::XUriReference > uriRef; + if (parser.is()) { + uriRef = parser->parse(scheme, schemeSpecificPart); + } else { + try { + uriRef = parseGeneric(scheme, schemeSpecificPart); + } catch (std::bad_alloc &) { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii("std::bad_alloc"), + static_cast< cppu::OWeakObject * >(this)); + } + } + if (uriRef.is() && fragment != uriReference.getLength()) { + uriRef->setFragment(uriReference.copy(fragment + 1)); + } + return uriRef; +} + +css::uno::Reference< css::uri::XUriReference > Factory::makeAbsolute( + css::uno::Reference< css::uri::XUriReference > const & baseUriReference, + css::uno::Reference< css::uri::XUriReference > const & uriReference, + sal_Bool processSpecialBaseSegments, + css::uri::RelativeUriExcessParentSegments excessParentSegments) + throw (css::uno::RuntimeException) +{ + if (!baseUriReference.is() || !baseUriReference->isAbsolute() + || !baseUriReference->isHierarchical() || !uriReference.is()) { + return 0; + } else if (uriReference->isAbsolute()) { + return clone(uriReference); + } else if (!uriReference->hasAuthority() + && uriReference->getPath().getLength() == 0 + && !uriReference->hasQuery()) { + css::uno::Reference< css::uri::XUriReference > abs( + clone(baseUriReference)); + if (uriReference->hasFragment()) { + abs->setFragment(uriReference->getFragment()); + } else { + abs->clearFragment(); + } + return abs; + } else { + rtl::OUStringBuffer abs(baseUriReference->getScheme()); + abs.append(static_cast< sal_Unicode >(':')); + if (uriReference->hasAuthority()) { + abs.appendAscii(RTL_CONSTASCII_STRINGPARAM("//")); + abs.append(uriReference->getAuthority()); + } else if (baseUriReference->hasAuthority()) { + abs.appendAscii(RTL_CONSTASCII_STRINGPARAM("//")); + abs.append(baseUriReference->getAuthority()); + } + if (uriReference->hasRelativePath()) { + Segments segments; + processSegments( + segments, baseUriReference, true, processSpecialBaseSegments); + processSegments(segments, uriReference, false, true); + // If the path component of the base URI reference is empty (which + // implies that the base URI reference denotes a "root entity"), and + // the resulting URI reference denotes the same root entity, make + // sure the path component of the resulting URI reference is also + // empty (and not "/"). RFC 2396 is unclear about this, and I chose + // these rules for consistent results. + bool slash = baseUriReference->getPath().getLength() != 0; + if (slash) { + abs.append(static_cast< sal_Unicode >('/')); + } + for (Segments::iterator i(segments.begin()); i != segments.end(); + ++i) + { + if (*i < -1) { + rtl::OUString segment( + baseUriReference->getPathSegment(-(*i + 2))); + if (segment.getLength() != 0 || segments.size() > 1) { + if (!slash) { + abs.append(static_cast< sal_Unicode >('/')); + } + abs.append(segment); + slash = true; + abs.append(static_cast< sal_Unicode >('/')); + } + } else if (*i > 1) { + rtl::OUString segment(uriReference->getPathSegment(*i - 2)); + if (segment.getLength() != 0 || segments.size() > 1) { + if (!slash) { + abs.append(static_cast< sal_Unicode >('/')); + } + abs.append(segment); + slash = false; + } + } else if (*i == 0) { + if (segments.size() > 1 && !slash) { + abs.append(static_cast< sal_Unicode >('/')); + } + } else { + switch (excessParentSegments) { + case css::uri::RelativeUriExcessParentSegments_ERROR: + return 0; + + case css::uri::RelativeUriExcessParentSegments_RETAIN: + if (!slash) { + abs.append(static_cast< sal_Unicode >('/')); + } + abs.appendAscii(RTL_CONSTASCII_STRINGPARAM("..")); + slash = *i < 0; + if (slash) { + abs.append(static_cast< sal_Unicode >('/')); + } + break; + + case css::uri::RelativeUriExcessParentSegments_REMOVE: + break; + + default: + OSL_ASSERT(false); + break; + } + } + } + } else { + abs.append(uriReference->getPath()); + } + if (uriReference->hasQuery()) { + abs.append(static_cast< sal_Unicode >('?')); + abs.append(uriReference->getQuery()); + } + if (uriReference->hasFragment()) { + abs.append(static_cast< sal_Unicode >('#')); + abs.append(uriReference->getFragment()); + } + return parse(abs.makeStringAndClear()); + } +} + +css::uno::Reference< css::uri::XUriReference > Factory::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) + throw (css::uno::RuntimeException) +{ + if (!baseUriReference.is() || !baseUriReference->isAbsolute() + || !baseUriReference->isHierarchical() || !uriReference.is()) { + return 0; + } else if (!uriReference->isAbsolute() || !uriReference->isHierarchical() + || !baseUriReference->getScheme().equalsIgnoreAsciiCase( + uriReference->getScheme())) { + return clone(uriReference); + } else { + rtl::OUStringBuffer rel; + bool omitQuery = false; + if ((baseUriReference->hasAuthority() != uriReference->hasAuthority()) + || !equalIgnoreEscapeCase( + baseUriReference->getAuthority(), + uriReference->getAuthority())) + { + if (uriReference->hasAuthority()) { + rel.appendAscii(RTL_CONSTASCII_STRINGPARAM("//")); + rel.append(uriReference->getAuthority()); + } + rel.append(uriReference->getPath()); + } else if ((equalIgnoreEscapeCase( + baseUriReference->getPath(), uriReference->getPath()) + || (baseUriReference->getPath().getLength() <= 1 + && uriReference->getPath().getLength() <= 1)) + && baseUriReference->hasQuery() == uriReference->hasQuery() + && equalIgnoreEscapeCase( + baseUriReference->getQuery(), uriReference->getQuery())) + { + omitQuery = true; + } else { + sal_Int32 count1 = std::max< sal_Int32 >( + baseUriReference->getPathSegmentCount(), 1); + sal_Int32 count2 = std::max< sal_Int32 >( + uriReference->getPathSegmentCount(), 1); + sal_Int32 i = 0; + for (; i < std::min(count1, count2) - 1; ++i) { + if (!equalIgnoreEscapeCase( + baseUriReference->getPathSegment(i), + uriReference->getPathSegment(i))) + { + break; + } + } + if (i == 0 && preferAbsoluteOverRelativePath + && (preferAuthorityOverRelativePath + || !uriReference->getPath().matchAsciiL( + RTL_CONSTASCII_STRINGPARAM("//")))) + { + if (baseUriReference->getPath().getLength() > 1 + || uriReference->getPath().getLength() > 1) + { + if (uriReference->getPath().getLength() == 0) { + rel.append(static_cast< sal_Unicode >('/')); + } else { + OSL_ASSERT(uriReference->getPath()[0] == '/'); + if (uriReference->getPath().matchAsciiL( + RTL_CONSTASCII_STRINGPARAM("//"))) { + OSL_ASSERT(uriReference->hasAuthority()); + rel.appendAscii(RTL_CONSTASCII_STRINGPARAM("//")); + rel.append(uriReference->getAuthority()); + } + rel.append(uriReference->getPath()); + } + } + } else { + bool segments = false; + for (sal_Int32 j = i; j < count1 - 1; ++j) { + if (segments) { + rel.append(static_cast< sal_Unicode >('/')); + } + rel.appendAscii(RTL_CONSTASCII_STRINGPARAM("..")); + segments = true; + } + if (i < count2 - 1 + || (uriReference->getPathSegment(count2 - 1).getLength() + != 0)) + { + if (!segments + && (uriReference->getPathSegment(i).getLength() == 0 + || (parseScheme(uriReference->getPathSegment(i)) + >= 0))) + { + rel.append(static_cast< sal_Unicode >('.')); + segments = true; + } + for (; i < count2; ++i) { + if (segments) { + rel.append(static_cast< sal_Unicode >('/')); + } + rtl::OUString s(uriReference->getPathSegment(i)); + if (encodeRetainedSpecialSegments + && s.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("."))) + { + rel.appendAscii(RTL_CONSTASCII_STRINGPARAM("%2E")); + } else if (encodeRetainedSpecialSegments + && s.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM(".."))) + { + rel.appendAscii( + RTL_CONSTASCII_STRINGPARAM("%2E%2E")); + } else { + rel.append(s); + } + segments = true; + } + } + } + } + if (!omitQuery && uriReference->hasQuery()) { + rel.append(static_cast< sal_Unicode >('?')); + rel.append(uriReference->getQuery()); + } + if (uriReference->hasFragment()) { + rel.append(static_cast< sal_Unicode >('#')); + rel.append(uriReference->getFragment()); + } + return parse(rel.makeStringAndClear()); + } +} + +} + +namespace stoc_services { namespace UriReferenceFactory { + +css::uno::Reference< css::uno::XInterface > create( + css::uno::Reference< css::uno::XComponentContext > const & context) + SAL_THROW((css::uno::Exception)) +{ + try { + return static_cast< cppu::OWeakObject * >(new Factory(context)); + } catch (std::bad_alloc &) { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii("std::bad_alloc"), 0); + } +} + +rtl::OUString getImplementationName() { + return rtl::OUString::createFromAscii( + "com.sun.star.comp.uri.UriReferenceFactory"); +} + +css::uno::Sequence< rtl::OUString > getSupportedServiceNames() { + css::uno::Sequence< rtl::OUString > s(1); + s[0] = rtl::OUString::createFromAscii( + "com.sun.star.uri.UriReferenceFactory"); + return s; +} + +} } |