Bug 562144: Make DTrace hooks pretty. (r=sayrer)
[mozilla-central.git] / modules / libjar / nsJARURI.cpp
blob064ef0a5bd1c6ee0a31309d6c1897fd805e992be
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is mozilla.org Code.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 1998
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
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 #include "nsJARURI.h"
40 #include "nsNetUtil.h"
41 #include "nsIIOService.h"
42 #include "nsIStandardURL.h"
43 #include "nsCRT.h"
44 #include "nsIComponentManager.h"
45 #include "nsIServiceManager.h"
46 #include "nsIZipReader.h"
47 #include "nsReadableUtils.h"
48 #include "nsAutoPtr.h"
49 #include "nsNetCID.h"
50 #include "nsIObjectInputStream.h"
51 #include "nsIObjectOutputStream.h"
52 #include "nsIProgrammingLanguage.h"
54 static NS_DEFINE_CID(kJARURICID, NS_JARURI_CID);
56 ////////////////////////////////////////////////////////////////////////////////
58 nsJARURI::nsJARURI()
62 nsJARURI::~nsJARURI()
66 // XXX Why is this threadsafe?
67 NS_IMPL_THREADSAFE_ADDREF(nsJARURI)
68 NS_IMPL_THREADSAFE_RELEASE(nsJARURI)
69 NS_INTERFACE_MAP_BEGIN(nsJARURI)
70 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIJARURI)
71 NS_INTERFACE_MAP_ENTRY(nsIURI)
72 NS_INTERFACE_MAP_ENTRY(nsIURL)
73 NS_INTERFACE_MAP_ENTRY(nsIJARURI)
74 NS_INTERFACE_MAP_ENTRY(nsISerializable)
75 NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
76 NS_INTERFACE_MAP_ENTRY(nsINestedURI)
77 // see nsJARURI::Equals
78 if (aIID.Equals(NS_GET_IID(nsJARURI)))
79 foundInterface = reinterpret_cast<nsISupports*>(this);
80 else
81 NS_INTERFACE_MAP_END
83 nsresult
84 nsJARURI::Init(const char *charsetHint)
86 mCharsetHint = charsetHint;
87 return NS_OK;
90 #define NS_JAR_SCHEME NS_LITERAL_CSTRING("jar:")
91 #define NS_JAR_DELIMITER NS_LITERAL_CSTRING("!/")
92 #define NS_BOGUS_ENTRY_SCHEME NS_LITERAL_CSTRING("x:///")
94 // FormatSpec takes the entry spec (including the "x:///" at the
95 // beginning) and gives us a full JAR spec.
96 nsresult
97 nsJARURI::FormatSpec(const nsACString &entrySpec, nsACString &result,
98 PRBool aIncludeScheme)
100 // The entrySpec MUST start with "x:///"
101 NS_ASSERTION(StringBeginsWith(entrySpec, NS_BOGUS_ENTRY_SCHEME),
102 "bogus entry spec");
104 nsCAutoString fileSpec;
105 nsresult rv = mJARFile->GetSpec(fileSpec);
106 if (NS_FAILED(rv)) return rv;
108 if (aIncludeScheme)
109 result = NS_JAR_SCHEME;
110 else
111 result.Truncate();
113 result.Append(fileSpec + NS_JAR_DELIMITER +
114 Substring(entrySpec, 5, entrySpec.Length() - 5));
115 return NS_OK;
118 nsresult
119 nsJARURI::CreateEntryURL(const nsACString& entryFilename,
120 const char* charset,
121 nsIURL** url)
123 *url = nsnull;
125 nsCOMPtr<nsIStandardURL> stdURL(do_CreateInstance(NS_STANDARDURL_CONTRACTID));
126 if (!stdURL) {
127 return NS_ERROR_OUT_OF_MEMORY;
130 // Flatten the concatenation, just in case. See bug 128288
131 nsCAutoString spec(NS_BOGUS_ENTRY_SCHEME + entryFilename);
132 nsresult rv = stdURL->Init(nsIStandardURL::URLTYPE_NO_AUTHORITY, -1,
133 spec, charset, nsnull);
134 if (NS_FAILED(rv)) {
135 return rv;
138 return CallQueryInterface(stdURL, url);
141 ////////////////////////////////////////////////////////////////////////////////
142 // nsISerializable methods:
144 NS_IMETHODIMP
145 nsJARURI::Read(nsIObjectInputStream* aInputStream)
147 nsresult rv;
149 rv = aInputStream->ReadObject(PR_TRUE, getter_AddRefs(mJARFile));
150 NS_ENSURE_SUCCESS(rv, rv);
152 rv = aInputStream->ReadObject(PR_TRUE, getter_AddRefs(mJAREntry));
153 NS_ENSURE_SUCCESS(rv, rv);
155 rv = aInputStream->ReadCString(mCharsetHint);
156 return rv;
159 NS_IMETHODIMP
160 nsJARURI::Write(nsIObjectOutputStream* aOutputStream)
162 nsresult rv;
164 rv = aOutputStream->WriteCompoundObject(mJARFile, NS_GET_IID(nsIURI),
165 PR_TRUE);
166 NS_ENSURE_SUCCESS(rv, rv);
168 rv = aOutputStream->WriteCompoundObject(mJAREntry, NS_GET_IID(nsIURL),
169 PR_TRUE);
170 NS_ENSURE_SUCCESS(rv, rv);
172 rv = aOutputStream->WriteStringZ(mCharsetHint.get());
173 return rv;
176 ////////////////////////////////////////////////////////////////////////////////
177 // nsIClassInfo methods:
179 NS_IMETHODIMP
180 nsJARURI::GetInterfaces(PRUint32 *count, nsIID * **array)
182 *count = 0;
183 *array = nsnull;
184 return NS_OK;
187 NS_IMETHODIMP
188 nsJARURI::GetHelperForLanguage(PRUint32 language, nsISupports **_retval)
190 *_retval = nsnull;
191 return NS_OK;
194 NS_IMETHODIMP
195 nsJARURI::GetContractID(char * *aContractID)
197 *aContractID = nsnull;
198 return NS_OK;
201 NS_IMETHODIMP
202 nsJARURI::GetClassDescription(char * *aClassDescription)
204 *aClassDescription = nsnull;
205 return NS_OK;
208 NS_IMETHODIMP
209 nsJARURI::GetClassID(nsCID * *aClassID)
211 *aClassID = (nsCID*) nsMemory::Alloc(sizeof(nsCID));
212 if (!*aClassID)
213 return NS_ERROR_OUT_OF_MEMORY;
214 return GetClassIDNoAlloc(*aClassID);
217 NS_IMETHODIMP
218 nsJARURI::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
220 *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
221 return NS_OK;
224 NS_IMETHODIMP
225 nsJARURI::GetFlags(PRUint32 *aFlags)
227 // XXX We implement THREADSAFE addref/release, but probably shouldn't.
228 *aFlags = nsIClassInfo::MAIN_THREAD_ONLY;
229 return NS_OK;
232 NS_IMETHODIMP
233 nsJARURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
235 *aClassIDNoAlloc = kJARURICID;
236 return NS_OK;
239 ////////////////////////////////////////////////////////////////////////////////
240 // nsIURI methods:
242 NS_IMETHODIMP
243 nsJARURI::GetSpec(nsACString &aSpec)
245 nsCAutoString entrySpec;
246 mJAREntry->GetSpec(entrySpec);
247 return FormatSpec(entrySpec, aSpec);
250 NS_IMETHODIMP
251 nsJARURI::SetSpec(const nsACString& aSpec)
253 return SetSpecWithBase(aSpec, nsnull);
256 nsresult
257 nsJARURI::SetSpecWithBase(const nsACString &aSpec, nsIURI* aBaseURL)
259 nsresult rv;
261 nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv));
262 NS_ENSURE_SUCCESS(rv, rv);
264 nsCAutoString scheme;
265 rv = ioServ->ExtractScheme(aSpec, scheme);
266 if (NS_FAILED(rv)) {
267 // not an absolute URI
268 if (!aBaseURL)
269 return NS_ERROR_MALFORMED_URI;
271 nsRefPtr<nsJARURI> otherJAR;
272 aBaseURL->QueryInterface(NS_GET_IID(nsJARURI), getter_AddRefs(otherJAR));
273 NS_ENSURE_TRUE(otherJAR, NS_NOINTERFACE);
275 mJARFile = otherJAR->mJARFile;
277 nsCOMPtr<nsIStandardURL> entry(do_CreateInstance(NS_STANDARDURL_CONTRACTID));
278 if (!entry)
279 return NS_ERROR_OUT_OF_MEMORY;
281 rv = entry->Init(nsIStandardURL::URLTYPE_NO_AUTHORITY, -1,
282 aSpec, mCharsetHint.get(), otherJAR->mJAREntry);
283 if (NS_FAILED(rv))
284 return rv;
286 mJAREntry = do_QueryInterface(entry);
287 if (!mJAREntry)
288 return NS_NOINTERFACE;
290 return NS_OK;
293 NS_ENSURE_TRUE(scheme.EqualsLiteral("jar"), NS_ERROR_MALFORMED_URI);
295 nsACString::const_iterator begin, end;
296 aSpec.BeginReading(begin);
297 aSpec.EndReading(end);
299 while (begin != end && *begin != ':')
300 ++begin;
302 ++begin; // now we're past the "jar:"
304 // Search backward from the end for the "!/" delimiter. Remember, jar URLs
305 // can nest, e.g.:
306 // jar:jar:http://www.foo.com/bar.jar!/a.jar!/b.html
307 // This gets the b.html document from out of the a.jar file, that's
308 // contained within the bar.jar file.
309 // Also, the outermost "inner" URI may be a relative URI:
310 // jar:../relative.jar!/a.html
312 nsACString::const_iterator delim_begin (begin),
313 delim_end (end);
315 if (!RFindInReadable(NS_JAR_DELIMITER, delim_begin, delim_end))
316 return NS_ERROR_MALFORMED_URI;
318 rv = ioServ->NewURI(Substring(begin, delim_begin), mCharsetHint.get(),
319 aBaseURL, getter_AddRefs(mJARFile));
320 if (NS_FAILED(rv)) return rv;
322 NS_TryToSetImmutable(mJARFile);
324 // skip over any extra '/' chars
325 while (*delim_end == '/')
326 ++delim_end;
328 return SetJAREntry(Substring(delim_end, end));
331 NS_IMETHODIMP
332 nsJARURI::GetPrePath(nsACString &prePath)
334 prePath = NS_JAR_SCHEME;
335 return NS_OK;
338 NS_IMETHODIMP
339 nsJARURI::GetScheme(nsACString &aScheme)
341 aScheme = "jar";
342 return NS_OK;
345 NS_IMETHODIMP
346 nsJARURI::SetScheme(const nsACString &aScheme)
348 // doesn't make sense to set the scheme of a jar: URL
349 return NS_ERROR_FAILURE;
352 NS_IMETHODIMP
353 nsJARURI::GetUserPass(nsACString &aUserPass)
355 return NS_ERROR_FAILURE;
358 NS_IMETHODIMP
359 nsJARURI::SetUserPass(const nsACString &aUserPass)
361 return NS_ERROR_FAILURE;
364 NS_IMETHODIMP
365 nsJARURI::GetUsername(nsACString &aUsername)
367 return NS_ERROR_FAILURE;
370 NS_IMETHODIMP
371 nsJARURI::SetUsername(const nsACString &aUsername)
373 return NS_ERROR_FAILURE;
376 NS_IMETHODIMP
377 nsJARURI::GetPassword(nsACString &aPassword)
379 return NS_ERROR_FAILURE;
382 NS_IMETHODIMP
383 nsJARURI::SetPassword(const nsACString &aPassword)
385 return NS_ERROR_FAILURE;
388 NS_IMETHODIMP
389 nsJARURI::GetHostPort(nsACString &aHostPort)
391 return NS_ERROR_FAILURE;
394 NS_IMETHODIMP
395 nsJARURI::SetHostPort(const nsACString &aHostPort)
397 return NS_ERROR_FAILURE;
400 NS_IMETHODIMP
401 nsJARURI::GetHost(nsACString &aHost)
403 return NS_ERROR_FAILURE;
406 NS_IMETHODIMP
407 nsJARURI::SetHost(const nsACString &aHost)
409 return NS_ERROR_FAILURE;
412 NS_IMETHODIMP
413 nsJARURI::GetPort(PRInt32 *aPort)
415 return NS_ERROR_FAILURE;
418 NS_IMETHODIMP
419 nsJARURI::SetPort(PRInt32 aPort)
421 return NS_ERROR_FAILURE;
424 NS_IMETHODIMP
425 nsJARURI::GetPath(nsACString &aPath)
427 nsCAutoString entrySpec;
428 mJAREntry->GetSpec(entrySpec);
429 return FormatSpec(entrySpec, aPath, PR_FALSE);
432 NS_IMETHODIMP
433 nsJARURI::SetPath(const nsACString &aPath)
435 return NS_ERROR_FAILURE;
438 NS_IMETHODIMP
439 nsJARURI::GetAsciiSpec(nsACString &aSpec)
441 // XXX Shouldn't this like... make sure it returns ASCII or something?
442 return GetSpec(aSpec);
445 NS_IMETHODIMP
446 nsJARURI::GetAsciiHost(nsACString &aHost)
448 return NS_ERROR_FAILURE;
451 NS_IMETHODIMP
452 nsJARURI::GetOriginCharset(nsACString &aOriginCharset)
454 aOriginCharset = mCharsetHint;
455 return NS_OK;
458 NS_IMETHODIMP
459 nsJARURI::Equals(nsIURI *other, PRBool *result)
461 nsresult rv;
463 *result = PR_FALSE;
465 if (other == nsnull)
466 return NS_OK; // not equal
468 nsRefPtr<nsJARURI> otherJAR;
469 other->QueryInterface(NS_GET_IID(nsJARURI), getter_AddRefs(otherJAR));
470 if (!otherJAR)
471 return NS_OK; // not equal
473 PRBool equal;
474 rv = mJARFile->Equals(otherJAR->mJARFile, &equal);
475 if (NS_FAILED(rv) || !equal) {
476 return rv; // not equal
479 rv = mJAREntry->Equals(otherJAR->mJAREntry, result);
480 return rv;
483 NS_IMETHODIMP
484 nsJARURI::SchemeIs(const char *i_Scheme, PRBool *o_Equals)
486 NS_ENSURE_ARG_POINTER(o_Equals);
487 if (!i_Scheme) return NS_ERROR_INVALID_ARG;
489 if (*i_Scheme == 'j' || *i_Scheme == 'J') {
490 *o_Equals = PL_strcasecmp("jar", i_Scheme) ? PR_FALSE : PR_TRUE;
491 } else {
492 *o_Equals = PR_FALSE;
494 return NS_OK;
497 NS_IMETHODIMP
498 nsJARURI::Clone(nsIURI **result)
500 nsresult rv;
502 nsCOMPtr<nsIJARURI> uri;
503 rv = CloneWithJARFile(mJARFile, getter_AddRefs(uri));
504 if (NS_FAILED(rv)) return rv;
506 return CallQueryInterface(uri, result);
509 NS_IMETHODIMP
510 nsJARURI::Resolve(const nsACString &relativePath, nsACString &result)
512 nsresult rv;
514 nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv));
515 if (NS_FAILED(rv))
516 return rv;
518 nsCAutoString scheme;
519 rv = ioServ->ExtractScheme(relativePath, scheme);
520 if (NS_SUCCEEDED(rv)) {
521 // then aSpec is absolute
522 result = relativePath;
523 return NS_OK;
526 nsCAutoString resolvedPath;
527 mJAREntry->Resolve(relativePath, resolvedPath);
529 return FormatSpec(resolvedPath, result);
532 ////////////////////////////////////////////////////////////////////////////////
533 // nsIURL methods:
535 NS_IMETHODIMP
536 nsJARURI::GetFilePath(nsACString& filePath)
538 return mJAREntry->GetFilePath(filePath);
541 NS_IMETHODIMP
542 nsJARURI::SetFilePath(const nsACString& filePath)
544 return mJAREntry->SetFilePath(filePath);
547 NS_IMETHODIMP
548 nsJARURI::GetParam(nsACString& param)
550 param.Truncate();
551 return NS_OK;
554 NS_IMETHODIMP
555 nsJARURI::SetParam(const nsACString& param)
557 return NS_ERROR_NOT_AVAILABLE;
560 NS_IMETHODIMP
561 nsJARURI::GetQuery(nsACString& query)
563 return mJAREntry->GetQuery(query);
566 NS_IMETHODIMP
567 nsJARURI::SetQuery(const nsACString& query)
569 return mJAREntry->SetQuery(query);
572 NS_IMETHODIMP
573 nsJARURI::GetRef(nsACString& ref)
575 return mJAREntry->GetRef(ref);
578 NS_IMETHODIMP
579 nsJARURI::SetRef(const nsACString& ref)
581 return mJAREntry->SetRef(ref);
584 NS_IMETHODIMP
585 nsJARURI::GetDirectory(nsACString& directory)
587 return mJAREntry->GetDirectory(directory);
590 NS_IMETHODIMP
591 nsJARURI::SetDirectory(const nsACString& directory)
593 return mJAREntry->SetDirectory(directory);
596 NS_IMETHODIMP
597 nsJARURI::GetFileName(nsACString& fileName)
599 return mJAREntry->GetFileName(fileName);
602 NS_IMETHODIMP
603 nsJARURI::SetFileName(const nsACString& fileName)
605 return mJAREntry->SetFileName(fileName);
608 NS_IMETHODIMP
609 nsJARURI::GetFileBaseName(nsACString& fileBaseName)
611 return mJAREntry->GetFileBaseName(fileBaseName);
614 NS_IMETHODIMP
615 nsJARURI::SetFileBaseName(const nsACString& fileBaseName)
617 return mJAREntry->SetFileBaseName(fileBaseName);
620 NS_IMETHODIMP
621 nsJARURI::GetFileExtension(nsACString& fileExtension)
623 return mJAREntry->GetFileExtension(fileExtension);
626 NS_IMETHODIMP
627 nsJARURI::SetFileExtension(const nsACString& fileExtension)
629 return mJAREntry->SetFileExtension(fileExtension);
632 NS_IMETHODIMP
633 nsJARURI::GetCommonBaseSpec(nsIURI* uriToCompare, nsACString& commonSpec)
635 commonSpec.Truncate();
637 NS_ENSURE_ARG_POINTER(uriToCompare);
639 commonSpec.Truncate();
640 nsCOMPtr<nsIJARURI> otherJARURI(do_QueryInterface(uriToCompare));
641 if (!otherJARURI) {
642 // Nothing in common
643 return NS_OK;
646 nsCOMPtr<nsIURI> otherJARFile;
647 nsresult rv = otherJARURI->GetJARFile(getter_AddRefs(otherJARFile));
648 if (NS_FAILED(rv)) return rv;
650 PRBool equal;
651 rv = mJARFile->Equals(otherJARFile, &equal);
652 if (NS_FAILED(rv)) return rv;
654 if (!equal) {
655 // See what the JAR file URIs have in common
656 nsCOMPtr<nsIURL> ourJARFileURL(do_QueryInterface(mJARFile));
657 if (!ourJARFileURL) {
658 // Not a URL, so nothing in common
659 return NS_OK;
661 nsCAutoString common;
662 rv = ourJARFileURL->GetCommonBaseSpec(otherJARFile, common);
663 if (NS_FAILED(rv)) return rv;
665 commonSpec = NS_JAR_SCHEME + common;
666 return NS_OK;
670 // At this point we have the same JAR file. Compare the JAREntrys
671 nsCAutoString otherEntry;
672 rv = otherJARURI->GetJAREntry(otherEntry);
673 if (NS_FAILED(rv)) return rv;
675 nsCAutoString otherCharset;
676 rv = uriToCompare->GetOriginCharset(otherCharset);
677 if (NS_FAILED(rv)) return rv;
679 nsCOMPtr<nsIURL> url;
680 rv = CreateEntryURL(otherEntry, otherCharset.get(), getter_AddRefs(url));
681 if (NS_FAILED(rv)) return rv;
683 nsCAutoString common;
684 rv = mJAREntry->GetCommonBaseSpec(url, common);
685 if (NS_FAILED(rv)) return rv;
687 rv = FormatSpec(common, commonSpec);
688 return rv;
691 NS_IMETHODIMP
692 nsJARURI::GetRelativeSpec(nsIURI* uriToCompare, nsACString& relativeSpec)
694 GetSpec(relativeSpec);
696 NS_ENSURE_ARG_POINTER(uriToCompare);
698 nsCOMPtr<nsIJARURI> otherJARURI(do_QueryInterface(uriToCompare));
699 if (!otherJARURI) {
700 // Nothing in common
701 return NS_OK;
704 nsCOMPtr<nsIURI> otherJARFile;
705 nsresult rv = otherJARURI->GetJARFile(getter_AddRefs(otherJARFile));
706 if (NS_FAILED(rv)) return rv;
708 PRBool equal;
709 rv = mJARFile->Equals(otherJARFile, &equal);
710 if (NS_FAILED(rv)) return rv;
712 if (!equal) {
713 // We live in different JAR files. Nothing in common.
714 return rv;
717 // Same JAR file. Compare the JAREntrys
718 nsCAutoString otherEntry;
719 rv = otherJARURI->GetJAREntry(otherEntry);
720 if (NS_FAILED(rv)) return rv;
722 nsCAutoString otherCharset;
723 rv = uriToCompare->GetOriginCharset(otherCharset);
724 if (NS_FAILED(rv)) return rv;
726 nsCOMPtr<nsIURL> url;
727 rv = CreateEntryURL(otherEntry, otherCharset.get(), getter_AddRefs(url));
728 if (NS_FAILED(rv)) return rv;
730 nsCAutoString relativeEntrySpec;
731 rv = mJAREntry->GetRelativeSpec(url, relativeEntrySpec);
732 if (NS_FAILED(rv)) return rv;
734 if (!StringBeginsWith(relativeEntrySpec, NS_BOGUS_ENTRY_SCHEME)) {
735 // An actual relative spec!
736 relativeSpec = relativeEntrySpec;
738 return rv;
741 ////////////////////////////////////////////////////////////////////////////////
742 // nsIJARURI methods:
744 NS_IMETHODIMP
745 nsJARURI::GetJARFile(nsIURI* *jarFile)
747 return GetInnerURI(jarFile);
750 NS_IMETHODIMP
751 nsJARURI::GetJAREntry(nsACString &entryPath)
753 nsCAutoString filePath;
754 mJAREntry->GetFilePath(filePath);
755 NS_ASSERTION(filePath.Length() > 0, "path should never be empty!");
756 // Trim off the leading '/'
757 entryPath = Substring(filePath, 1, filePath.Length() - 1);
758 return NS_OK;
761 NS_IMETHODIMP
762 nsJARURI::SetJAREntry(const nsACString &entryPath)
764 return CreateEntryURL(entryPath, mCharsetHint.get(),
765 getter_AddRefs(mJAREntry));
768 NS_IMETHODIMP
769 nsJARURI::CloneWithJARFile(nsIURI *jarFile, nsIJARURI **result)
771 if (!jarFile) {
772 return NS_ERROR_INVALID_ARG;
775 nsresult rv;
777 nsCOMPtr<nsIURI> newJARFile;
778 rv = jarFile->Clone(getter_AddRefs(newJARFile));
779 if (NS_FAILED(rv)) return rv;
781 NS_TryToSetImmutable(newJARFile);
783 nsCOMPtr<nsIURI> newJAREntryURI;
784 rv = mJAREntry->Clone(getter_AddRefs(newJAREntryURI));
785 if (NS_FAILED(rv)) return rv;
787 nsCOMPtr<nsIURL> newJAREntry(do_QueryInterface(newJAREntryURI));
788 NS_ASSERTION(newJAREntry, "This had better QI to nsIURL!");
790 nsJARURI* uri = new nsJARURI();
791 if (uri) {
792 NS_ADDREF(uri);
793 uri->mJARFile = newJARFile;
794 uri->mJAREntry = newJAREntry;
795 *result = uri;
796 rv = NS_OK;
797 } else {
798 rv = NS_ERROR_OUT_OF_MEMORY;
801 return rv;
804 ////////////////////////////////////////////////////////////////////////////////
806 NS_IMETHODIMP
807 nsJARURI::GetInnerURI(nsIURI **uri)
809 return NS_EnsureSafeToReturn(mJARFile, uri);
812 NS_IMETHODIMP
813 nsJARURI::GetInnermostURI(nsIURI** uri)
815 return NS_ImplGetInnermostURI(this, uri);