Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / netwerk / base / src / nsSimpleURI.cpp
blob92c9afb012e16103ccd58353510efdd9d7ba92b9
1 /* -*- Mode: C++; tab-width: 2; 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 * Pierre Phaneuf <pp@ludusdesign.com>
24 * Gagan Saksena <gagan@netscape.com>
25 * Darin Fisher <darin@netscape.com>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either the GNU General Public License Version 2 or later (the "GPL"), or
29 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 #include "nsSimpleURI.h"
42 #include "nscore.h"
43 #include "nsCRT.h"
44 #include "nsString.h"
45 #include "nsReadableUtils.h"
46 #include "prmem.h"
47 #include "prprf.h"
48 #include "nsURLHelper.h"
49 #include "nsNetCID.h"
50 #include "nsIObjectInputStream.h"
51 #include "nsIObjectOutputStream.h"
52 #include "nsEscape.h"
53 #include "nsNetError.h"
54 #include "nsIProgrammingLanguage.h"
56 static NS_DEFINE_CID(kThisSimpleURIImplementationCID,
57 NS_THIS_SIMPLEURI_IMPLEMENTATION_CID);
58 static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
60 ////////////////////////////////////////////////////////////////////////////////
61 // nsSimpleURI methods:
63 nsSimpleURI::nsSimpleURI(nsISupports* outer)
64 : mMutable(PR_TRUE)
66 NS_INIT_AGGREGATED(outer);
69 nsSimpleURI::~nsSimpleURI()
73 NS_IMPL_AGGREGATED(nsSimpleURI)
75 nsresult
76 nsSimpleURI::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
78 NS_ENSURE_ARG_POINTER(aInstancePtr);
80 if (aIID.Equals(NS_GET_IID(nsISupports))) {
81 *aInstancePtr = InnerObject();
82 } else if (aIID.Equals(kThisSimpleURIImplementationCID) || // used by Equals
83 aIID.Equals(NS_GET_IID(nsIURI))) {
84 *aInstancePtr = static_cast<nsIURI*>(this);
85 } else if (aIID.Equals(NS_GET_IID(nsISerializable))) {
86 *aInstancePtr = static_cast<nsISerializable*>(this);
87 } else if (aIID.Equals(NS_GET_IID(nsIClassInfo))) {
88 *aInstancePtr = static_cast<nsIClassInfo*>(this);
89 } else if (aIID.Equals(NS_GET_IID(nsIMutable))) {
90 *aInstancePtr = static_cast<nsIMutable*>(this);
91 } else {
92 *aInstancePtr = nsnull;
93 return NS_NOINTERFACE;
95 NS_ADDREF((nsISupports*)*aInstancePtr);
96 return NS_OK;
99 ////////////////////////////////////////////////////////////////////////////////
100 // nsISerializable methods:
102 NS_IMETHODIMP
103 nsSimpleURI::Read(nsIObjectInputStream* aStream)
105 nsresult rv;
107 rv = aStream->ReadBoolean(&mMutable);
108 if (NS_FAILED(rv)) return rv;
110 rv = aStream->ReadCString(mScheme);
111 if (NS_FAILED(rv)) return rv;
113 rv = aStream->ReadCString(mPath);
114 if (NS_FAILED(rv)) return rv;
116 return NS_OK;
119 NS_IMETHODIMP
120 nsSimpleURI::Write(nsIObjectOutputStream* aStream)
122 nsresult rv;
124 rv = aStream->WriteBoolean(mMutable);
125 if (NS_FAILED(rv)) return rv;
127 rv = aStream->WriteStringZ(mScheme.get());
128 if (NS_FAILED(rv)) return rv;
130 rv = aStream->WriteStringZ(mPath.get());
131 if (NS_FAILED(rv)) return rv;
133 return NS_OK;
136 ////////////////////////////////////////////////////////////////////////////////
137 // nsIURI methods:
139 NS_IMETHODIMP
140 nsSimpleURI::GetSpec(nsACString &result)
142 result = mScheme + NS_LITERAL_CSTRING(":") + mPath;
143 return NS_OK;
146 NS_IMETHODIMP
147 nsSimpleURI::SetSpec(const nsACString &aSpec)
149 NS_ENSURE_STATE(mMutable);
151 const nsAFlatCString& flat = PromiseFlatCString(aSpec);
152 const char* specPtr = flat.get();
154 // filter out unexpected chars "\r\n\t" if necessary
155 nsCAutoString filteredSpec;
156 PRInt32 specLen;
157 if (net_FilterURIString(specPtr, filteredSpec)) {
158 specPtr = filteredSpec.get();
159 specLen = filteredSpec.Length();
160 } else
161 specLen = flat.Length();
163 // nsSimpleURI currently restricts the charset to US-ASCII
164 nsCAutoString spec;
165 NS_EscapeURL(specPtr, specLen, esc_OnlyNonASCII|esc_AlwaysCopy, spec);
167 PRInt32 pos = spec.FindChar(':');
168 if (pos == -1 || !net_IsValidScheme(spec.get(), pos))
169 return NS_ERROR_MALFORMED_URI;
171 mScheme.Truncate();
172 mPath.Truncate();
174 PRInt32 n = spec.Left(mScheme, pos);
175 NS_ASSERTION(n == pos, "Left failed");
177 PRInt32 count = spec.Length() - pos - 1;
178 n = spec.Mid(mPath, pos + 1, count);
179 NS_ASSERTION(n == count, "Mid failed");
181 ToLowerCase(mScheme);
182 return NS_OK;
185 NS_IMETHODIMP
186 nsSimpleURI::GetScheme(nsACString &result)
188 result = mScheme;
189 return NS_OK;
192 NS_IMETHODIMP
193 nsSimpleURI::SetScheme(const nsACString &scheme)
195 NS_ENSURE_STATE(mMutable);
197 const nsPromiseFlatCString &flat = PromiseFlatCString(scheme);
198 if (!net_IsValidScheme(flat)) {
199 NS_ERROR("the given url scheme contains invalid characters");
200 return NS_ERROR_MALFORMED_URI;
203 mScheme = scheme;
204 ToLowerCase(mScheme);
205 return NS_OK;
208 NS_IMETHODIMP
209 nsSimpleURI::GetPrePath(nsACString &result)
211 result = mScheme + NS_LITERAL_CSTRING(":");
212 return NS_OK;
215 NS_IMETHODIMP
216 nsSimpleURI::GetUserPass(nsACString &result)
218 return NS_ERROR_FAILURE;
221 NS_IMETHODIMP
222 nsSimpleURI::SetUserPass(const nsACString &userPass)
224 NS_ENSURE_STATE(mMutable);
226 return NS_ERROR_FAILURE;
229 NS_IMETHODIMP
230 nsSimpleURI::GetUsername(nsACString &result)
232 return NS_ERROR_FAILURE;
235 NS_IMETHODIMP
236 nsSimpleURI::SetUsername(const nsACString &userName)
238 NS_ENSURE_STATE(mMutable);
240 return NS_ERROR_FAILURE;
243 NS_IMETHODIMP
244 nsSimpleURI::GetPassword(nsACString &result)
246 return NS_ERROR_FAILURE;
249 NS_IMETHODIMP
250 nsSimpleURI::SetPassword(const nsACString &password)
252 NS_ENSURE_STATE(mMutable);
254 return NS_ERROR_FAILURE;
257 NS_IMETHODIMP
258 nsSimpleURI::GetHostPort(nsACString &result)
260 // Note: Audit all callers before changing this to return an empty
261 // string -- CAPS and UI code may depend on this throwing.
262 return NS_ERROR_FAILURE;
265 NS_IMETHODIMP
266 nsSimpleURI::SetHostPort(const nsACString &result)
268 NS_ENSURE_STATE(mMutable);
270 return NS_ERROR_FAILURE;
273 NS_IMETHODIMP
274 nsSimpleURI::GetHost(nsACString &result)
276 // Note: Audit all callers before changing this to return an empty
277 // string -- CAPS and UI code depend on this throwing.
278 return NS_ERROR_FAILURE;
281 NS_IMETHODIMP
282 nsSimpleURI::SetHost(const nsACString &host)
284 NS_ENSURE_STATE(mMutable);
286 return NS_ERROR_FAILURE;
289 NS_IMETHODIMP
290 nsSimpleURI::GetPort(PRInt32 *result)
292 // Note: Audit all callers before changing this to return an empty
293 // string -- CAPS and UI code may depend on this throwing.
294 return NS_ERROR_FAILURE;
297 NS_IMETHODIMP
298 nsSimpleURI::SetPort(PRInt32 port)
300 NS_ENSURE_STATE(mMutable);
302 return NS_ERROR_FAILURE;
305 NS_IMETHODIMP
306 nsSimpleURI::GetPath(nsACString &result)
308 result = mPath;
309 return NS_OK;
312 NS_IMETHODIMP
313 nsSimpleURI::SetPath(const nsACString &path)
315 NS_ENSURE_STATE(mMutable);
317 mPath = path;
318 return NS_OK;
321 NS_IMETHODIMP
322 nsSimpleURI::Equals(nsIURI* other, PRBool *result)
324 PRBool eq = PR_FALSE;
325 if (other) {
326 nsSimpleURI* otherUrl;
327 nsresult rv =
328 other->QueryInterface(kThisSimpleURIImplementationCID,
329 (void**)&otherUrl);
330 if (NS_SUCCEEDED(rv)) {
331 eq = PRBool((0 == strcmp(mScheme.get(), otherUrl->mScheme.get())) &&
332 (0 == strcmp(mPath.get(), otherUrl->mPath.get())));
333 NS_RELEASE(otherUrl);
336 *result = eq;
337 return NS_OK;
340 NS_IMETHODIMP
341 nsSimpleURI::SchemeIs(const char *i_Scheme, PRBool *o_Equals)
343 NS_ENSURE_ARG_POINTER(o_Equals);
344 if (!i_Scheme) return NS_ERROR_NULL_POINTER;
346 const char *this_scheme = mScheme.get();
348 // mScheme is guaranteed to be lower case.
349 if (*i_Scheme == *this_scheme || *i_Scheme == (*this_scheme - ('a' - 'A')) ) {
350 *o_Equals = PL_strcasecmp(this_scheme, i_Scheme) ? PR_FALSE : PR_TRUE;
351 } else {
352 *o_Equals = PR_FALSE;
355 return NS_OK;
358 /* virtual */ nsSimpleURI*
359 nsSimpleURI::StartClone()
361 return new nsSimpleURI(nsnull); // XXX outer?
364 NS_IMETHODIMP
365 nsSimpleURI::Clone(nsIURI* *result)
367 nsSimpleURI* url = StartClone();
368 if (url == nsnull)
369 return NS_ERROR_OUT_OF_MEMORY;
371 // Note: |url| may well have mMutable false at this point, so
372 // don't call any setter methods.
373 url->mScheme = mScheme;
374 url->mPath = mPath;
376 *result = url;
377 NS_ADDREF(url);
378 return NS_OK;
381 NS_IMETHODIMP
382 nsSimpleURI::Resolve(const nsACString &relativePath, nsACString &result)
384 result = relativePath;
385 return NS_OK;
388 NS_IMETHODIMP
389 nsSimpleURI::GetAsciiSpec(nsACString &result)
391 nsCAutoString buf;
392 nsresult rv = GetSpec(buf);
393 if (NS_FAILED(rv)) return rv;
394 NS_EscapeURL(buf, esc_OnlyNonASCII|esc_AlwaysCopy, result);
395 return NS_OK;
398 NS_IMETHODIMP
399 nsSimpleURI::GetAsciiHost(nsACString &result)
401 result.Truncate();
402 return NS_OK;
405 NS_IMETHODIMP
406 nsSimpleURI::GetOriginCharset(nsACString &result)
408 result.Truncate();
409 return NS_OK;
412 //----------------------------------------------------------------------------
413 // nsSimpleURI::nsIClassInfo
414 //----------------------------------------------------------------------------
416 NS_IMETHODIMP
417 nsSimpleURI::GetInterfaces(PRUint32 *count, nsIID * **array)
419 *count = 0;
420 *array = nsnull;
421 return NS_OK;
424 NS_IMETHODIMP
425 nsSimpleURI::GetHelperForLanguage(PRUint32 language, nsISupports **_retval)
427 *_retval = nsnull;
428 return NS_OK;
431 NS_IMETHODIMP
432 nsSimpleURI::GetContractID(char * *aContractID)
434 // Make sure to modify any subclasses as needed if this ever
435 // changes.
436 *aContractID = nsnull;
437 return NS_OK;
440 NS_IMETHODIMP
441 nsSimpleURI::GetClassDescription(char * *aClassDescription)
443 *aClassDescription = nsnull;
444 return NS_OK;
447 NS_IMETHODIMP
448 nsSimpleURI::GetClassID(nsCID * *aClassID)
450 // Make sure to modify any subclasses as needed if this ever
451 // changes to not call the virtual GetClassIDNoAlloc.
452 *aClassID = (nsCID*) nsMemory::Alloc(sizeof(nsCID));
453 if (!*aClassID)
454 return NS_ERROR_OUT_OF_MEMORY;
455 return GetClassIDNoAlloc(*aClassID);
458 NS_IMETHODIMP
459 nsSimpleURI::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
461 *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
462 return NS_OK;
465 NS_IMETHODIMP
466 nsSimpleURI::GetFlags(PRUint32 *aFlags)
468 *aFlags = nsIClassInfo::MAIN_THREAD_ONLY;
469 return NS_OK;
472 NS_IMETHODIMP
473 nsSimpleURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
475 *aClassIDNoAlloc = kSimpleURICID;
476 return NS_OK;
479 //----------------------------------------------------------------------------
480 // nsSimpleURI::nsISimpleURI
481 //----------------------------------------------------------------------------
482 NS_IMETHODIMP
483 nsSimpleURI::GetMutable(PRBool *value)
485 *value = mMutable;
486 return NS_OK;
489 NS_IMETHODIMP
490 nsSimpleURI::SetMutable(PRBool value)
492 NS_ENSURE_ARG(mMutable || !value);
494 mMutable = value;
495 return NS_OK;