Back to index

lightning-sunbird  0.9+nobinonly
nsSimpleURI.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Pierre Phaneuf <pp@ludusdesign.com>
00024  *   Gagan Saksena <gagan@netscape.com>
00025  *   Darin Fisher <darin@netscape.com>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either the GNU General Public License Version 2 or later (the "GPL"), or
00029  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 #include "nsSimpleURI.h"
00042 #include "nscore.h"
00043 #include "nsCRT.h"
00044 #include "nsString.h"
00045 #include "nsReadableUtils.h"
00046 #include "prmem.h"
00047 #include "prprf.h"
00048 #include "nsURLHelper.h"
00049 #include "nsNetCID.h"
00050 #include "nsIObjectInputStream.h"
00051 #include "nsIObjectOutputStream.h"
00052 #include "nsEscape.h"
00053 #include "nsNetError.h"
00054 
00055 static NS_DEFINE_CID(kThisSimpleURIImplementationCID,
00056                      NS_THIS_SIMPLEURI_IMPLEMENTATION_CID);
00057 static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
00058 
00059 static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
00060 
00062 // nsSimpleURI methods:
00063 
00064 nsSimpleURI::nsSimpleURI(nsISupports* outer)
00065 {
00066     NS_INIT_AGGREGATED(outer);
00067 }
00068 
00069 nsSimpleURI::~nsSimpleURI()
00070 {
00071 }
00072 
00073 NS_IMPL_AGGREGATED(nsSimpleURI)
00074 
00075 NS_IMETHODIMP
00076 nsSimpleURI::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
00077 {
00078     NS_ENSURE_ARG_POINTER(aInstancePtr);
00079 
00080     if (aIID.Equals(kISupportsIID)) {
00081         *aInstancePtr = GetInner();
00082     } else if (aIID.Equals(kThisSimpleURIImplementationCID) || // used by Equals
00083                aIID.Equals(NS_GET_IID(nsIURI))) {
00084         *aInstancePtr = NS_STATIC_CAST(nsIURI*, this);
00085     } else if (aIID.Equals(NS_GET_IID(nsISerializable))) {
00086         *aInstancePtr = NS_STATIC_CAST(nsISerializable*, this);
00087     } else if (aIID.Equals(NS_GET_IID(nsIClassInfo))) {
00088         *aInstancePtr = NS_STATIC_CAST(nsIClassInfo*, this);
00089     } else {
00090         *aInstancePtr = nsnull;
00091         return NS_NOINTERFACE;
00092     }
00093     NS_ADDREF((nsISupports*)*aInstancePtr);
00094     return NS_OK;
00095 }
00096 
00098 // nsISerializable methods:
00099 
00100 NS_IMETHODIMP
00101 nsSimpleURI::Read(nsIObjectInputStream* aStream)
00102 {
00103     nsresult rv;
00104 
00105     rv = aStream->ReadCString(mScheme);
00106     if (NS_FAILED(rv)) return rv;
00107 
00108     rv = aStream->ReadCString(mPath);
00109     if (NS_FAILED(rv)) return rv;
00110 
00111     return NS_OK;
00112 }
00113 
00114 NS_IMETHODIMP
00115 nsSimpleURI::Write(nsIObjectOutputStream* aStream)
00116 {
00117     nsresult rv;
00118 
00119     rv = aStream->WriteStringZ(mScheme.get());
00120     if (NS_FAILED(rv)) return rv;
00121 
00122     rv = aStream->WriteStringZ(mPath.get());
00123     if (NS_FAILED(rv)) return rv;
00124 
00125     return NS_OK;
00126 }
00127 
00129 // nsIURI methods:
00130 
00131 NS_IMETHODIMP
00132 nsSimpleURI::GetSpec(nsACString &result)
00133 {
00134     result = mScheme + NS_LITERAL_CSTRING(":") + mPath;
00135     return NS_OK;
00136 }
00137 
00138 NS_IMETHODIMP
00139 nsSimpleURI::SetSpec(const nsACString &aSpec)
00140 {
00141     const nsAFlatCString& flat = PromiseFlatCString(aSpec);
00142     const char* specPtr = flat.get();
00143 
00144     // filter out unexpected chars "\r\n\t" if necessary
00145     nsCAutoString filteredSpec;
00146     PRInt32 specLen;
00147     if (net_FilterURIString(specPtr, filteredSpec)) {
00148         specPtr = filteredSpec.get();
00149         specLen = filteredSpec.Length();
00150     } else
00151         specLen = flat.Length();
00152 
00153     // nsSimpleURI currently restricts the charset to US-ASCII
00154     nsCAutoString spec;
00155     NS_EscapeURL(specPtr, specLen, esc_OnlyNonASCII|esc_AlwaysCopy, spec);
00156 
00157     PRInt32 pos = spec.FindChar(':');
00158     if (pos == -1 || !net_IsValidScheme(spec.get(), pos))
00159         return NS_ERROR_MALFORMED_URI;
00160 
00161     mScheme.Truncate();
00162     mPath.Truncate();
00163 
00164     PRInt32 n = spec.Left(mScheme, pos);
00165     NS_ASSERTION(n == pos, "Left failed");
00166 
00167     PRInt32 count = spec.Length() - pos - 1;
00168     n = spec.Mid(mPath, pos + 1, count);
00169     NS_ASSERTION(n == count, "Mid failed");
00170 
00171     ToLowerCase(mScheme);
00172     return NS_OK;
00173 }
00174 
00175 NS_IMETHODIMP
00176 nsSimpleURI::GetScheme(nsACString &result)
00177 {
00178     result = mScheme;
00179     return NS_OK;
00180 }
00181 
00182 NS_IMETHODIMP
00183 nsSimpleURI::SetScheme(const nsACString &scheme)
00184 {
00185     const nsPromiseFlatCString &flat = PromiseFlatCString(scheme);
00186     if (!net_IsValidScheme(flat)) {
00187         NS_ERROR("the given url scheme contains invalid characters");
00188         return NS_ERROR_MALFORMED_URI;
00189     }
00190 
00191     mScheme = scheme;
00192     ToLowerCase(mScheme);
00193     return NS_OK;
00194 }
00195 
00196 NS_IMETHODIMP
00197 nsSimpleURI::GetPrePath(nsACString &result)
00198 {
00199     result = mScheme + NS_LITERAL_CSTRING(":");
00200     return NS_OK;
00201 }
00202 
00203 NS_IMETHODIMP
00204 nsSimpleURI::GetUserPass(nsACString &result)
00205 {
00206     return NS_ERROR_FAILURE;
00207 }
00208 
00209 NS_IMETHODIMP
00210 nsSimpleURI::SetUserPass(const nsACString &userPass)
00211 {
00212     return NS_ERROR_FAILURE;
00213 }
00214 
00215 NS_IMETHODIMP
00216 nsSimpleURI::GetUsername(nsACString &result)
00217 {
00218     return NS_ERROR_FAILURE;
00219 }
00220 
00221 NS_IMETHODIMP
00222 nsSimpleURI::SetUsername(const nsACString &userName)
00223 {
00224     return NS_ERROR_FAILURE;
00225 }
00226 
00227 NS_IMETHODIMP
00228 nsSimpleURI::GetPassword(nsACString &result)
00229 {
00230     return NS_ERROR_FAILURE;
00231 }
00232 
00233 NS_IMETHODIMP
00234 nsSimpleURI::SetPassword(const nsACString &password)
00235 {
00236     return NS_ERROR_FAILURE;
00237 }
00238 
00239 NS_IMETHODIMP
00240 nsSimpleURI::GetHostPort(nsACString &result)
00241 {
00242     return NS_ERROR_FAILURE;
00243 }
00244 
00245 NS_IMETHODIMP
00246 nsSimpleURI::SetHostPort(const nsACString &result)
00247 {
00248     return NS_ERROR_FAILURE;
00249 }
00250 
00251 NS_IMETHODIMP
00252 nsSimpleURI::GetHost(nsACString &result)
00253 {
00254     return NS_ERROR_FAILURE;
00255 }
00256 
00257 NS_IMETHODIMP
00258 nsSimpleURI::SetHost(const nsACString &host)
00259 {
00260     return NS_ERROR_FAILURE;
00261 }
00262 
00263 NS_IMETHODIMP
00264 nsSimpleURI::GetPort(PRInt32 *result)
00265 {
00266     return NS_ERROR_FAILURE;
00267 }
00268 
00269 NS_IMETHODIMP
00270 nsSimpleURI::SetPort(PRInt32 port)
00271 {
00272     return NS_ERROR_FAILURE;
00273 }
00274 
00275 NS_IMETHODIMP
00276 nsSimpleURI::GetPath(nsACString &result)
00277 {
00278     result = mPath;
00279     return NS_OK;
00280 }
00281 
00282 NS_IMETHODIMP
00283 nsSimpleURI::SetPath(const nsACString &path)
00284 {
00285     mPath = path;
00286     return NS_OK;
00287 }
00288 
00289 NS_IMETHODIMP
00290 nsSimpleURI::Equals(nsIURI* other, PRBool *result)
00291 {
00292     PRBool eq = PR_FALSE;
00293     if (other) {
00294         nsSimpleURI* otherUrl;
00295         nsresult rv =
00296             other->QueryInterface(kThisSimpleURIImplementationCID,
00297                                   (void**)&otherUrl);
00298         if (NS_SUCCEEDED(rv)) {
00299             eq = PRBool((0 == strcmp(mScheme.get(), otherUrl->mScheme.get())) && 
00300                         (0 == strcmp(mPath.get(), otherUrl->mPath.get())));
00301             NS_RELEASE(otherUrl);
00302         }
00303     }
00304     *result = eq;
00305     return NS_OK;
00306 }
00307 
00308 NS_IMETHODIMP
00309 nsSimpleURI::SchemeIs(const char *i_Scheme, PRBool *o_Equals)
00310 {
00311     NS_ENSURE_ARG_POINTER(o_Equals);
00312     if (!i_Scheme) return NS_ERROR_NULL_POINTER;
00313 
00314     const char *this_scheme = mScheme.get();
00315 
00316     // mScheme is guaranteed to be lower case.
00317     if (*i_Scheme == *this_scheme || *i_Scheme == (*this_scheme - ('a' - 'A')) ) {
00318         *o_Equals = PL_strcasecmp(this_scheme, i_Scheme) ? PR_FALSE : PR_TRUE;
00319     } else {
00320         *o_Equals = PR_FALSE;
00321     }
00322 
00323     return NS_OK;
00324 }
00325 
00326 NS_IMETHODIMP
00327 nsSimpleURI::Clone(nsIURI* *result)
00328 {
00329     nsSimpleURI* url = new nsSimpleURI(nsnull);     // XXX outer?
00330     if (url == nsnull)
00331         return NS_ERROR_OUT_OF_MEMORY;
00332 
00333     url->mScheme = mScheme;
00334     url->mPath = mPath;
00335 
00336     *result = url;
00337     NS_ADDREF(url);
00338     return NS_OK;
00339 }
00340 
00341 NS_IMETHODIMP
00342 nsSimpleURI::Resolve(const nsACString &relativePath, nsACString &result) 
00343 {
00344     result = relativePath;
00345     return NS_OK;
00346 }
00347 
00348 NS_IMETHODIMP
00349 nsSimpleURI::GetAsciiSpec(nsACString &result)
00350 {
00351     nsCAutoString buf;
00352     nsresult rv = GetSpec(buf);
00353     if (NS_FAILED(rv)) return rv;
00354     NS_EscapeURL(buf, esc_OnlyNonASCII|esc_AlwaysCopy, result);
00355     return NS_OK;
00356 }
00357 
00358 NS_IMETHODIMP
00359 nsSimpleURI::GetAsciiHost(nsACString &result)
00360 {
00361     result.Truncate();
00362     return NS_OK;
00363 }
00364 
00365 NS_IMETHODIMP
00366 nsSimpleURI::GetOriginCharset(nsACString &result)
00367 {
00368     result.Truncate();
00369     return NS_OK;
00370 }
00371 
00373 
00374 NS_METHOD
00375 nsSimpleURI::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
00376 {
00377     NS_ENSURE_ARG_POINTER(aResult);
00378      NS_ENSURE_PROPER_AGGREGATION(aOuter, aIID);
00379 
00380     nsSimpleURI* url = new nsSimpleURI(aOuter);
00381     if (url == nsnull)
00382         return NS_ERROR_OUT_OF_MEMORY;
00383 
00384     nsresult rv = url->AggregatedQueryInterface(aIID, aResult);
00385 
00386      if (NS_FAILED(rv))
00387          delete url;
00388     return rv;
00389 }
00390 
00392 
00393 
00394 //----------------------------------------------------------------------------
00395 // nsSimpleURI::nsIClassInfo
00396 //----------------------------------------------------------------------------
00397 
00398 NS_IMETHODIMP 
00399 nsSimpleURI::GetInterfaces(PRUint32 *count, nsIID * **array)
00400 {
00401     *count = 0;
00402     *array = nsnull;
00403     return NS_OK;
00404 }
00405 
00406 NS_IMETHODIMP 
00407 nsSimpleURI::GetHelperForLanguage(PRUint32 language, nsISupports **_retval)
00408 {
00409     *_retval = nsnull;
00410     return NS_OK;
00411 }
00412 
00413 NS_IMETHODIMP 
00414 nsSimpleURI::GetContractID(char * *aContractID)
00415 {
00416     *aContractID = nsnull;
00417     return NS_OK;
00418 }
00419 
00420 NS_IMETHODIMP 
00421 nsSimpleURI::GetClassDescription(char * *aClassDescription)
00422 {
00423     *aClassDescription = nsnull;
00424     return NS_OK;
00425 }
00426 
00427 NS_IMETHODIMP 
00428 nsSimpleURI::GetClassID(nsCID * *aClassID)
00429 {
00430     *aClassID = (nsCID*) nsMemory::Alloc(sizeof(nsCID));
00431     if (!*aClassID)
00432         return NS_ERROR_OUT_OF_MEMORY;
00433     return GetClassIDNoAlloc(*aClassID);
00434 }
00435 
00436 NS_IMETHODIMP 
00437 nsSimpleURI::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
00438 {
00439     *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
00440     return NS_OK;
00441 }
00442 
00443 NS_IMETHODIMP 
00444 nsSimpleURI::GetFlags(PRUint32 *aFlags)
00445 {
00446     *aFlags = nsIClassInfo::MAIN_THREAD_ONLY;
00447     return NS_OK;
00448 }
00449 
00450 NS_IMETHODIMP 
00451 nsSimpleURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
00452 {
00453     *aClassIDNoAlloc = kSimpleURICID;
00454     return NS_OK;
00455 }
00456