Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / netwerk / base / src / nsStandardURL.h
blob0082325ca8e2ab834e660c76c91476f4f103f013
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
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/
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.
15 * The Original Code is mozilla.org code.
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.
22 * Contributor(s):
23 * Darin Fisher <darin@netscape.com> (original author)
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.
37 * ***** END LICENSE BLOCK ***** */
39 #ifndef nsStandardURL_h__
40 #define nsStandardURL_h__
42 #include "nsString.h"
43 #include "nsDependentString.h"
44 #include "nsDependentSubstring.h"
45 #include "nsISerializable.h"
46 #include "nsIFileURL.h"
47 #include "nsIStandardURL.h"
48 #include "nsIFile.h"
49 #include "nsIURLParser.h"
50 #include "nsIUnicodeEncoder.h"
51 #include "nsIObserver.h"
52 #include "nsIIOService.h"
53 #include "nsCOMPtr.h"
54 #include "nsURLHelper.h"
55 #include "nsIClassInfo.h"
57 class nsIBinaryInputStream;
58 class nsIBinaryOutputStream;
59 class nsIIDNService;
60 class nsICharsetConverterManager;
61 class nsIPrefBranch;
63 //-----------------------------------------------------------------------------
64 // standard URL implementation
65 //-----------------------------------------------------------------------------
67 class nsStandardURL : public nsIFileURL
68 , public nsIStandardURL
69 , public nsISerializable
70 , public nsIClassInfo
72 public:
73 NS_DECL_ISUPPORTS
74 NS_DECL_NSIURI
75 NS_DECL_NSIURL
76 NS_DECL_NSIFILEURL
77 NS_DECL_NSISTANDARDURL
78 NS_DECL_NSISERIALIZABLE
79 NS_DECL_NSICLASSINFO
80 NS_DECL_NSIMUTABLE
82 nsStandardURL(PRBool aSupportsFileURL = PR_FALSE);
83 virtual ~nsStandardURL();
85 static void InitGlobalObjects();
86 static void ShutdownGlobalObjects();
88 public: /* internal -- HPUX compiler can't handle this being private */
90 // location and length of an url segment relative to mSpec
92 struct URLSegment
94 PRUint32 mPos;
95 PRInt32 mLen;
97 URLSegment() : mPos(0), mLen(-1) {}
98 URLSegment(PRUint32 pos, PRInt32 len) : mPos(pos), mLen(len) {}
99 void Reset() { mPos = 0; mLen = -1; }
103 // Pref observer
105 class nsPrefObserver : public nsIObserver
107 public:
108 NS_DECL_ISUPPORTS
109 NS_DECL_NSIOBSERVER
111 nsPrefObserver() { }
113 friend class nsPrefObserver;
116 // URL segment encoder : performs charset conversion and URL escaping.
118 class nsSegmentEncoder
120 public:
121 nsSegmentEncoder(const char *charset);
123 // Encode the given segment if necessary, and return the length of
124 // the encoded segment. The encoded segment is appended to |buf|
125 // if and only if encoding is required.
126 PRInt32 EncodeSegmentCount(const char *str,
127 const URLSegment &segment,
128 PRInt16 mask,
129 nsAFlatCString &buf,
130 PRBool& appended);
132 // Encode the given string if necessary, and return a reference to
133 // the encoded string. Returns a reference to |buf| if encoding
134 // is required. Otherwise, a reference to |str| is returned.
135 const nsACString &EncodeSegment(const nsASingleFragmentCString &str,
136 PRInt16 mask,
137 nsAFlatCString &buf);
138 private:
139 PRBool InitUnicodeEncoder();
141 const char* mCharset; // Caller should keep this alive for
142 // the life of the segment encoder
143 nsCOMPtr<nsIUnicodeEncoder> mEncoder;
145 friend class nsSegmentEncoder;
147 protected:
148 virtual nsStandardURL* StartClone();
150 // Helper for subclass implementation of GetFile(). Subclasses that map
151 // URIs to files in a special way should implement this method. It should
152 // ensure that our mFile is initialized, if it's possible.
153 virtual nsresult EnsureFile();
155 private:
156 PRInt32 Port() { return mPort == -1 ? mDefaultPort : mPort; }
158 void Clear();
159 void InvalidateCache(PRBool invalidateCachedFile = PR_TRUE);
161 PRBool EscapeIPv6(const char *host, nsCString &result);
162 PRBool NormalizeIDN(const nsCSubstring &host, nsCString &result);
163 void CoalescePath(netCoalesceFlags coalesceFlag, char *path);
165 PRUint32 AppendSegmentToBuf(char *, PRUint32, const char *, URLSegment &, const nsCString *esc=nsnull, PRBool useEsc = PR_FALSE);
166 PRUint32 AppendToBuf(char *, PRUint32, const char *, PRUint32);
168 nsresult BuildNormalizedSpec(const char *spec);
170 PRBool SegmentIs(const URLSegment &s1, const char *val, PRBool ignoreCase = PR_FALSE);
171 PRBool SegmentIs(const char* spec, const URLSegment &s1, const char *val, PRBool ignoreCase = PR_FALSE);
172 PRBool SegmentIs(const URLSegment &s1, const char *val, const URLSegment &s2, PRBool ignoreCase = PR_FALSE);
174 PRInt32 ReplaceSegment(PRUint32 pos, PRUint32 len, const char *val, PRUint32 valLen);
175 PRInt32 ReplaceSegment(PRUint32 pos, PRUint32 len, const nsACString &val);
177 nsresult ParseURL(const char *spec, PRInt32 specLen);
178 nsresult ParsePath(const char *spec, PRUint32 pathPos, PRInt32 pathLen = -1);
180 char *AppendToSubstring(PRUint32 pos, PRInt32 len, const char *tail, PRInt32 tailLen = -1);
182 // dependent substring helpers
183 const nsDependentCSubstring Segment(PRUint32 pos, PRInt32 len); // see below
184 const nsDependentCSubstring Segment(const URLSegment &s) { return Segment(s.mPos, s.mLen); }
186 // dependent substring getters
187 const nsDependentCSubstring Prepath(); // see below
188 const nsDependentCSubstring Scheme() { return Segment(mScheme); }
189 const nsDependentCSubstring Userpass(PRBool includeDelim = PR_FALSE); // see below
190 const nsDependentCSubstring Username() { return Segment(mUsername); }
191 const nsDependentCSubstring Password() { return Segment(mPassword); }
192 const nsDependentCSubstring Hostport(); // see below
193 const nsDependentCSubstring Host(); // see below
194 const nsDependentCSubstring Path() { return Segment(mPath); }
195 const nsDependentCSubstring Filepath() { return Segment(mFilepath); }
196 const nsDependentCSubstring Directory() { return Segment(mDirectory); }
197 const nsDependentCSubstring Filename(); // see below
198 const nsDependentCSubstring Basename() { return Segment(mBasename); }
199 const nsDependentCSubstring Extension() { return Segment(mExtension); }
200 const nsDependentCSubstring Param() { return Segment(mParam); }
201 const nsDependentCSubstring Query() { return Segment(mQuery); }
202 const nsDependentCSubstring Ref() { return Segment(mRef); }
204 // shift the URLSegments to the right by diff
205 void ShiftFromAuthority(PRInt32 diff) { mAuthority.mPos += diff; ShiftFromUsername(diff); }
206 void ShiftFromUsername(PRInt32 diff) { mUsername.mPos += diff; ShiftFromPassword(diff); }
207 void ShiftFromPassword(PRInt32 diff) { mPassword.mPos += diff; ShiftFromHost(diff); }
208 void ShiftFromHost(PRInt32 diff) { mHost.mPos += diff; ShiftFromPath(diff); }
209 void ShiftFromPath(PRInt32 diff) { mPath.mPos += diff; ShiftFromFilepath(diff); }
210 void ShiftFromFilepath(PRInt32 diff) { mFilepath.mPos += diff; ShiftFromDirectory(diff); }
211 void ShiftFromDirectory(PRInt32 diff) { mDirectory.mPos += diff; ShiftFromBasename(diff); }
212 void ShiftFromBasename(PRInt32 diff) { mBasename.mPos += diff; ShiftFromExtension(diff); }
213 void ShiftFromExtension(PRInt32 diff) { mExtension.mPos += diff; ShiftFromParam(diff); }
214 void ShiftFromParam(PRInt32 diff) { mParam.mPos += diff; ShiftFromQuery(diff); }
215 void ShiftFromQuery(PRInt32 diff) { mQuery.mPos += diff; ShiftFromRef(diff); }
216 void ShiftFromRef(PRInt32 diff) { mRef.mPos += diff; }
218 // fastload helper functions
219 nsresult ReadSegment(nsIBinaryInputStream *, URLSegment &);
220 nsresult WriteSegment(nsIBinaryOutputStream *, const URLSegment &);
222 static void PrefsChanged(nsIPrefBranch *prefs, const char *pref);
224 // mSpec contains the normalized version of the URL spec (UTF-8 encoded).
225 nsCString mSpec;
226 PRInt32 mDefaultPort;
227 PRInt32 mPort;
229 // url parts (relative to mSpec)
230 URLSegment mScheme;
231 URLSegment mAuthority;
232 URLSegment mUsername;
233 URLSegment mPassword;
234 URLSegment mHost;
235 URLSegment mPath;
236 URLSegment mFilepath;
237 URLSegment mDirectory;
238 URLSegment mBasename;
239 URLSegment mExtension;
240 URLSegment mParam;
241 URLSegment mQuery;
242 URLSegment mRef;
244 nsCString mOriginCharset;
245 nsCOMPtr<nsIURLParser> mParser;
247 // mFile is protected so subclasses can access it directly
248 protected:
249 nsCOMPtr<nsIFile> mFile; // cached result for nsIFileURL::GetFile
251 private:
252 char *mHostA; // cached result for nsIURI::GetHostA
254 enum {
255 eEncoding_Unknown,
256 eEncoding_ASCII,
257 eEncoding_UTF8
260 PRUint32 mHostEncoding : 2; // eEncoding_xxx
261 PRUint32 mSpecEncoding : 2; // eEncoding_xxx
262 PRUint32 mURLType : 2; // nsIStandardURL::URLTYPE_xxx
263 PRUint32 mMutable : 1; // nsIStandardURL::mutable
264 PRUint32 mSupportsFileURL : 1; // QI to nsIFileURL?
266 // global objects. don't use COMPtr as its destructor will cause a
267 // coredump if we leak it.
268 static nsIIDNService *gIDN;
269 static nsICharsetConverterManager *gCharsetMgr;
270 static PRBool gInitialized;
271 static PRBool gEscapeUTF8;
272 static PRBool gAlwaysEncodeInUTF8;
273 static PRBool gEncodeQueryInUTF8;
276 #define NS_THIS_STANDARDURL_IMPL_CID \
277 { /* b8e3e97b-1ccd-4b45-af5a-79596770f5d7 */ \
278 0xb8e3e97b, \
279 0x1ccd, \
280 0x4b45, \
281 {0xaf, 0x5a, 0x79, 0x59, 0x67, 0x70, 0xf5, 0xd7} \
284 //-----------------------------------------------------------------------------
285 // Dependent substring getters
286 //-----------------------------------------------------------------------------
288 inline const nsDependentCSubstring
289 nsStandardURL::Segment(PRUint32 pos, PRInt32 len)
291 if (len < 0) {
292 pos = 0;
293 len = 0;
295 return Substring(mSpec, pos, PRUint32(len));
298 inline const nsDependentCSubstring
299 nsStandardURL::Prepath()
301 PRUint32 len = 0;
302 if (mAuthority.mLen >= 0)
303 len = mAuthority.mPos + mAuthority.mLen;
304 return Substring(mSpec, 0, len);
307 inline const nsDependentCSubstring
308 nsStandardURL::Userpass(int includeDelim)
310 PRUint32 pos=0, len=0;
311 // if there is no username, then there can be no password
312 if (mUsername.mLen > 0) {
313 pos = mUsername.mPos;
314 len = mUsername.mLen;
315 if (mPassword.mLen >= 0)
316 len += (mPassword.mLen + 1);
317 if (includeDelim)
318 len++;
320 return Substring(mSpec, pos, len);
323 inline const nsDependentCSubstring
324 nsStandardURL::Hostport()
326 PRUint32 pos=0, len=0;
327 if (mAuthority.mLen > 0) {
328 pos = mHost.mPos;
329 len = mAuthority.mPos + mAuthority.mLen - pos;
331 return Substring(mSpec, pos, len);
334 inline const nsDependentCSubstring
335 nsStandardURL::Host()
337 PRUint32 pos=0, len=0;
338 if (mHost.mLen > 0) {
339 pos = mHost.mPos;
340 len = mHost.mLen;
341 if (mSpec.CharAt(pos) == '[' && mSpec.CharAt(pos + len - 1) == ']') {
342 pos++;
343 len -= 2;
346 return Substring(mSpec, pos, len);
349 inline const nsDependentCSubstring
350 nsStandardURL::Filename()
352 PRUint32 pos=0, len=0;
353 // if there is no basename, then there can be no extension
354 if (mBasename.mLen > 0) {
355 pos = mBasename.mPos;
356 len = mBasename.mLen;
357 if (mExtension.mLen >= 0)
358 len += (mExtension.mLen + 1);
360 return Substring(mSpec, pos, len);
363 #endif // nsStandardURL_h__