LCOV - code coverage report
Current view: top level - stoc/source/uriproc - UriReferenceFactory.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 262 345 75.9 %
Date: 2012-08-25 Functions: 38 44 86.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 364 871 41.8 %

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

Generated by: LCOV version 1.10