LCOV - code coverage report
Current view: directory - netwerk/base/src - nsStandardURL.h (source / functions) Found Hit Coverage
Test: app.info Lines: 77 62 80.5 %
Date: 2012-06-02 Functions: 36 31 86.1 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Darin Fisher <darin@netscape.com> (original author)
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #ifndef nsStandardURL_h__
      40                 : #define nsStandardURL_h__
      41                 : 
      42                 : #include "nsString.h"
      43                 : #include "nsDependentString.h"
      44                 : #include "nsDependentSubstring.h"
      45                 : #include "nsISerializable.h"
      46                 : #include "nsIIPCSerializable.h"
      47                 : #include "nsIFileURL.h"
      48                 : #include "nsIStandardURL.h"
      49                 : #include "nsIFile.h"
      50                 : #include "nsIURLParser.h"
      51                 : #include "nsIUnicodeEncoder.h"
      52                 : #include "nsIObserver.h"
      53                 : #include "nsIIOService.h"
      54                 : #include "nsCOMPtr.h"
      55                 : #include "nsURLHelper.h"
      56                 : #include "nsIClassInfo.h"
      57                 : #include "nsISizeOf.h"
      58                 : #include "prclist.h"
      59                 : 
      60                 : #ifdef NS_BUILD_REFCNT_LOGGING
      61                 : #define DEBUG_DUMP_URLS_AT_SHUTDOWN
      62                 : #endif
      63                 : 
      64                 : class nsIBinaryInputStream;
      65                 : class nsIBinaryOutputStream;
      66                 : class nsIIDNService;
      67                 : class nsICharsetConverterManager;
      68                 : class nsIPrefBranch;
      69                 : 
      70                 : //-----------------------------------------------------------------------------
      71                 : // standard URL implementation
      72                 : //-----------------------------------------------------------------------------
      73                 : 
      74                 : class nsStandardURL : public nsIFileURL
      75                 :                     , public nsIStandardURL
      76                 :                     , public nsISerializable
      77                 :                     , public nsIIPCSerializable
      78                 :                     , public nsIClassInfo
      79                 :                     , public nsISizeOf
      80                 : {
      81                 : public:
      82                 :     NS_DECL_ISUPPORTS
      83                 :     NS_DECL_NSIURI
      84                 :     NS_DECL_NSIURL
      85                 :     NS_DECL_NSIFILEURL
      86                 :     NS_DECL_NSISTANDARDURL
      87                 :     NS_DECL_NSISERIALIZABLE
      88                 :     NS_DECL_NSIIPCSERIALIZABLE
      89                 :     NS_DECL_NSICLASSINFO
      90                 :     NS_DECL_NSIMUTABLE
      91                 : 
      92                 :     // nsISizeOf
      93                 :     virtual size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
      94                 :     virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
      95                 : 
      96                 :     nsStandardURL(bool aSupportsFileURL = false);
      97                 :     virtual ~nsStandardURL();
      98                 : 
      99                 :     static void InitGlobalObjects();
     100                 :     static void ShutdownGlobalObjects();
     101                 : 
     102                 : public: /* internal -- HPUX compiler can't handle this being private */
     103                 :     //
     104                 :     // location and length of an url segment relative to mSpec
     105                 :     //
     106                 :     struct URLSegment
     107                 :     {
     108                 :         PRUint32 mPos;
     109                 :         PRInt32  mLen;
     110                 : 
     111         3590554 :         URLSegment() : mPos(0), mLen(-1) {}
     112            1336 :         URLSegment(PRUint32 pos, PRInt32 len) : mPos(pos), mLen(len) {}
     113         3204762 :         void Reset() { mPos = 0; mLen = -1; }
     114                 :         // Merge another segment following this one to it if they're contiguous
     115                 :         // Assumes we have something like "foo;bar" where this object is 'foo' and right
     116                 :         // is 'bar'.
     117               0 :         void Merge(const nsCString &spec, const char separator, const URLSegment &right) {
     118               0 :             if (mLen >= 0 && 
     119               0 :                 *(spec.get() + mPos + mLen) == separator &&
     120                 :                 mPos + mLen + 1 == right.mPos) {
     121               0 :                 mLen += 1 + right.mLen;
     122                 :             }
     123               0 :         }
     124                 :     };
     125                 : 
     126                 :     //
     127                 :     // Pref observer
     128                 :     //
     129                 :     class nsPrefObserver : public nsIObserver
     130                 :     {
     131                 :     public:
     132                 :         NS_DECL_ISUPPORTS
     133                 :         NS_DECL_NSIOBSERVER
     134                 : 
     135            1419 :         nsPrefObserver() { }
     136                 :     };
     137                 :     friend class nsPrefObserver;
     138                 : 
     139                 :     //
     140                 :     // URL segment encoder : performs charset conversion and URL escaping.
     141                 :     //
     142                 :     class nsSegmentEncoder
     143          583931 :     {
     144                 :     public:
     145                 :         nsSegmentEncoder(const char *charset);
     146                 : 
     147                 :         // Encode the given segment if necessary, and return the length of
     148                 :         // the encoded segment.  The encoded segment is appended to |buf|
     149                 :         // if and only if encoding is required.
     150                 :         PRInt32 EncodeSegmentCount(const char *str,
     151                 :                                    const URLSegment &segment,
     152                 :                                    PRInt16 mask,
     153                 :                                    nsAFlatCString &buf,
     154                 :                                    bool& appended,
     155                 :                                    PRUint32 extraLen = 0);
     156                 :          
     157                 :         // Encode the given string if necessary, and return a reference to
     158                 :         // the encoded string.  Returns a reference to |buf| if encoding
     159                 :         // is required.  Otherwise, a reference to |str| is returned.
     160                 :         const nsACString &EncodeSegment(const nsASingleFragmentCString &str,
     161                 :                                         PRInt16 mask,
     162                 :                                         nsAFlatCString &buf);
     163                 :     private:
     164                 :         bool InitUnicodeEncoder();
     165                 :         
     166                 :         const char* mCharset;  // Caller should keep this alive for
     167                 :                                // the life of the segment encoder
     168                 :         nsCOMPtr<nsIUnicodeEncoder> mEncoder;
     169                 :     };
     170                 :     friend class nsSegmentEncoder;
     171                 : 
     172                 : protected:
     173                 :     // enum used in a few places to specify how .ref attribute should be handled
     174                 :     enum RefHandlingEnum {
     175                 :         eIgnoreRef,
     176                 :         eHonorRef
     177                 :     };
     178                 : 
     179                 :     // Helper to share code between Equals and EqualsExceptRef
     180                 :     // NOTE: *not* virtual, because no one needs to override this so far...
     181                 :     nsresult EqualsInternal(nsIURI* unknownOther,
     182                 :                             RefHandlingEnum refHandlingMode,
     183                 :                             bool* result);
     184                 : 
     185                 :     virtual nsStandardURL* StartClone();
     186                 : 
     187                 :     // Helper to share code between Clone methods.
     188                 :     nsresult CloneInternal(RefHandlingEnum aRefHandlingMode,
     189                 :                            nsIURI** aClone);
     190                 : 
     191                 :     // Helper for subclass implementation of GetFile().  Subclasses that map
     192                 :     // URIs to files in a special way should implement this method.  It should
     193                 :     // ensure that our mFile is initialized, if it's possible.
     194                 :     // returns NS_ERROR_NO_INTERFACE if the url does not map to a file
     195                 :     virtual nsresult EnsureFile();
     196                 : 
     197                 : private:
     198           42604 :     PRInt32  Port() { return mPort == -1 ? mDefaultPort : mPort; }
     199                 : 
     200                 :     void     Clear();
     201                 :     void     InvalidateCache(bool invalidateCachedFile = true);
     202                 : 
     203                 :     bool     EscapeIPv6(const char *host, nsCString &result);
     204                 :     bool     NormalizeIDN(const nsCSubstring &host, nsCString &result);
     205                 :     void     CoalescePath(netCoalesceFlags coalesceFlag, char *path);
     206                 : 
     207                 :     PRUint32 AppendSegmentToBuf(char *, PRUint32, const char *, URLSegment &, const nsCString *esc=nsnull, bool useEsc = false);
     208                 :     PRUint32 AppendToBuf(char *, PRUint32, const char *, PRUint32);
     209                 : 
     210                 :     nsresult BuildNormalizedSpec(const char *spec);
     211                 : 
     212                 :     bool     SegmentIs(const URLSegment &s1, const char *val, bool ignoreCase = false);
     213                 :     bool     SegmentIs(const char* spec, const URLSegment &s1, const char *val, bool ignoreCase = false);
     214                 :     bool     SegmentIs(const URLSegment &s1, const char *val, const URLSegment &s2, bool ignoreCase = false);
     215                 : 
     216                 :     PRInt32  ReplaceSegment(PRUint32 pos, PRUint32 len, const char *val, PRUint32 valLen);
     217                 :     PRInt32  ReplaceSegment(PRUint32 pos, PRUint32 len, const nsACString &val);
     218                 : 
     219                 :     nsresult ParseURL(const char *spec, PRInt32 specLen);
     220                 :     nsresult ParsePath(const char *spec, PRUint32 pathPos, PRInt32 pathLen = -1);
     221                 : 
     222                 :     char    *AppendToSubstring(PRUint32 pos, PRInt32 len, const char *tail);
     223                 : 
     224                 :     // dependent substring helpers
     225                 :     const nsDependentCSubstring Segment(PRUint32 pos, PRInt32 len); // see below
     226          459765 :     const nsDependentCSubstring Segment(const URLSegment &s) { return Segment(s.mPos, s.mLen); }
     227                 : 
     228                 :     // dependent substring getters
     229                 :     const nsDependentCSubstring Prepath();  // see below
     230          301601 :     const nsDependentCSubstring Scheme()    { return Segment(mScheme); }
     231                 :     const nsDependentCSubstring Userpass(bool includeDelim = false); // see below
     232             302 :     const nsDependentCSubstring Username()  { return Segment(mUsername); }
     233             260 :     const nsDependentCSubstring Password()  { return Segment(mPassword); }
     234                 :     const nsDependentCSubstring Hostport(); // see below
     235                 :     const nsDependentCSubstring Host();     // see below
     236          134585 :     const nsDependentCSubstring Path()      { return Segment(mPath); }
     237             770 :     const nsDependentCSubstring Filepath()  { return Segment(mFilepath); }
     238           18941 :     const nsDependentCSubstring Directory() { return Segment(mDirectory); }
     239                 :     const nsDependentCSubstring Filename(); // see below
     240             222 :     const nsDependentCSubstring Basename()  { return Segment(mBasename); }
     241            1358 :     const nsDependentCSubstring Extension() { return Segment(mExtension); }
     242             472 :     const nsDependentCSubstring Query()     { return Segment(mQuery); }
     243            1253 :     const nsDependentCSubstring Ref()       { return Segment(mRef); }
     244                 : 
     245                 :     // shift the URLSegments to the right by diff
     246               0 :     void ShiftFromAuthority(PRInt32 diff) { mAuthority.mPos += diff; ShiftFromUsername(diff); }
     247               0 :     void ShiftFromUsername(PRInt32 diff)  { mUsername.mPos += diff; ShiftFromPassword(diff); }
     248               0 :     void ShiftFromPassword(PRInt32 diff)  { mPassword.mPos += diff; ShiftFromHost(diff); }
     249               0 :     void ShiftFromHost(PRInt32 diff)      { mHost.mPos += diff; ShiftFromPath(diff); }
     250               7 :     void ShiftFromPath(PRInt32 diff)      { mPath.mPos += diff; ShiftFromFilepath(diff); }
     251               7 :     void ShiftFromFilepath(PRInt32 diff)  { mFilepath.mPos += diff; ShiftFromDirectory(diff); }
     252               7 :     void ShiftFromDirectory(PRInt32 diff) { mDirectory.mPos += diff; ShiftFromBasename(diff); }
     253              19 :     void ShiftFromBasename(PRInt32 diff)  { mBasename.mPos += diff; ShiftFromExtension(diff); }
     254              19 :     void ShiftFromExtension(PRInt32 diff) { mExtension.mPos += diff; ShiftFromQuery(diff); }
     255              19 :     void ShiftFromQuery(PRInt32 diff)     { mQuery.mPos += diff; ShiftFromRef(diff); }
     256             413 :     void ShiftFromRef(PRInt32 diff)       { mRef.mPos += diff; }
     257                 : 
     258                 :     // fastload helper functions
     259                 :     nsresult ReadSegment(nsIBinaryInputStream *, URLSegment &);
     260                 :     nsresult WriteSegment(nsIBinaryOutputStream *, const URLSegment &);
     261                 : 
     262                 :     // ipc helper functions
     263                 :     bool ReadSegment(const IPC::Message *, void **, URLSegment &);
     264                 :     void WriteSegment(IPC::Message *, const URLSegment &);
     265                 : 
     266                 :     static void PrefsChanged(nsIPrefBranch *prefs, const char *pref);
     267                 : 
     268                 :     // mSpec contains the normalized version of the URL spec (UTF-8 encoded).
     269                 :     nsCString mSpec;
     270                 :     PRInt32   mDefaultPort;
     271                 :     PRInt32   mPort;
     272                 : 
     273                 :     // url parts (relative to mSpec)
     274                 :     URLSegment mScheme;
     275                 :     URLSegment mAuthority;
     276                 :     URLSegment mUsername;
     277                 :     URLSegment mPassword;
     278                 :     URLSegment mHost;
     279                 :     URLSegment mPath;
     280                 :     URLSegment mFilepath;
     281                 :     URLSegment mDirectory;
     282                 :     URLSegment mBasename;
     283                 :     URLSegment mExtension;
     284                 :     URLSegment mQuery;
     285                 :     URLSegment mRef;
     286                 : 
     287                 :     nsCString              mOriginCharset;
     288                 :     nsCOMPtr<nsIURLParser> mParser;
     289                 : 
     290                 :     // mFile is protected so subclasses can access it directly
     291                 : protected:
     292                 :     nsCOMPtr<nsIFile>      mFile;  // cached result for nsIFileURL::GetFile
     293                 :     
     294                 : private:
     295                 :     char                  *mHostA; // cached result for nsIURI::GetHostA
     296                 : 
     297                 :     enum {
     298                 :         eEncoding_Unknown,
     299                 :         eEncoding_ASCII,
     300                 :         eEncoding_UTF8
     301                 :     };
     302                 : 
     303                 :     PRUint32 mHostEncoding    : 2; // eEncoding_xxx
     304                 :     PRUint32 mSpecEncoding    : 2; // eEncoding_xxx
     305                 :     PRUint32 mURLType         : 2; // nsIStandardURL::URLTYPE_xxx
     306                 :     PRUint32 mMutable         : 1; // nsIStandardURL::mutable
     307                 :     PRUint32 mSupportsFileURL : 1; // QI to nsIFileURL?
     308                 : 
     309                 :     // global objects.  don't use COMPtr as its destructor will cause a
     310                 :     // coredump if we leak it.
     311                 :     static nsIIDNService               *gIDN;
     312                 :     static nsICharsetConverterManager  *gCharsetMgr;
     313                 :     static bool                         gInitialized;
     314                 :     static bool                         gEscapeUTF8;
     315                 :     static bool                         gAlwaysEncodeInUTF8;
     316                 :     static bool                         gEncodeQueryInUTF8;
     317                 : 
     318                 : public:
     319                 : #ifdef DEBUG_DUMP_URLS_AT_SHUTDOWN
     320                 :     PRCList mDebugCList;
     321             536 :     void PrintSpec() const { printf("  %s\n", mSpec.get()); }
     322                 : #endif
     323                 : };
     324                 : 
     325                 : #define NS_THIS_STANDARDURL_IMPL_CID                 \
     326                 : { /* b8e3e97b-1ccd-4b45-af5a-79596770f5d7 */         \
     327                 :     0xb8e3e97b,                                      \
     328                 :     0x1ccd,                                          \
     329                 :     0x4b45,                                          \
     330                 :     {0xaf, 0x5a, 0x79, 0x59, 0x67, 0x70, 0xf5, 0xd7} \
     331                 : }
     332                 : 
     333                 : //-----------------------------------------------------------------------------
     334                 : // Dependent substring getters
     335                 : //-----------------------------------------------------------------------------
     336                 : 
     337                 : inline const nsDependentCSubstring
     338          459765 : nsStandardURL::Segment(PRUint32 pos, PRInt32 len)
     339                 : {
     340          459765 :     if (len < 0) {
     341            3225 :         pos = 0;
     342            3225 :         len = 0;
     343                 :     }
     344          459765 :     return Substring(mSpec, pos, PRUint32(len));
     345                 : }
     346                 : 
     347                 : inline const nsDependentCSubstring
     348             576 : nsStandardURL::Prepath()
     349                 : {
     350             576 :     PRUint32 len = 0;
     351             576 :     if (mAuthority.mLen >= 0)
     352             576 :         len = mAuthority.mPos + mAuthority.mLen;
     353             576 :     return Substring(mSpec, 0, len);
     354                 : }
     355                 : 
     356                 : inline const nsDependentCSubstring
     357             253 : nsStandardURL::Userpass(bool includeDelim)
     358                 : {
     359             253 :     PRUint32 pos=0, len=0;
     360                 :     // if there is no username, then there can be no password
     361             253 :     if (mUsername.mLen > 0) {
     362               0 :         pos = mUsername.mPos;
     363               0 :         len = mUsername.mLen;
     364               0 :         if (mPassword.mLen >= 0)
     365               0 :             len += (mPassword.mLen + 1);
     366               0 :         if (includeDelim)
     367               0 :             len++;
     368                 :     }
     369             253 :     return Substring(mSpec, pos, len);
     370                 : }
     371                 : 
     372                 : inline const nsDependentCSubstring
     373            8324 : nsStandardURL::Hostport()
     374                 : {
     375            8324 :     PRUint32 pos=0, len=0;
     376            8324 :     if (mAuthority.mLen > 0) {
     377            8324 :         pos = mHost.mPos;
     378            8324 :         len = mAuthority.mPos + mAuthority.mLen - pos;
     379                 :     }
     380            8324 :     return Substring(mSpec, pos, len);
     381                 : }
     382                 : 
     383                 : inline const nsDependentCSubstring
     384          176557 : nsStandardURL::Host()
     385                 : {
     386          176557 :     PRUint32 pos=0, len=0;
     387          176557 :     if (mHost.mLen > 0) {
     388          172895 :         pos = mHost.mPos;
     389          172895 :         len = mHost.mLen;
     390          172895 :         if (mSpec.CharAt(pos) == '[' && mSpec.CharAt(pos + len - 1) == ']') {
     391               2 :             pos++;
     392               2 :             len -= 2;
     393                 :         }
     394                 :     }
     395          176557 :     return Substring(mSpec, pos, len);
     396                 : }
     397                 : 
     398                 : inline const nsDependentCSubstring
     399             233 : nsStandardURL::Filename()
     400                 : {
     401             233 :     PRUint32 pos=0, len=0;
     402                 :     // if there is no basename, then there can be no extension
     403             233 :     if (mBasename.mLen > 0) {
     404              77 :         pos = mBasename.mPos;
     405              77 :         len = mBasename.mLen;
     406              77 :         if (mExtension.mLen >= 0)
     407               4 :             len += (mExtension.mLen + 1);
     408                 :     }
     409             233 :     return Substring(mSpec, pos, len);
     410                 : }
     411                 : 
     412                 : #endif // nsStandardURL_h__

Generated by: LCOV version 1.7