LCOV - code coverage report
Current view: top level - include/tools - urlobj.hxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 98 119 82.4 %
Date: 2014-04-11 Functions: 49 56 87.5 %
Legend: Lines: hit not hit

          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             : #ifndef INCLUDED_TOOLS_URLOBJ_HXX
      20             : #define INCLUDED_TOOLS_URLOBJ_HXX
      21             : 
      22             : #include <tools/toolsdllapi.h>
      23             : #include <com/sun/star/uno/Reference.hxx>
      24             : #include <rtl/string.h>
      25             : #include <rtl/ustrbuf.hxx>
      26             : #include <rtl/textenc.h>
      27             : #include <sal/types.h>
      28             : 
      29             : namespace com { namespace sun { namespace star { namespace util {
      30             :     class XStringWidth;
      31             : } } } }
      32             : 
      33             : // Common URL prefixes for various schemes:
      34             : #define INET_FTP_SCHEME "ftp://"
      35             : #define INET_HTTP_SCHEME "http://"
      36             : #define INET_HTTPS_SCHEME "https://"
      37             : #define INET_FILE_SCHEME "file://"
      38             : #define INET_MAILTO_SCHEME "mailto:"
      39             : #define INET_NEWS_SCHEME "news:"
      40             : #define INET_HID_SCHEME "hid:"
      41             : 
      42             : #define URL_PREFIX_PRIV_SOFFICE "private:"
      43             : enum
      44             : {
      45             :     URL_PREFIX_PRIV_SOFFICE_LEN
      46             :         = RTL_CONSTASCII_LENGTH(URL_PREFIX_PRIV_SOFFICE)
      47             : };
      48             : 
      49             : #define URL_PREFIX_PRIV_OBSOLETE URL_PREFIX_PRIV_SOFFICE
      50             : enum
      51             : {
      52             :     URL_PREFIX_PRIV_OBSOLETE_LEN
      53             :         = RTL_CONSTASCII_LENGTH(URL_PREFIX_PRIV_OBSOLETE)
      54             : };
      55             : 
      56             : #define URL_PREFIX_PRIV_EXTERN "staroffice:"
      57             : enum
      58             : {
      59             :     URL_PREFIX_PRIV_EXTERN_LEN = RTL_CONSTASCII_LENGTH(URL_PREFIX_PRIV_EXTERN)
      60             : };
      61             : 
      62             : // Schemes:
      63             : enum INetProtocol
      64             : {
      65             :     INET_PROT_NOT_VALID = 0,
      66             :     INET_PROT_FTP = 1,
      67             :     INET_PROT_HTTP = 2,
      68             :     INET_PROT_FILE = 3,
      69             :     INET_PROT_MAILTO = 4,
      70             :     INET_PROT_VND_SUN_STAR_WEBDAV = 5,
      71             :     INET_PROT_NEWS = 6,
      72             :     INET_PROT_PRIV_SOFFICE = 7,
      73             :     INET_PROT_PRIVATE = INET_PROT_PRIV_SOFFICE, // obsolete
      74             :     INET_PROT_VND_SUN_STAR_HELP = 8,
      75             :     INET_PROT_HTTPS = 9,
      76             :     INET_PROT_SLOT = 10,
      77             :     INET_PROT_MACRO = 11,
      78             :     INET_PROT_JAVASCRIPT = 12,
      79             :     INET_PROT_IMAP = 13,
      80             :     INET_PROT_POP3 = 14,
      81             :     INET_PROT_DATA = 15,
      82             :     INET_PROT_CID = 16,
      83             :     INET_PROT_OUT = 17,
      84             :     INET_PROT_VND_SUN_STAR_HIER = 18,
      85             :     INET_PROT_VIM = 19,
      86             :     INET_PROT_UNO = 20,
      87             :     INET_PROT_COMPONENT = 21,
      88             :     INET_PROT_VND_SUN_STAR_PKG = 22,
      89             :     INET_PROT_LDAP = 23,
      90             :     INET_PROT_DB = 24,
      91             :     INET_PROT_VND_SUN_STAR_CMD = 25,
      92             :     INET_PROT_TELNET = 27,
      93             :     INET_PROT_VND_SUN_STAR_EXPAND = 28,
      94             :     INET_PROT_VND_SUN_STAR_TDOC = 29,
      95             :     INET_PROT_GENERIC = 30,
      96             :     INET_PROT_SMB = 31,
      97             :     INET_PROT_HID = 32,
      98             :     INET_PROT_SFTP = 33,
      99             :     INET_PROT_CMIS = 34,
     100             :     INET_PROT_END = 35
     101             : };
     102             : 
     103      732070 : class TOOLS_DLLPUBLIC SAL_WARN_UNUSED INetURLObject
     104             : {
     105             : public:
     106             :     // Get- and Set-Methods:
     107             : 
     108             :     /** The way input strings that represent (parts of) URIs are interpreted
     109             :         in set-methods.
     110             : 
     111             :         @descr  UTF-32 characters in the range 0x80--0x10FFFF are replaced by
     112             :         sequences of escape sequences, representing the UTF-8 coded characters.
     113             : 
     114             :         @descr  Along with an EncodeMechanism parameter, the set-methods all
     115             :         take an rtl_TextEncoding parameter, which is ignored unless the
     116             :         EncodeMechanism is WAS_ENCODED.
     117             :      */
     118             :     enum EncodeMechanism
     119             :     {
     120             :         /** All escape sequences that are already present are ignored, and are
     121             :             interpreted as literal sequences of three characters.
     122             :          */
     123             :         ENCODE_ALL,
     124             : 
     125             :         /** Sequences of escape sequences, that represent characters from the
     126             :             specified character set and that can be converted to UTF-32
     127             :             characters, are first decoded.  If they have to be encoded, they
     128             :             are converted to UTF-8 characters and are than translated into
     129             :             (sequences of) escape sequences.  Other escape sequences are
     130             :             copied verbatim (but using upper case hex digits).
     131             :          */
     132             :         WAS_ENCODED,
     133             : 
     134             :         /** All escape sequences that are already present are copied verbatim
     135             :             (but using upper case hex digits).
     136             :          */
     137             :         NOT_CANONIC
     138             :     };
     139             : 
     140             :     /** The way strings that represent (parts of) URIs are returned from get-
     141             :         methods.
     142             : 
     143             :         @descr  Along with a DecodeMechanism parameter, the get-methods all
     144             :         take an rtl_TextEncoding parameter, which is ignored unless the
     145             :         DecodeMechanism is DECODE_WITH_CHARSET or DECODE_UNAMBIGUOUS.
     146             :      */
     147             :     enum DecodeMechanism
     148             :     {
     149             :         /** The (part of the) URI is returned unchanged.  Since URIs are
     150             :             written using a subset of US-ASCII, the returned string is
     151             :             guaranteed to contain only US-ASCII characters.
     152             :          */
     153             :         NO_DECODE,
     154             : 
     155             :         /** All sequences of escape sequences that represent UTF-8 coded
     156             :             UTF-32 characters with a numerical value greater than 0x7F, are
     157             :             replaced by the respective UTF-16 characters.  All other escape
     158             :             sequences are not decoded.
     159             :          */
     160             :         DECODE_TO_IURI,
     161             : 
     162             :         /** All (sequences of) escape sequences that represent characters from
     163             :             the specified character set, and that can be converted to UTF-32,
     164             :             are replaced by the respective UTF-16 characters.  All other
     165             :             escape sequences are not decoded.
     166             :          */
     167             :         DECODE_WITH_CHARSET,
     168             : 
     169             :         /** All (sequences of) escape sequences that represent characters from
     170             :             the specified character set, that can be converted to UTF-32, and
     171             :             that (in the case of ASCII characters) can safely be decoded
     172             :             without altering the meaning of the (part of the) URI, are
     173             :             replaced by the respective UTF-16 characters.  All other escape
     174             :             sequences are not decoded.
     175             :          */
     176             :         DECODE_UNAMBIGUOUS
     177             :     };
     178             : 
     179             :     // General Structure:
     180             : 
     181        9649 :     inline INetURLObject():
     182        9649 :         m_eScheme(INET_PROT_NOT_VALID), m_eSmartScheme(INET_PROT_HTTP) {}
     183             : 
     184      794123 :     inline bool HasError() const { return m_eScheme == INET_PROT_NOT_VALID; }
     185             : 
     186      645169 :     inline OUString GetMainURL(DecodeMechanism eMechanism,
     187             :                                 rtl_TextEncoding eCharset
     188             :                                     = RTL_TEXTENCODING_UTF8) const
     189      645169 :     { return decode(m_aAbsURIRef, getEscapePrefix(), eMechanism, eCharset); }
     190             : 
     191             :     OUString GetURLNoPass(DecodeMechanism eMechanism = DECODE_TO_IURI,
     192             :                            rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
     193             :         const;
     194             : 
     195             :     OUString GetURLNoMark(DecodeMechanism eMechanism = DECODE_TO_IURI,
     196             :                            rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
     197             :         const;
     198             : 
     199             :     OUString
     200             :     getAbbreviated(com::sun::star::uno::Reference<
     201             :                            com::sun::star::util::XStringWidth > const &
     202             :                        rStringWidth,
     203             :                    sal_Int32 nWidth,
     204             :                    DecodeMechanism eMechanism = DECODE_TO_IURI,
     205             :                    rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
     206             :         const;
     207             : 
     208             :     bool operator ==(INetURLObject const & rObject) const;
     209             : 
     210         372 :     inline bool operator !=(INetURLObject const & rObject) const
     211         372 :     { return !(*this == rObject); }
     212             : 
     213             :     bool operator <(INetURLObject const & rObject) const;
     214             : 
     215             :     inline bool operator >(INetURLObject const & rObject) const
     216             :     { return rObject < *this; }
     217             : 
     218             :     // Strict Parsing:
     219             : 
     220             :     inline explicit INetURLObject(
     221             :         OUString const & rTheAbsURIRef,
     222             :         EncodeMechanism eMechanism = WAS_ENCODED,
     223             :         rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
     224             : 
     225             :     inline bool SetURL(OUString const & rTheAbsURIRef,
     226             :                        EncodeMechanism eMechanism = WAS_ENCODED,
     227             :                        rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
     228             : 
     229             :     bool ConcatData(INetProtocol eTheScheme, OUString const & rTheUser,
     230             :                     OUString const & rThePassword,
     231             :                     OUString const & rTheHost, sal_uInt32 nThePort,
     232             :                     OUString const & rThePath,
     233             :                     EncodeMechanism eMechanism = WAS_ENCODED,
     234             :                     rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
     235             : 
     236             :     // Smart Parsing:
     237             : 
     238             :     /** The supported notations for file system paths.
     239             :      */
     240             :     enum FSysStyle
     241             :     {
     242             :         /** VOS notation (e.g., "//server/dir/file").
     243             :          */
     244             :         FSYS_VOS = 0x1,
     245             : 
     246             :         /** Unix notation (e.g., "/dir/file").
     247             :          */
     248             :         FSYS_UNX = 0x2,
     249             : 
     250             :         /** DOS notation (e.g., "a:\dir\file" and "\\server\dir\file").
     251             :          */
     252             :         FSYS_DOS = 0x4,
     253             : 
     254             :         /** Detect the used notation.
     255             : 
     256             :             @descr  For the following descriptions, please note that
     257             :             whereas FSYS_DEFAULT includes all style bits, combinations of only
     258             :             a few style bits are also possible, and are also described.
     259             : 
     260             :             @descr  When used to translate a file system path to a file URL,
     261             :             the subset of the following productions for which the appropriate
     262             :             style bit is set are checked in order (using the conventions of
     263             :             RFC 2234, RFC 2396, and RFC 2732; UCS4 stands for any UCS4
     264             :             character):
     265             : 
     266             :              Production T1 (VOS local; FSYS_VOS only):
     267             :                 "//." ["/" *UCS4]
     268             :               becomes
     269             :                 "file:///" *UCS4
     270             : 
     271             :              Production T2 (VOS host; FSYS_VOS only):
     272             :                 "//" [host] ["/" *UCS4]
     273             :               becomes
     274             :                 "file://" host "/" *UCS4
     275             : 
     276             :              Production T3 (UNC; FSYS_DOS only):
     277             :                 "\\" [host] ["\" *UCS4]
     278             :               becomes
     279             :                 "file://" host "/" *UCS4
     280             :               replacing "\" by "/" within <*UCS4>
     281             : 
     282             :              Production T4 (Unix-like DOS; FSYS_DOS only):
     283             :                 ALPHA ":" ["/" *UCS4]
     284             :               becomes
     285             :                 "file:///" ALPHA ":/" *UCS4
     286             :               replacing "\" by "/" within <*UCS4>
     287             : 
     288             :              Production T5 (DOS; FSYS_DOS only):
     289             :                 ALPHA ":" ["\" *UCS4]
     290             :               becomes
     291             :                 "file:///" ALPHA ":/" *UCS4
     292             :               replacing "\" by "/" within <*UCS4>
     293             : 
     294             :              Production T6 (any):
     295             :                 *UCS4
     296             :               becomes
     297             :                 "file:///" *UCS4
     298             :               replacing the delimiter by "/" within <*UCS4>.  The delimiter is
     299             :               that character from the set { "/", "\" } which appears most
     300             :               often in <*UCS4> (if FSYS_UNX is not among the style bits, "/"
     301             :               is removed from the set; if FSYS_DOS is not among the style
     302             :               bits, "\" is removed from the set).  If two or more
     303             :               characters appear the same number of times, the character
     304             :               mentioned first in that set is chosen.  If the first character
     305             :               of <*UCS4> is the delimiter, that character is not copied.
     306             : 
     307             :             @descr  When used to translate a file URL to a file system path,
     308             :             the following productions are checked in order (using the
     309             :             conventions of RFC 2234, RFC 2396, and RFC 2732):
     310             : 
     311             :              Production F1 (VOS; FSYS_VOS):
     312             :                 "file://" host "/" fpath ["#" fragment]
     313             :               becomes
     314             :                 "//" host "/" fpath
     315             : 
     316             :              Production F2 (DOS; FSYS_DOS):
     317             :                 "file:///" ALPHA ":" ["/" fpath] ["#" fragment]
     318             :               becomes
     319             :                 ALPHA ":" ["\" fpath]
     320             :               replacing "/" by "\" in <fpath>
     321             : 
     322             :              Production F3 (Unix; FSYS_UNX):
     323             :                 "file:///" fpath ["#" fragment]
     324             :               becomes
     325             :                 "/" fpath
     326             :          */
     327             :         FSYS_DETECT = FSYS_VOS | FSYS_UNX | FSYS_DOS
     328             :     };
     329             : 
     330             :     inline INetURLObject(OUString const & rTheAbsURIRef,
     331             :                          INetProtocol eTheSmartScheme,
     332             :                          EncodeMechanism eMechanism = WAS_ENCODED,
     333             :                          rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
     334             :                          FSysStyle eStyle = FSYS_DETECT);
     335             : 
     336         374 :     inline void SetSmartProtocol(INetProtocol eTheSmartScheme)
     337         374 :     { m_eSmartScheme = eTheSmartScheme; }
     338             : 
     339             :     inline bool
     340             :     SetSmartURL(OUString const & rTheAbsURIRef,
     341             :                 EncodeMechanism eMechanism = WAS_ENCODED,
     342             :                 rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
     343             :                 FSysStyle eStyle = FSYS_DETECT);
     344             : 
     345             :     inline INetURLObject
     346             :     smartRel2Abs(OUString const & rTheRelURIRef,
     347             :                  bool & rWasAbsolute,
     348             :                  bool bIgnoreFragment = false,
     349             :                  EncodeMechanism eMechanism = WAS_ENCODED,
     350             :                  rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
     351             :                  bool bRelativeNonURIs = false,
     352             :                  FSysStyle eStyle = FSYS_DETECT) const;
     353             : 
     354             :     // Relative URLs:
     355             : 
     356             :     inline bool
     357             :     GetNewAbsURL(OUString const & rTheRelURIRef,
     358             :                  INetURLObject * pTheAbsURIRef,
     359             :                  EncodeMechanism eMechanism = WAS_ENCODED,
     360             :                  rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
     361             :                  FSysStyle eStyle = FSYS_DETECT, bool bIgnoreFragment = false)
     362             :         const;
     363             : 
     364             :     /** @descr  If rTheRelURIRef cannot be converted to an absolute URL
     365             :         (because of syntactic reasons), either rTheRelURIRef or an empty
     366             :         string is returned:  If all of the parameters eEncodeMechanism,
     367             :         eDecodeMechanism and eCharset have their respective default values,
     368             :         then rTheRelURIRef is returned unmodified; otherwise, an empty string
     369             :         is returned.
     370             :      */
     371             :     static OUString
     372             :     GetAbsURL(OUString const & rTheBaseURIRef,
     373             :               OUString const & rTheRelURIRef,
     374             :               bool bIgnoreFragment = false,
     375             :               EncodeMechanism eEncodeMechanism = WAS_ENCODED,
     376             :               DecodeMechanism eDecodeMechanism = DECODE_TO_IURI,
     377             :               rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
     378             :               FSysStyle eStyle = FSYS_DETECT);
     379             : 
     380             :     static inline OUString
     381             :     GetRelURL(OUString const & rTheBaseURIRef,
     382             :               OUString const & rTheAbsURIRef,
     383             :               EncodeMechanism eEncodeMechanism = WAS_ENCODED,
     384             :               DecodeMechanism eDecodeMechanism = DECODE_TO_IURI,
     385             :               rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
     386             :               FSysStyle eStyle = FSYS_DETECT);
     387             : 
     388             :     // External URLs:
     389             : 
     390             :     OUString getExternalURL(DecodeMechanism eMechanism = DECODE_TO_IURI,
     391             :                              rtl_TextEncoding eCharset
     392             :                                  = RTL_TEXTENCODING_UTF8) const;
     393             : 
     394             :     static inline bool translateToExternal(OUString const & rTheIntURIRef,
     395             :                                            OUString & rTheExtURIRef,
     396             :                                            DecodeMechanism eDecodeMechanism
     397             :                                                = DECODE_TO_IURI,
     398             :                                            rtl_TextEncoding eCharset
     399             :                                                = RTL_TEXTENCODING_UTF8);
     400             : 
     401             :     static inline bool translateToInternal(OUString const & rTheExtURIRef,
     402             :                                            OUString & rTheIntURIRef,
     403             :                                            DecodeMechanism eDecodeMechanism
     404             :                                                = DECODE_TO_IURI,
     405             :                                            rtl_TextEncoding eCharset
     406             :                                                = RTL_TEXTENCODING_UTF8);
     407             : 
     408             :     // Scheme:
     409             : 
     410             :     struct SchemeInfo;
     411             : 
     412      709960 :     inline INetProtocol GetProtocol() const { return m_eScheme; }
     413             : 
     414             :     /** Return the URL 'prefix' for a given scheme.
     415             : 
     416             :         @param eTheScheme  One of the supported URL schemes.
     417             : 
     418             :         @return  The 'prefix' of URLs of the given scheme.
     419             :      */
     420             :     static OUString GetScheme(INetProtocol eTheScheme);
     421             : 
     422             :     /** Return the a human-readable name for a given scheme.
     423             : 
     424             :         @param eTheScheme  One of the supported URL schemes.
     425             : 
     426             :         @return  The protocol name of URLs of the given scheme.
     427             :      */
     428             :     static OUString GetSchemeName(INetProtocol eTheScheme);
     429             : 
     430             :     static INetProtocol CompareProtocolScheme(OUString const &
     431             :                                                   rTheAbsURIRef);
     432             : 
     433             :     // User Info:
     434             : 
     435           1 :     inline bool HasUserData() const { return m_aUser.isPresent(); }
     436             : 
     437             :     inline bool IsEmptyUser() const
     438             :     { return m_aUser.isPresent() && m_aUser.isEmpty(); }
     439             : 
     440      295184 :     inline OUString GetUser(DecodeMechanism eMechanism = DECODE_TO_IURI,
     441             :                              rtl_TextEncoding eCharset
     442             :                                  = RTL_TEXTENCODING_UTF8) const
     443      295184 :     { return decode(m_aUser, getEscapePrefix(), eMechanism, eCharset); }
     444             : 
     445      295183 :     inline OUString GetPass(DecodeMechanism eMechanism = DECODE_TO_IURI,
     446             :                              rtl_TextEncoding eCharset
     447             :                                  = RTL_TEXTENCODING_UTF8) const
     448      295183 :     { return decode(m_aAuth, getEscapePrefix(), eMechanism, eCharset); }
     449             : 
     450           0 :     inline bool SetUser(OUString const & rTheUser,
     451             :                         EncodeMechanism eMechanism = WAS_ENCODED,
     452             :                         rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
     453           0 :     { return setUser(rTheUser, false, eMechanism, eCharset); }
     454             : 
     455             :     inline bool SetPass(OUString const & rThePassword,
     456             :                         EncodeMechanism eMechanism = WAS_ENCODED,
     457             :                         rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
     458             : 
     459             :     inline bool SetUserAndPass(OUString const & rTheUser,
     460             :                                OUString const & rThePassword,
     461             :                                EncodeMechanism eMechanism = WAS_ENCODED,
     462             :                                rtl_TextEncoding eCharset
     463             :                                    = RTL_TEXTENCODING_UTF8);
     464             : 
     465             :     // Host and Port:
     466             : 
     467         664 :     inline bool HasPort() const { return m_aPort.isPresent(); }
     468             : 
     469      295193 :     inline OUString GetHost(DecodeMechanism eMechanism = DECODE_TO_IURI,
     470             :                              rtl_TextEncoding eCharset
     471             :                                  = RTL_TEXTENCODING_UTF8) const
     472      295193 :     { return decode(m_aHost, getEscapePrefix(), eMechanism, eCharset); }
     473             : 
     474             :     OUString GetHostPort(DecodeMechanism eMechanism = DECODE_TO_IURI,
     475             :                           rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
     476             : 
     477             :     sal_uInt32 GetPort() const;
     478             : 
     479           0 :     inline bool SetHost(OUString const & rTheHost,
     480             :                         EncodeMechanism eMechanism = WAS_ENCODED,
     481             :                         rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
     482           0 :     { return setHost(rTheHost, false, eMechanism, eCharset); }
     483             : 
     484             :     bool SetPort(sal_uInt32 nThePort);
     485             : 
     486             :     // Path:
     487             : 
     488         664 :     inline bool HasURLPath() const { return !m_aPath.isEmpty(); }
     489             : 
     490      378271 :     inline OUString GetURLPath(DecodeMechanism eMechanism = DECODE_TO_IURI,
     491             :                                 rtl_TextEncoding eCharset
     492             :                                     = RTL_TEXTENCODING_UTF8) const
     493      378271 :     { return decode(m_aPath, getEscapePrefix(), eMechanism, eCharset); }
     494             : 
     495         126 :     inline bool SetURLPath(OUString const & rThePath,
     496             :                            EncodeMechanism eMechanism = WAS_ENCODED,
     497             :                            rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
     498         126 :     { return setPath(rThePath, false, eMechanism, eCharset); }
     499             : 
     500             :     // Hierarchical Path:
     501             : 
     502             :     /** A constant to address the last segment in various methods dealing with
     503             :         hierarchical paths.
     504             : 
     505             :         @descr  It is often more efficient to address the last segment using
     506             :         this constant, than to determine its ordinal value using
     507             :         getSegmentCount().
     508             :      */
     509             :     enum { LAST_SEGMENT = -1 };
     510             : 
     511             :     /** The number of segments in the hierarchical path.
     512             : 
     513             :         @descr  Using RFC 2396 and RFC 2234, a hierarchical path is of the
     514             :         form
     515             : 
     516             :           hierarchical-path = 1*("/" segment)
     517             : 
     518             :           segment = name *(";" param)
     519             : 
     520             :           name = [base ["." extension]]
     521             : 
     522             :           base = 1*pchar
     523             : 
     524             :           extension = *<any pchar except ".">
     525             : 
     526             :           param = *pchar
     527             : 
     528             :         @param bIgnoreFinalSlash  If true, a final slash at the end of the
     529             :         hierarchical path does not denote an empty segment, but is ignored.
     530             : 
     531             :         @return  The number of segments in the hierarchical path.  If the path
     532             :         is not hierarchical, 0 is returned.
     533             :      */
     534             :     sal_Int32 getSegmentCount(bool bIgnoreFinalSlash = true) const;
     535             : 
     536             :     /** Remove a segment from the hierarchical path.
     537             : 
     538             :         @param nIndex  The non-negative index of the segment, or LAST_SEGMENT
     539             :         if addressing the last segment.
     540             : 
     541             :         @param bIgnoreFinalSlash  If true, a final slash at the end of the
     542             :         hierarchical path does not denote an empty segment, but is ignored.
     543             : 
     544             :         @return  True if the segment has successfully been removed (and the
     545             :         resulting URI is still valid).  If the path is not hierarchical, or
     546             :         the specified segment does not exist, false is returned.  If false is
     547             :         returned, the object is not modified.
     548             :      */
     549             :     bool removeSegment(sal_Int32 nIndex = LAST_SEGMENT,
     550             :                        bool bIgnoreFinalSlash = true);
     551             : 
     552             :     /** Insert a new segment into the hierarchical path.
     553             : 
     554             :         @param rTheName  The name part of the new segment.  The new segment
     555             :         will contain no parameters.
     556             : 
     557             :         @param bAppendFinalSlash  If the new segment is appended at the end of
     558             :         the hierarchical path, this parameter specifies whether to add a final
     559             :         slash after it or not.
     560             : 
     561             :         @param nIndex  The non-negative index of the segment before which
     562             :         to insert the new segment.  LAST_SEGMENT or an nIndex that equals
     563             :         getSegmentCount() inserts the new segment at the end of the
     564             :         hierarchical path.
     565             : 
     566             :         @param bIgnoreFinalSlash  If true, a final slash at the end of the
     567             :         hierarchical path does not denote an empty segment, but is ignored.
     568             : 
     569             :         @param eMechanism  See the general discussion for set-methods.
     570             : 
     571             :         @param eCharset  See the general discussion for set-methods.
     572             : 
     573             :         @return  True if the segment has successfully been inserted (and the
     574             :         resulting URI is still valid).  If the path is not hierarchical, or
     575             :         the specified place to insert the new segment does not exist, false is
     576             :         returned.  If false is returned, the object is not modified.
     577             :      */
     578             :     inline bool insertName(OUString const & rTheName,
     579             :                            bool bAppendFinalSlash = false,
     580             :                            sal_Int32 nIndex = LAST_SEGMENT,
     581             :                            bool bIgnoreFinalSlash = true,
     582             :                            EncodeMechanism eMechanism = WAS_ENCODED,
     583             :                            rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
     584             : 
     585             :     /** Get the name of a segment of the hierarchical path.
     586             : 
     587             :         @param nIndex  The non-negative index of the segment, or LAST_SEGMENT
     588             :         if addressing the last segment.
     589             : 
     590             :         @param bIgnoreFinalSlash  If true, a final slash at the end of the
     591             :         hierarchical path does not denote an empty segment, but is ignored.
     592             : 
     593             :         @param eMechanism  See the general discussion for get-methods.
     594             : 
     595             :         @param eCharset  See the general discussion for get-methods.
     596             : 
     597             :         @return  The name part of the specified segment.  If the path is not
     598             :         hierarchical, or the specified segment does not exits, an empty string
     599             :         is returned.
     600             :      */
     601             :     OUString getName(sal_Int32 nIndex = LAST_SEGMENT,
     602             :                       bool bIgnoreFinalSlash = true,
     603             :                       DecodeMechanism eMechanism = DECODE_TO_IURI,
     604             :                       rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
     605             :         const;
     606             : 
     607             :     /** Set the name of a segment (preserving any parameters and any query or
     608             :         fragment part).
     609             : 
     610             :         @param rTheName  The new name.
     611             : 
     612             :         @param nIndex  The non-negative index of the segment, or LAST_SEGMENT
     613             :         if addressing the last segment.
     614             : 
     615             :         @param bIgnoreFinalSlash  If true, a final slash at the end of the
     616             :         hierarchical path does not denote an empty segment, but is ignored.
     617             : 
     618             :         @param eMechanism  See the general discussion for set-methods.
     619             : 
     620             :         @param eCharset  See the general discussion for set-methods.
     621             : 
     622             :         @return  True if the name has successfully been modified (and the
     623             :         resulting URI is still valid).  If the path is not hierarchical, or
     624             :         the specified segment does not exist, false is returned.  If false is
     625             :         returned, the object is not modified.
     626             :      */
     627             :     bool setName(OUString const & rTheName,
     628             :                  sal_Int32 nIndex = LAST_SEGMENT,
     629             :                  bool bIgnoreFinalSlash = true,
     630             :                  EncodeMechanism eMechanism = WAS_ENCODED,
     631             :                  rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
     632             : 
     633             :     /** Get the base of the name of a segment.
     634             : 
     635             :         @param nIndex  The non-negative index of the segment, or LAST_SEGMENT
     636             :         if addressing the last segment.
     637             : 
     638             :         @param bIgnoreFinalSlash  If true, a final slash at the end of the
     639             :         hierarchical path does not denote an empty segment, but is ignored.
     640             : 
     641             :         @param eMechanism  See the general discussion for get-methods.
     642             : 
     643             :         @param eCharset  See the general discussion for get-methods.
     644             : 
     645             :         @return  The base part of the specified segment.  If the path is
     646             :         not hierarchical, or the specified segment does not exits, an empty
     647             :         string is returned.
     648             :      */
     649             :     OUString getBase(sal_Int32 nIndex = LAST_SEGMENT,
     650             :                       bool bIgnoreFinalSlash = true,
     651             :                       DecodeMechanism eMechanism = DECODE_TO_IURI,
     652             :                       rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
     653             :         const;
     654             : 
     655             :     /** Set the base of the name of a segment (preserving the extension).
     656             : 
     657             :         @param rTheBase  The new base.
     658             : 
     659             :         @param nIndex  The non-negative index of the segment, or LAST_SEGMENT
     660             :         if addressing the last segment.
     661             : 
     662             :         @param bIgnoreFinalSlash  If true, a final slash at the end of the
     663             :         hierarchical path does not denote an empty segment, but is ignored.
     664             : 
     665             :         @param eMechanism  See the general discussion for set-methods.
     666             : 
     667             :         @param eCharset  See the general discussion for set-methods.
     668             : 
     669             :         @return  True if the base has successfully been modified (and the
     670             :         resulting URI is still valid).  If the path is not hierarchical, or
     671             :         the specified segment does not exist, false is returned.  If false is
     672             :         returned, the object is not modified.
     673             :      */
     674             :     bool setBase(OUString const & rTheBase,
     675             :                  sal_Int32 nIndex = LAST_SEGMENT,
     676             :                  bool bIgnoreFinalSlash = true,
     677             :                  EncodeMechanism eMechanism = WAS_ENCODED,
     678             :                  rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
     679             : 
     680             :     /** Determine whether the name of a segment has an extension.
     681             : 
     682             :         @param nIndex  The non-negative index of the segment, or LAST_SEGMENT
     683             :         if addressing the last segment.
     684             : 
     685             :         @param bIgnoreFinalSlash  If true, a final slash at the end of the
     686             :         hierarchical path does not denote an empty segment, but is ignored.
     687             : 
     688             :         @return  True if the name of the specified segment has an extension.
     689             :         If the path is not hierarchical, or the specified segment does not
     690             :         exist, false is returned.
     691             :      */
     692             :     bool hasExtension(sal_Int32 nIndex = LAST_SEGMENT,
     693             :                       bool bIgnoreFinalSlash = true) const;
     694             : 
     695             :     /** Get the extension of the name of a segment.
     696             : 
     697             :         @param nIndex  The non-negative index of the segment, or LAST_SEGMENT
     698             :         if addressing the last segment.
     699             : 
     700             :         @param bIgnoreFinalSlash  If true, a final slash at the end of the
     701             :         hierarchical path does not denote an empty segment, but is ignored.
     702             : 
     703             :         @param eMechanism  See the general discussion for get-methods.
     704             : 
     705             :         @param eCharset  See the general discussion for get-methods.
     706             : 
     707             :         @return  The extension part of the specified segment.  If the path is
     708             :         not hierarchical, or the specified segment does not exits, an empty
     709             :         string is returned.
     710             :      */
     711             :     OUString getExtension(sal_Int32 nIndex = LAST_SEGMENT,
     712             :                            bool bIgnoreFinalSlash = true,
     713             :                            DecodeMechanism eMechanism = DECODE_TO_IURI,
     714             :                            rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
     715             :         const;
     716             : 
     717             :     /** Set the extension of the name of a segment (replacing an already
     718             :         existing extension).
     719             : 
     720             :         @param rTheExtension  The new extension.
     721             : 
     722             :         @param nIndex  The non-negative index of the segment, or LAST_SEGMENT
     723             :         if addressing the last segment.
     724             : 
     725             :         @param bIgnoreFinalSlash  If true, a final slash at the end of the
     726             :         hierarchical path does not denote an empty segment, but is ignored.
     727             : 
     728             :         @param eMechanism  See the general discussion for set-methods.
     729             : 
     730             :         @param eCharset  See the general discussion for set-methods.
     731             : 
     732             :         @return  True if the extension has successfully been modified (and the
     733             :         resulting URI is still valid).  If the path is not hierarchical, or
     734             :         the specified segment does not exist, false is returned.  If false is
     735             :         returned, the object is not modified.
     736             :      */
     737             :     bool setExtension(OUString const & rTheExtension,
     738             :                       sal_Int32 nIndex = LAST_SEGMENT,
     739             :                       bool bIgnoreFinalSlash = true,
     740             :                       EncodeMechanism eMechanism = WAS_ENCODED,
     741             :                       rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
     742             : 
     743             :     /** Remove the extension of the name of a segment.
     744             : 
     745             :         @param nIndex  The non-negative index of the segment, or LAST_SEGMENT
     746             :         if addressing the last segment.
     747             : 
     748             :         @param bIgnoreFinalSlash  If true, a final slash at the end of the
     749             :         hierarchical path does not denote an empty segment, but is ignored.
     750             : 
     751             :         @return  True if the extension has successfully been removed (and the
     752             :         resulting URI is still valid), or if the name did not have an
     753             :         extension.  If the path is not hierarchical, or the specified segment
     754             :         does not exist, false is returned.  If false is returned, the object
     755             :         is not modified.
     756             :      */
     757             :     bool removeExtension(sal_Int32 nIndex = LAST_SEGMENT,
     758             :                          bool bIgnoreFinalSlash = true);
     759             : 
     760             :     /** Determine whether the hierarchical path ends in a final slash.
     761             : 
     762             :         @return  True if the hierarchical path ends in a final slash.  If the
     763             :         path is not hierarchical, false is returned.
     764             :      */
     765             :     bool hasFinalSlash() const;
     766             : 
     767             :     /** Make the hierarchical path end in a final slash (if it does not
     768             :         already do so).
     769             : 
     770             :         @return  True if a final slash has successfully been appended (and the
     771             :         resulting URI is still valid), or if the hierarchical path already
     772             :         ended in a final slash.  If the path is not hierarchical, false is
     773             :         returned.  If false is returned, the object is not modified.
     774             :      */
     775             :     bool setFinalSlash();
     776             : 
     777             :     /** Remove a final slash from the hierarchical path.
     778             : 
     779             :         @return  True if a final slash has successfully been removed (and the
     780             :         resulting URI is still valid), or if the hierarchical path already did
     781             :         not end in a final slash.  If the path is not hierarchical, false is
     782             :         returned.  If false is returned, the object is not modified.
     783             :      */
     784             :     bool removeFinalSlash();
     785             : 
     786             :     // Query:
     787             : 
     788       33347 :     inline bool HasParam() const { return m_aQuery.isPresent(); }
     789             : 
     790      295183 :     inline OUString GetParam(DecodeMechanism eMechanism = DECODE_TO_IURI,
     791             :                               rtl_TextEncoding eCharset
     792             :                                   = RTL_TEXTENCODING_UTF8) const
     793      295183 :     { return decode(m_aQuery, getEscapePrefix(), eMechanism, eCharset); }
     794             : 
     795             :     inline bool SetParam(OUString const & rTheQuery,
     796             :                          EncodeMechanism eMechanism = WAS_ENCODED,
     797             :                          rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
     798             : 
     799             :     // Fragment:
     800             : 
     801       15142 :     inline bool HasMark() const { return m_aFragment.isPresent(); }
     802             : 
     803      262306 :     inline OUString GetMark(DecodeMechanism eMechanism = DECODE_TO_IURI,
     804             :                              rtl_TextEncoding eCharset
     805             :                                  = RTL_TEXTENCODING_UTF8) const
     806      262306 :     { return decode(m_aFragment, getEscapePrefix(), eMechanism, eCharset); }
     807             : 
     808             :     inline bool SetMark(OUString const & rTheFragment,
     809             :                         EncodeMechanism eMechanism = WAS_ENCODED,
     810             :                         rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
     811             : 
     812             :     // File URLs:
     813             : 
     814             :     /** Create an INetURLObject from a file system path.
     815             : 
     816             :         @param rFSysPath  A file system path.  An URL is not allowed here!
     817             : 
     818             :         @param eStyle  The notation of rFSysPath.
     819             :      */
     820             :     inline INetURLObject(OUString const & rFSysPath, FSysStyle eStyle);
     821             : 
     822             :     /** Set this INetURLObject to a file URL constructed from a file system
     823             :         path.
     824             : 
     825             :         @param rFSysPath  A file system path.  An URL is not allowed here!
     826             : 
     827             :         @param eStyle  The notation of rFSysPath.
     828             : 
     829             :         @return  True if this INetURLObject has successfully been changed.  If
     830             :         false is returned, this INetURLObject has not been modified.
     831             :      */
     832             :     bool setFSysPath(OUString const & rFSysPath, FSysStyle eStyle);
     833             : 
     834             :     /** Return the file system path represented by a file URL (ignoring any
     835             :         fragment part).
     836             : 
     837             :         @param eStyle  The notation of the returned file system path.
     838             : 
     839             :         @param pDelimiter  Upon successful return, this parameter can return
     840             :         the character that is the 'main' delimiter within the returned file
     841             :         system path (e.g., "/" for Unix, "\" for DOS).  This is
     842             :         especially useful for routines that later try to shorten the returned
     843             :         file system path at a 'good' position, e.g. to fit it into some
     844             :         limited display space.
     845             : 
     846             :         @return  The file system path represented by this file URL.  If this
     847             :         file URL does not represent a file system path according to the
     848             :         specified notation, or if this is not a file URL at all, an empty
     849             :         string is returned.
     850             :      */
     851             :     OUString getFSysPath(FSysStyle eStyle, sal_Unicode * pDelimiter = 0)
     852             :         const;
     853             : 
     854             :     // POP3 and URLs:
     855             : 
     856             :     OUString GetMsgId(DecodeMechanism eMechanism = DECODE_TO_IURI,
     857             :                        rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
     858             :         const;
     859             : 
     860             :     // Coding:
     861             : 
     862             :     enum Part
     863             :     {
     864             :         PART_OBSOLETE_NORMAL = 0x001, // Obsolete, do not use!
     865             :         PART_OBSOLETE_FILE = 0x002, // Obsolete, do not use!
     866             :         PART_OBSOLETE_PARAM = 0x004, // Obsolete, do not use!
     867             :         PART_USER_PASSWORD = 0x008,
     868             :         PART_IMAP_ACHAR = 0x010,
     869             :         PART_VIM = 0x020,
     870             :         PART_HOST_EXTRA = 0x040,
     871             :         PART_FPATH = 0x080,
     872             :         PART_AUTHORITY = 0x100,
     873             :         PART_PATH_SEGMENTS_EXTRA = 0x200,
     874             :         PART_REL_SEGMENT_EXTRA = 0x400,
     875             :         PART_URIC = 0x800,
     876             :         PART_HTTP_PATH = 0x1000,
     877             :         PART_FILE_SEGMENT_EXTRA = 0x2000, // Obsolete, do not use!
     878             :         PART_MESSAGE_ID = 0x4000,
     879             :         PART_MESSAGE_ID_PATH = 0x8000,
     880             :         PART_MAILTO = 0x10000,
     881             :         PART_PATH_BEFORE_QUERY = 0x20000,
     882             :         PART_PCHAR = 0x40000,
     883             :         PART_FRAGMENT = 0x80000, // Obsolete, do not use!
     884             :         PART_VISIBLE = 0x100000,
     885             :         PART_VISIBLE_NONSPECIAL = 0x200000,
     886             :         PART_CREATEFRAGMENT = 0x400000,
     887             :         PART_UNO_PARAM_VALUE = 0x800000,
     888             :         PART_UNAMBIGUOUS = 0x1000000,
     889             :         PART_URIC_NO_SLASH = 0x2000000,
     890             :         PART_HTTP_QUERY = 0x4000000, //TODO! unused?
     891             :         PART_NEWS_ARTICLE_LOCALPART = 0x8000000,
     892             :         max_part = 0x80000000
     893             :             // Do not use!  Only there to allow compatible changes in the
     894             :             // future.
     895             :     };
     896             : 
     897             :     enum EscapeType
     898             :     {
     899             :         ESCAPE_NO,
     900             :         ESCAPE_OCTET,
     901             :         ESCAPE_UTF32
     902             :     };
     903             : 
     904             :     /** Encode some text as part of a URI.
     905             : 
     906             :         @param rText  Some text (for its interpretation, see the general
     907             :         discussion for set-methods).
     908             : 
     909             :         @param ePart  The part says which characters are 'forbidden' and must
     910             :         be encoded (replaced by escape sequences).  Characters outside the US-
     911             :         ASCII range are always 'forbidden.'
     912             : 
     913             :         @param cEscapePrefix  The first character in an escape sequence
     914             :         (normally '%').
     915             : 
     916             :         @param eMechanism  See the general discussion for set-methods.
     917             : 
     918             :         @param eCharset  See the general discussion for set-methods.
     919             : 
     920             :         @return  The text, encoded according to the given mechanism and
     921             :         charset ('forbidden' characters replaced by escape sequences).
     922             :      */
     923             :     static inline OUString encode(OUString const & rText, Part ePart,
     924             :                                    sal_Char cEscapePrefix,
     925             :                                    EncodeMechanism eMechanism,
     926             :                                    rtl_TextEncoding eCharset
     927             :                                        = RTL_TEXTENCODING_UTF8);
     928             : 
     929             :     /** Decode some text.
     930             : 
     931             :         @param rText  Some (encoded) text.
     932             : 
     933             :         @param cEscapePrefix  The first character in an escape sequence
     934             :         (normally '%').
     935             : 
     936             :         @param eMechanism  See the general discussion for get-methods.
     937             : 
     938             :         @param eCharset  See the general discussion for get-methods.
     939             : 
     940             :         @return  The text, decoded according to the given mechanism and
     941             :         charset (escape sequences replaced by 'raw' characters).
     942             :      */
     943             :     static inline OUString decode(OUString const & rText,
     944             :                                    sal_Char cEscapePrefix,
     945             :                                    DecodeMechanism eMechanism,
     946             :                                    rtl_TextEncoding eCharset
     947             :                                        = RTL_TEXTENCODING_UTF8);
     948             : 
     949             :     static inline OUString decode(OUStringBuffer const & rText,
     950             :                                    sal_Char cEscapePrefix,
     951             :                                    DecodeMechanism eMechanism,
     952             :                                    rtl_TextEncoding eCharset
     953             :                                        = RTL_TEXTENCODING_UTF8);
     954             : 
     955             :     static void appendUCS4Escape(OUStringBuffer & rTheText,
     956             :                                  sal_Char cEscapePrefix,
     957             :                                  sal_uInt32 nUCS4);
     958             : 
     959             :     static void appendUCS4(OUStringBuffer & rTheText, sal_uInt32 nUCS4,
     960             :                            EscapeType eEscapeType, bool bOctets, Part ePart,
     961             :                            sal_Char cEscapePrefix, rtl_TextEncoding eCharset,
     962             :                            bool bKeepVisibleEscapes);
     963             : 
     964             :     static sal_uInt32 getUTF32(sal_Unicode const *& rBegin,
     965             :                                sal_Unicode const * pEnd, bool bOctets,
     966             :                                sal_Char cEscapePrefix,
     967             :                                EncodeMechanism eMechanism,
     968             :                                rtl_TextEncoding eCharset,
     969             :                                EscapeType & rEscapeType);
     970             : 
     971             :     // Specialized helpers:
     972             : 
     973             :     static sal_uInt32 scanDomain(sal_Unicode const *& rBegin,
     974             :                                  sal_Unicode const * pEnd,
     975             :                                  bool bEager = true);
     976             : 
     977             :     // OBSOLETE Hierarchical Path:
     978             : 
     979             :     OUString GetPartBeforeLastName(DecodeMechanism eMechanism
     980             :                                         = DECODE_TO_IURI,
     981             :                                     rtl_TextEncoding eCharset
     982             :                                         = RTL_TEXTENCODING_UTF8) const;
     983             : 
     984             :     /** Get the last segment in the path.
     985             : 
     986             :         @param eMechanism  See the general discussion for get-methods.
     987             : 
     988             :         @param eCharset  See the general discussion for get-methods.
     989             : 
     990             :         @return  For a hierarchical URL, the last segment (everything after
     991             :         the last unencoded '/').  Not that this last segment may be empty.  If
     992             :         the URL is not hierarchical, an empty string is returned.
     993             :      */
     994             :     OUString GetLastName(DecodeMechanism eMechanism = DECODE_TO_IURI,
     995             :                           rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
     996             :         const;
     997             : 
     998             :     /** Get the 'extension' of the last segment in the path.
     999             : 
    1000             :         @param eMechanism  See the general discussion for get-methods.
    1001             : 
    1002             :         @param eCharset  See the general discussion for get-methods.
    1003             : 
    1004             :         @return  For a hierarchical URL, everything after the first unencoded
    1005             :         '.' in the last segment of the path.  Note that this 'extension' may
    1006             :         be empty.  If the URL is not hierarchical, or if the last segment does
    1007             :         not contain an unencoded '.', an empty string is returned.
    1008             :      */
    1009             :     OUString GetFileExtension(DecodeMechanism eMechanism = DECODE_TO_IURI,
    1010             :                                rtl_TextEncoding eCharset
    1011             :                                    = RTL_TEXTENCODING_UTF8) const;
    1012             : 
    1013       11438 :     inline bool Append(OUString const & rTheSegment,
    1014             :                        EncodeMechanism eMechanism = WAS_ENCODED,
    1015             :                        rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
    1016       11438 :     { return appendSegment(rTheSegment, false, eMechanism, eCharset); }
    1017             : 
    1018             :     bool CutLastName();
    1019             : 
    1020             :     // OBSOLETE File URLs:
    1021             : 
    1022             :     OUString PathToFileName() const;
    1023             : 
    1024             :     OUString GetFull() const;
    1025             : 
    1026             :     OUString GetPath() const;
    1027             : 
    1028             :     void SetBase(OUString const & rTheBase);
    1029             : 
    1030             :     OUString GetBase() const;
    1031             : 
    1032             :     void SetName(OUString const & rTheName,
    1033             :                  EncodeMechanism eMechanism = WAS_ENCODED,
    1034             :                  rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
    1035             : 
    1036      258180 :     inline OUString GetName(DecodeMechanism eMechanism = DECODE_TO_IURI,
    1037             :                              rtl_TextEncoding eCharset
    1038             :                                  = RTL_TEXTENCODING_UTF8) const
    1039      258180 :     { return GetLastName(eMechanism, eCharset); }
    1040             : 
    1041             :     void SetExtension(OUString const & rTheExtension,
    1042             :                       EncodeMechanism eMechanism = WAS_ENCODED,
    1043             :                       rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
    1044             : 
    1045          77 :     inline OUString GetExtension(
    1046             :                                   DecodeMechanism eMechanism = DECODE_TO_IURI,
    1047             :                                   rtl_TextEncoding eCharset
    1048             :                                       = RTL_TEXTENCODING_UTF8) const
    1049          77 :     { return GetFileExtension(eMechanism, eCharset); }
    1050             : 
    1051             :     OUString CutExtension(DecodeMechanism eMechanism = DECODE_TO_IURI,
    1052             :                            rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
    1053             : 
    1054             :     bool IsCaseSensitive() const;
    1055             : 
    1056             : 
    1057             : private:
    1058             :     // General Structure:
    1059             : 
    1060             :     class SubString
    1061             :     {
    1062             :         sal_Int32 m_nBegin;
    1063             :         sal_Int32 m_nLength;
    1064             : 
    1065             :     public:
    1066     6437783 :         explicit inline SubString(sal_Int32 nTheBegin = -1,
    1067             :                                   sal_Int32 nTheLength = 0):
    1068     6437783 :             m_nBegin(nTheBegin), m_nLength(nTheLength) {}
    1069             : 
    1070     3169879 :         inline bool isPresent() const { return m_nBegin != -1; }
    1071             : 
    1072      254279 :         inline bool isEmpty() const { return m_nLength == 0; }
    1073             : 
    1074      782330 :         inline sal_Int32 getBegin() const { return m_nBegin; }
    1075             : 
    1076      343273 :         inline sal_Int32 getLength() const { return m_nLength; }
    1077             : 
    1078      443363 :         inline sal_Int32 getEnd() const { return m_nBegin + m_nLength; }
    1079             : 
    1080             :         inline sal_Int32 clear();
    1081             : 
    1082             :         inline sal_Int32 set(OUStringBuffer & rString,
    1083             :                              OUString const & rSubString,
    1084             :                              sal_Int32 nTheBegin);
    1085             : 
    1086             :         inline sal_Int32 set(OUString & rString,
    1087             :                              OUString const & rSubString);
    1088             : 
    1089             :         inline sal_Int32 set(OUStringBuffer & rString,
    1090             :                              OUString const & rSubString);
    1091             : 
    1092             :         inline void operator +=(sal_Int32 nDelta);
    1093             : 
    1094             :         int compare(SubString const & rOther,
    1095             :             OUStringBuffer const & rThisString,
    1096             :             OUStringBuffer const & rOtherString) const;
    1097             :     };
    1098             : 
    1099             :     OUStringBuffer m_aAbsURIRef;
    1100             :     SubString m_aScheme;
    1101             :     SubString m_aUser;
    1102             :     SubString m_aAuth;
    1103             :     SubString m_aHost;
    1104             :     SubString m_aPort;
    1105             :     SubString m_aPath;
    1106             :     SubString m_aQuery;
    1107             :     SubString m_aFragment;
    1108             :     INetProtocol m_eScheme;
    1109             :     INetProtocol m_eSmartScheme;
    1110             : 
    1111             :     TOOLS_DLLPRIVATE void setInvalid();
    1112             : 
    1113             :     bool setAbsURIRef(
    1114             :         OUString const & rTheAbsURIRef, bool bOctets,
    1115             :         EncodeMechanism eMechanism, rtl_TextEncoding eCharset, bool bSmart,
    1116             :         FSysStyle eStyle);
    1117             : 
    1118             :     // Relative URLs:
    1119             : 
    1120             :     bool convertRelToAbs(
    1121             :         OUString const & rTheRelURIRef, bool bOctets,
    1122             :         INetURLObject & rTheAbsURIRef, bool & rWasAbsolute,
    1123             :         EncodeMechanism eMechanism, rtl_TextEncoding eCharset,
    1124             :         bool bIgnoreFragment, bool bSmart, bool bRelativeNonURIs,
    1125             :         FSysStyle eStyle) const;
    1126             : 
    1127             :     bool convertAbsToRel(
    1128             :         OUString const & rTheAbsURIRef, bool bOctets,
    1129             :         OUString & rTheRelURIRef, EncodeMechanism eEncodeMechanism,
    1130             :         DecodeMechanism eDecodeMechanism, rtl_TextEncoding eCharset,
    1131             :         FSysStyle eStyle) const;
    1132             : 
    1133             :     // External URLs:
    1134             : 
    1135             :     static bool convertIntToExt(
    1136             :         OUString const & rTheIntURIRef, bool bOctets,
    1137             :         OUString & rTheExtURIRef, DecodeMechanism eDecodeMechanism,
    1138             :         rtl_TextEncoding eCharset);
    1139             : 
    1140             :     static bool convertExtToInt(
    1141             :         OUString const & rTheExtURIRef, bool bOctets,
    1142             :         OUString & rTheIntURIRef, DecodeMechanism eDecodeMechanism,
    1143             :         rtl_TextEncoding eCharset);
    1144             : 
    1145             :     // Scheme:
    1146             : 
    1147             :     struct PrefixInfo;
    1148             : 
    1149             :     TOOLS_DLLPRIVATE static inline SchemeInfo const & getSchemeInfo(
    1150             :         INetProtocol eTheScheme);
    1151             : 
    1152             :     TOOLS_DLLPRIVATE inline SchemeInfo const & getSchemeInfo() const;
    1153             : 
    1154             :     TOOLS_DLLPRIVATE static PrefixInfo const * getPrefix(
    1155             :         sal_Unicode const *& rBegin, sal_Unicode const * pEnd);
    1156             : 
    1157             :     // Authority:
    1158             : 
    1159             :     TOOLS_DLLPRIVATE sal_Int32 getAuthorityBegin() const;
    1160             : 
    1161             :     TOOLS_DLLPRIVATE SubString getAuthority() const;
    1162             : 
    1163             :     // User Info:
    1164             : 
    1165             :     bool setUser(
    1166             :         OUString const & rTheUser, bool bOctets,
    1167             :         EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
    1168             : 
    1169             :     bool clearPassword();
    1170             : 
    1171             :     bool setPassword(
    1172             :         OUString const & rThePassword, bool bOctets,
    1173             :         EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
    1174             : 
    1175             :     // Host and Port:
    1176             : 
    1177             :     TOOLS_DLLPRIVATE static bool parseHost(
    1178             :         sal_Unicode const *& rBegin, sal_Unicode const * pEnd,
    1179             :         OUString & rCanonic);
    1180             : 
    1181             :     TOOLS_DLLPRIVATE static bool parseHostOrNetBiosName(
    1182             :         sal_Unicode const * pBegin, sal_Unicode const * pEnd, bool bOctets,
    1183             :         EncodeMechanism eMechanism, rtl_TextEncoding eCharset,
    1184             :         bool bNetBiosName, OUStringBuffer* pCanonic);
    1185             : 
    1186             :     bool setHost(
    1187             :         OUString const & rTheHost, bool bOctets,
    1188             :         EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
    1189             : 
    1190             :     // Path:
    1191             : 
    1192             :     TOOLS_DLLPRIVATE static bool parsePath(
    1193             :         INetProtocol eScheme, sal_Unicode const ** pBegin,
    1194             :         sal_Unicode const * pEnd, bool bOctets, EncodeMechanism eMechanism,
    1195             :         rtl_TextEncoding eCharset, bool bSkippedInitialSlash,
    1196             :         sal_uInt32 nSegmentDelimiter, sal_uInt32 nAltSegmentDelimiter,
    1197             :         sal_uInt32 nQueryDelimiter, sal_uInt32 nFragmentDelimiter,
    1198             :         OUStringBuffer &rSynPath);
    1199             : 
    1200             :     bool setPath(
    1201             :         OUString const & rThePath, bool bOctets,
    1202             :         EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
    1203             : 
    1204             :     // Hierarchical Path:
    1205             : 
    1206             :     TOOLS_DLLPRIVATE bool checkHierarchical() const;
    1207             : 
    1208             :     bool appendSegment(
    1209             :         OUString const & rTheSegment, bool bOctets,
    1210             :         EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
    1211             : 
    1212             :     TOOLS_DLLPRIVATE SubString getSegment(
    1213             :         sal_Int32 nIndex, bool bIgnoreFinalSlash) const;
    1214             : 
    1215             :     bool insertName(
    1216             :         OUString const & rTheName, bool bOctets, bool bAppendFinalSlash,
    1217             :         sal_Int32 nIndex, bool bIgnoreFinalSlash, EncodeMechanism eMechanism,
    1218             :         rtl_TextEncoding eCharset);
    1219             : 
    1220             :     // Query:
    1221             : 
    1222             :     bool clearQuery();
    1223             : 
    1224             :     bool setQuery(
    1225             :         OUString const & rTheQuery, bool bOctets,
    1226             :         EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
    1227             : 
    1228             :     // Fragment:
    1229             : 
    1230             :     bool clearFragment();
    1231             : 
    1232             :     bool setFragment(
    1233             :         OUString const & rTheMark, bool bOctets,
    1234             :         EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
    1235             : 
    1236             :     // FILE URLs:
    1237             : 
    1238             :     TOOLS_DLLPRIVATE bool hasDosVolume(FSysStyle eStyle) const;
    1239             : 
    1240             :     // Coding:
    1241             : 
    1242     3297093 :     static inline sal_Char getEscapePrefix(INetProtocol eTheScheme)
    1243     3297093 :     { return eTheScheme == INET_PROT_VIM ? '=' : '%'; }
    1244             : 
    1245     3297093 :     inline sal_Char getEscapePrefix() const
    1246     3297093 :     { return getEscapePrefix(m_eScheme); }
    1247             : 
    1248             :     TOOLS_DLLPRIVATE static inline void appendEscape(
    1249             :         OUStringBuffer & rTheText, sal_Char cEscapePrefix,
    1250             :         sal_uInt32 nOctet);
    1251             : 
    1252             :     static OUString encodeText(
    1253             :         sal_Unicode const * pBegin, sal_Unicode const * pEnd, bool bOctets,
    1254             :         Part ePart, sal_Char cEscapePrefix, EncodeMechanism eMechanism,
    1255             :         rtl_TextEncoding eCharset, bool bKeepVisibleEscapes);
    1256             : 
    1257             :     static inline OUString encodeText(
    1258             :         OUString const & rTheText, bool bOctets, Part ePart,
    1259             :         sal_Char cEscapePrefix, EncodeMechanism eMechanism,
    1260             :         rtl_TextEncoding eCharset, bool bKeepVisibleEscapes);
    1261             : 
    1262             :     static OUString decode(
    1263             :         sal_Unicode const * pBegin, sal_Unicode const * pEnd,
    1264             :         sal_Char cEscapePrefix, DecodeMechanism, rtl_TextEncoding eCharset);
    1265             : 
    1266             :     inline OUString decode(
    1267             :         SubString const & rSubString, sal_Char cEscapePrefix,
    1268             :         DecodeMechanism eMechanism, rtl_TextEncoding eCharset) const;
    1269             : 
    1270             :     // Specialized helpers:
    1271             : 
    1272             :     TOOLS_DLLPRIVATE static bool scanIPv6reference(
    1273             :         sal_Unicode const *& rBegin, sal_Unicode const * pEnd);
    1274             : 
    1275             : private:
    1276             :     void changeScheme(INetProtocol eTargetScheme);
    1277             : };
    1278             : 
    1279             : // static
    1280       16965 : inline OUString INetURLObject::encodeText(OUString const & rTheText,
    1281             :                                            bool bOctets, Part ePart,
    1282             :                                            sal_Char cEscapePrefix,
    1283             :                                            EncodeMechanism eMechanism,
    1284             :                                            rtl_TextEncoding eCharset,
    1285             :                                            bool bKeepVisibleEscapes)
    1286             : {
    1287             :     return encodeText(rTheText.getStr(),
    1288       16965 :                       rTheText.getStr() + rTheText.getLength(), bOctets, ePart,
    1289             :                       cEscapePrefix, eMechanism, eCharset,
    1290       33930 :                       bKeepVisibleEscapes);
    1291             : }
    1292             : 
    1293     1821334 : inline OUString INetURLObject::decode(SubString const & rSubString,
    1294             :                                        sal_Char cEscapePrefix,
    1295             :                                        DecodeMechanism eMechanism,
    1296             :                                        rtl_TextEncoding eCharset) const
    1297             : {
    1298     1821334 :     return rSubString.isPresent() ?
    1299      415686 :                decode(m_aAbsURIRef.getStr() + rSubString.getBegin(),
    1300      415686 :                       m_aAbsURIRef.getStr() + rSubString.getEnd(),
    1301             :                       cEscapePrefix, eMechanism, eCharset) :
    1302     2652707 :                OUString();
    1303             : }
    1304             : 
    1305      649655 : inline INetURLObject::INetURLObject(OUString const & rTheAbsURIRef,
    1306             :                                     EncodeMechanism eMechanism,
    1307             :                                     rtl_TextEncoding eCharset):
    1308      649655 :     m_eScheme(INET_PROT_NOT_VALID), m_eSmartScheme(INET_PROT_HTTP)
    1309             : {
    1310             :     setAbsURIRef(rTheAbsURIRef, false, eMechanism, eCharset, false,
    1311      649655 :                  FSysStyle(0));
    1312      649655 : }
    1313             : 
    1314        2519 : inline bool INetURLObject::SetURL(OUString const & rTheAbsURIRef,
    1315             :                                   EncodeMechanism eMechanism,
    1316             :                                   rtl_TextEncoding eCharset)
    1317             : {
    1318             :     return setAbsURIRef(rTheAbsURIRef, false, eMechanism, eCharset, false,
    1319        2519 :                         FSysStyle(0));
    1320             : }
    1321             : 
    1322       16543 : inline INetURLObject::INetURLObject(OUString const & rTheAbsURIRef,
    1323             :                                     INetProtocol eTheSmartScheme,
    1324             :                                     EncodeMechanism eMechanism,
    1325             :                                     rtl_TextEncoding eCharset,
    1326             :                                     FSysStyle eStyle):
    1327       16543 :     m_eScheme(INET_PROT_NOT_VALID), m_eSmartScheme(eTheSmartScheme)
    1328             : {
    1329       16543 :     setAbsURIRef(rTheAbsURIRef, false, eMechanism, eCharset, true, eStyle);
    1330       16543 : }
    1331             : 
    1332        1040 : inline bool INetURLObject::SetSmartURL(OUString const & rTheAbsURIRef,
    1333             :                                        EncodeMechanism eMechanism,
    1334             :                                        rtl_TextEncoding eCharset,
    1335             :                                        FSysStyle eStyle)
    1336             : {
    1337             :     return setAbsURIRef(rTheAbsURIRef, false, eMechanism, eCharset, true,
    1338        1040 :                         eStyle);
    1339             : }
    1340             : 
    1341             : inline INetURLObject
    1342          95 : INetURLObject::smartRel2Abs(OUString const & rTheRelURIRef,
    1343             :                             bool & rWasAbsolute,
    1344             :                             bool bIgnoreFragment,
    1345             :                             EncodeMechanism eMechanism,
    1346             :                             rtl_TextEncoding eCharset,
    1347             :                             bool bRelativeNonURIs,
    1348             :                             FSysStyle eStyle) const
    1349             : {
    1350          95 :     INetURLObject aTheAbsURIRef;
    1351             :     convertRelToAbs(rTheRelURIRef, false, aTheAbsURIRef, rWasAbsolute,
    1352             :                     eMechanism, eCharset, bIgnoreFragment, true,
    1353          95 :                     bRelativeNonURIs, eStyle);
    1354          95 :     return aTheAbsURIRef;
    1355             : }
    1356             : 
    1357          92 : inline bool INetURLObject::GetNewAbsURL(OUString const & rTheRelURIRef,
    1358             :                                         INetURLObject * pTheAbsURIRef,
    1359             :                                         EncodeMechanism eMechanism,
    1360             :                                         rtl_TextEncoding eCharset,
    1361             :                                         FSysStyle eStyle, bool bIgnoreFragment)
    1362             :     const
    1363             : {
    1364          92 :     INetURLObject aTheAbsURIRef;
    1365             :     bool bWasAbsolute;
    1366          92 :     if (!convertRelToAbs(rTheRelURIRef, false, aTheAbsURIRef, bWasAbsolute,
    1367             :                          eMechanism, eCharset, bIgnoreFragment, false, false,
    1368          92 :                          eStyle))
    1369           0 :         return false;
    1370          92 :     if (pTheAbsURIRef)
    1371          92 :         *pTheAbsURIRef = aTheAbsURIRef;
    1372          92 :     return true;
    1373             : }
    1374             : 
    1375             : // static
    1376          87 : inline OUString INetURLObject::GetRelURL(OUString const & rTheBaseURIRef,
    1377             :                                           OUString const & rTheAbsURIRef,
    1378             :                                           EncodeMechanism eEncodeMechanism,
    1379             :                                           DecodeMechanism eDecodeMechanism,
    1380             :                                           rtl_TextEncoding eCharset,
    1381             :                                           FSysStyle eStyle)
    1382             : {
    1383          87 :     OUString aTheRelURIRef;
    1384             :     INetURLObject(rTheBaseURIRef, eEncodeMechanism, eCharset).
    1385             :         convertAbsToRel(rTheAbsURIRef, false, aTheRelURIRef, eEncodeMechanism,
    1386          87 :                         eDecodeMechanism, eCharset, eStyle);
    1387          87 :     return aTheRelURIRef;
    1388             : }
    1389             : 
    1390             : // static
    1391           0 : inline bool INetURLObject::translateToExternal(OUString const &
    1392             :                                                    rTheIntURIRef,
    1393             :                                                OUString & rTheExtURIRef,
    1394             :                                                DecodeMechanism
    1395             :                                                    eDecodeMechanism,
    1396             :                                                rtl_TextEncoding eCharset)
    1397             : {
    1398             :     return convertIntToExt(rTheIntURIRef, false, rTheExtURIRef,
    1399           0 :                            eDecodeMechanism, eCharset);
    1400             : }
    1401             : 
    1402             : // static
    1403           0 : inline bool INetURLObject::translateToInternal(OUString const &
    1404             :                                                    rTheExtURIRef,
    1405             :                                                OUString & rTheIntURIRef,
    1406             :                                                DecodeMechanism
    1407             :                                                    eDecodeMechanism,
    1408             :                                                rtl_TextEncoding eCharset)
    1409             : {
    1410             :     return convertExtToInt(rTheExtURIRef, false, rTheIntURIRef,
    1411           0 :                            eDecodeMechanism, eCharset);
    1412             : }
    1413             : 
    1414           0 : inline bool INetURLObject::SetPass(OUString const & rThePassword,
    1415             :                                    EncodeMechanism eMechanism,
    1416             :                                    rtl_TextEncoding eCharset)
    1417             : {
    1418           0 :     return rThePassword.isEmpty() ?
    1419             :                clearPassword() :
    1420           0 :                setPassword(rThePassword, false, eMechanism, eCharset);
    1421             : }
    1422             : 
    1423           0 : inline bool INetURLObject::SetUserAndPass(OUString const & rTheUser,
    1424             :                                           OUString const & rThePassword,
    1425             :                                           EncodeMechanism eMechanism,
    1426             :                                           rtl_TextEncoding eCharset)
    1427             : {
    1428           0 :     return setUser(rTheUser, false, eMechanism, eCharset)
    1429           0 :            && (rThePassword.isEmpty() ?
    1430           0 :                    clearPassword() :
    1431           0 :                    setPassword(rThePassword, false, eMechanism, eCharset));
    1432             : }
    1433             : 
    1434        2303 : inline bool INetURLObject::insertName(OUString const & rTheName,
    1435             :                                       bool bAppendFinalSlash,
    1436             :                                       sal_Int32 nIndex,
    1437             :                                       bool bIgnoreFinalSlash,
    1438             :                                       EncodeMechanism eMechanism,
    1439             :                                       rtl_TextEncoding eCharset)
    1440             : {
    1441             :     return insertName(rTheName, false, bAppendFinalSlash, nIndex,
    1442        2303 :                       bIgnoreFinalSlash, eMechanism, eCharset);
    1443             : }
    1444             : 
    1445      262023 : inline bool INetURLObject::SetParam(OUString const & rTheQuery,
    1446             :                                     EncodeMechanism eMechanism,
    1447             :                                     rtl_TextEncoding eCharset)
    1448             : {
    1449      262023 :     return rTheQuery.isEmpty() ?
    1450             :                clearQuery() :
    1451      262023 :                setQuery(rTheQuery, false, eMechanism, eCharset);
    1452             : }
    1453             : 
    1454      267856 : inline bool INetURLObject::SetMark(OUString const & rTheFragment,
    1455             :                                    EncodeMechanism eMechanism,
    1456             :                                    rtl_TextEncoding eCharset)
    1457             : {
    1458      267856 :     return rTheFragment.isEmpty() ?
    1459             :                clearFragment() :
    1460      267856 :                setFragment(rTheFragment, false, eMechanism, eCharset);
    1461             : }
    1462             : 
    1463           0 : inline INetURLObject::INetURLObject(OUString const & rFSysPath,
    1464             :                                     FSysStyle eStyle):
    1465           0 :     m_eScheme(INET_PROT_NOT_VALID), m_eSmartScheme(INET_PROT_HTTP)
    1466             : {
    1467           0 :     setFSysPath(rFSysPath, eStyle);
    1468           0 : }
    1469             : 
    1470             : // static
    1471        1327 : inline OUString INetURLObject::encode(OUString const & rText, Part ePart,
    1472             :                                        sal_Char cEscapePrefix,
    1473             :                                        EncodeMechanism eMechanism,
    1474             :                                        rtl_TextEncoding eCharset)
    1475             : {
    1476             :     return encodeText(rText, false, ePart, cEscapePrefix, eMechanism,
    1477        1327 :                       eCharset, false);
    1478             : }
    1479             : 
    1480             : // static
    1481         221 : inline OUString INetURLObject::decode(OUString const & rText,
    1482             :                                        sal_Char cEscapePrefix,
    1483             :                                        DecodeMechanism eMechanism,
    1484             :                                        rtl_TextEncoding eCharset)
    1485             : {
    1486         221 :     return decode(rText.getStr(), rText.getStr() + rText.getLength(),
    1487         442 :                   cEscapePrefix, eMechanism, eCharset);
    1488             : }
    1489             : 
    1490      645169 : inline OUString INetURLObject::decode(OUStringBuffer const & rText,
    1491             :                                        sal_Char cEscapePrefix,
    1492             :                                        DecodeMechanism eMechanism,
    1493             :                                        rtl_TextEncoding eCharset)
    1494             : {
    1495      645169 :     return decode(rText.getStr(), rText.getStr() + rText.getLength(),
    1496     1290338 :                   cEscapePrefix, eMechanism, eCharset);
    1497             : }
    1498             : 
    1499             : #endif
    1500             : 
    1501             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10