diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /modules/libjar/nsJARURI.cpp | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'modules/libjar/nsJARURI.cpp')
-rw-r--r-- | modules/libjar/nsJARURI.cpp | 714 |
1 files changed, 714 insertions, 0 deletions
diff --git a/modules/libjar/nsJARURI.cpp b/modules/libjar/nsJARURI.cpp new file mode 100644 index 0000000000..e6837e998f --- /dev/null +++ b/modules/libjar/nsJARURI.cpp @@ -0,0 +1,714 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "base/basictypes.h" + +#include "nsJARURI.h" +#include "nsNetUtil.h" +#include "nsIClassInfoImpl.h" +#include "nsIIOService.h" +#include "nsIStandardURL.h" +#include "nsCRT.h" +#include "nsReadableUtils.h" +#include "nsNetCID.h" +#include "nsIObjectInputStream.h" +#include "nsIObjectOutputStream.h" +#include "nsQueryObject.h" +#include "mozilla/ipc/URIUtils.h" + +using namespace mozilla::ipc; + +//////////////////////////////////////////////////////////////////////////////// + +NS_IMPL_CLASSINFO(nsJARURI, nullptr, nsIClassInfo::THREADSAFE, NS_JARURI_CID) +// Empty CI getter. We only need nsIClassInfo for Serialization +NS_IMPL_CI_INTERFACE_GETTER0(nsJARURI) + +nsJARURI::nsJARURI() {} + +nsJARURI::~nsJARURI() {} + +// XXX Why is this threadsafe? +NS_IMPL_ADDREF(nsJARURI) +NS_IMPL_RELEASE(nsJARURI) +NS_INTERFACE_MAP_BEGIN(nsJARURI) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIJARURI) + NS_INTERFACE_MAP_ENTRY(nsIURI) + NS_INTERFACE_MAP_ENTRY(nsIURL) + NS_INTERFACE_MAP_ENTRY(nsIJARURI) + NS_INTERFACE_MAP_ENTRY(nsISerializable) + NS_IMPL_QUERY_CLASSINFO(nsJARURI) + NS_INTERFACE_MAP_ENTRY(nsINestedURI) + NS_INTERFACE_MAP_ENTRY_CONCRETE(nsJARURI) +NS_INTERFACE_MAP_END + +nsresult nsJARURI::Init(const char* charsetHint) { + mCharsetHint = charsetHint; + return NS_OK; +} + +#define NS_JAR_SCHEME "jar:"_ns +#define NS_JAR_DELIMITER "!/"_ns +#define NS_BOGUS_ENTRY_SCHEME "x:///"_ns + +// FormatSpec takes the entry spec (including the "x:///" at the +// beginning) and gives us a full JAR spec. +nsresult nsJARURI::FormatSpec(const nsACString& entrySpec, nsACString& result, + bool aIncludeScheme) { + // The entrySpec MUST start with "x:///" + NS_ASSERTION(StringBeginsWith(entrySpec, NS_BOGUS_ENTRY_SCHEME), + "bogus entry spec"); + + nsAutoCString fileSpec; + nsresult rv = mJARFile->GetSpec(fileSpec); + if (NS_FAILED(rv)) return rv; + + if (aIncludeScheme) + result = NS_JAR_SCHEME; + else + result.Truncate(); + + result.Append(fileSpec + NS_JAR_DELIMITER + + Substring(entrySpec, 5, entrySpec.Length() - 5)); + return NS_OK; +} + +nsresult nsJARURI::CreateEntryURL(const nsACString& entryFilename, + const char* charset, nsIURL** url) { + *url = nullptr; + // Flatten the concatenation, just in case. See bug 128288 + nsAutoCString spec(NS_BOGUS_ENTRY_SCHEME + entryFilename); + return NS_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID) + .Apply(&nsIStandardURLMutator::Init, nsIStandardURL::URLTYPE_NO_AUTHORITY, + -1, spec, charset, nullptr, nullptr) + .Finalize(url); +} + +//////////////////////////////////////////////////////////////////////////////// +// nsISerializable methods: + +NS_IMETHODIMP +nsJARURI::Read(nsIObjectInputStream* aStream) { + MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +nsresult nsJARURI::ReadPrivate(nsIObjectInputStream* aInputStream) { + nsresult rv; + + nsCOMPtr<nsISupports> supports; + rv = aInputStream->ReadObject(true, getter_AddRefs(supports)); + NS_ENSURE_SUCCESS(rv, rv); + + mJARFile = do_QueryInterface(supports, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aInputStream->ReadObject(true, getter_AddRefs(supports)); + NS_ENSURE_SUCCESS(rv, rv); + + mJAREntry = do_QueryInterface(supports); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aInputStream->ReadCString(mCharsetHint); + return rv; +} + +NS_IMETHODIMP +nsJARURI::Write(nsIObjectOutputStream* aOutputStream) { + nsresult rv; + + rv = aOutputStream->WriteCompoundObject(mJARFile, NS_GET_IID(nsIURI), true); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aOutputStream->WriteCompoundObject(mJAREntry, NS_GET_IID(nsIURL), true); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aOutputStream->WriteStringZ(mCharsetHint.get()); + return rv; +} + +//////////////////////////////////////////////////////////////////////////////// +// nsIURI methods: + +NS_IMETHODIMP +nsJARURI::GetSpec(nsACString& aSpec) { + nsAutoCString entrySpec; + mJAREntry->GetSpec(entrySpec); + return FormatSpec(entrySpec, aSpec); +} + +NS_IMETHODIMP +nsJARURI::GetSpecIgnoringRef(nsACString& aSpec) { + nsAutoCString entrySpec; + mJAREntry->GetSpecIgnoringRef(entrySpec); + return FormatSpec(entrySpec, aSpec); +} + +NS_IMETHODIMP +nsJARURI::GetDisplaySpec(nsACString& aUnicodeSpec) { + return GetSpec(aUnicodeSpec); +} + +NS_IMETHODIMP +nsJARURI::GetDisplayHostPort(nsACString& aUnicodeHostPort) { + return GetHostPort(aUnicodeHostPort); +} + +NS_IMETHODIMP +nsJARURI::GetDisplayPrePath(nsACString& aPrePath) { + return GetPrePath(aPrePath); +} + +NS_IMETHODIMP +nsJARURI::GetDisplayHost(nsACString& aUnicodeHost) { + return GetHost(aUnicodeHost); +} + +NS_IMETHODIMP +nsJARURI::GetHasRef(bool* result) { return mJAREntry->GetHasRef(result); } + +nsresult nsJARURI::SetSpecInternal(const nsACString& aSpec) { + return SetSpecWithBase(aSpec, nullptr); +} + +// Queries this list of interfaces. If none match, it queries mURI. +NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsJARURI::Mutator, nsIURISetters, nsIURIMutator, + nsIURLMutator, nsISerializable, + nsIJARURIMutator) + +NS_IMETHODIMP +nsJARURI::Mutator::SetFileName(const nsACString& aFileName, + nsIURIMutator** aMutator) { + if (!mURI) { + return NS_ERROR_NULL_POINTER; + } + if (aMutator) { + nsCOMPtr<nsIURIMutator> mutator = this; + mutator.forget(aMutator); + } + return mURI->SetFileNameInternal(aFileName); +} + +NS_IMETHODIMP +nsJARURI::Mutator::SetFileBaseName(const nsACString& aFileBaseName, + nsIURIMutator** aMutator) { + if (!mURI) { + return NS_ERROR_NULL_POINTER; + } + if (aMutator) { + nsCOMPtr<nsIURIMutator> mutator = this; + mutator.forget(aMutator); + } + return mURI->SetFileBaseNameInternal(aFileBaseName); +} + +NS_IMETHODIMP +nsJARURI::Mutator::SetFileExtension(const nsACString& aFileExtension, + nsIURIMutator** aMutator) { + if (!mURI) { + return NS_ERROR_NULL_POINTER; + } + if (aMutator) { + nsCOMPtr<nsIURIMutator> mutator = this; + mutator.forget(aMutator); + } + return mURI->SetFileExtensionInternal(aFileExtension); +} + +NS_IMETHODIMP +nsJARURI::Mutate(nsIURIMutator** aMutator) { + RefPtr<nsJARURI::Mutator> mutator = new nsJARURI::Mutator(); + nsresult rv = mutator->InitFromURI(this); + if (NS_FAILED(rv)) { + return rv; + } + mutator.forget(aMutator); + return NS_OK; +} + +nsresult nsJARURI::SetSpecWithBase(const nsACString& aSpec, nsIURI* aBaseURL) { + nsresult rv; + + nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv)); + NS_ENSURE_SUCCESS(rv, rv); + + nsAutoCString scheme; + rv = ioServ->ExtractScheme(aSpec, scheme); + if (NS_FAILED(rv)) { + // not an absolute URI + if (!aBaseURL) return NS_ERROR_MALFORMED_URI; + + RefPtr<nsJARURI> otherJAR = do_QueryObject(aBaseURL); + NS_ENSURE_TRUE(otherJAR, NS_NOINTERFACE); + + mJARFile = otherJAR->mJARFile; + + nsCOMPtr<nsIURI> entry; + + rv = NS_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID) + .Apply(&nsIStandardURLMutator::Init, + nsIStandardURL::URLTYPE_NO_AUTHORITY, -1, aSpec, + mCharsetHint.get(), otherJAR->mJAREntry, nullptr) + .Finalize(entry); + if (NS_FAILED(rv)) { + return rv; + } + + mJAREntry = do_QueryInterface(entry); + if (!mJAREntry) return NS_NOINTERFACE; + + return NS_OK; + } + + NS_ENSURE_TRUE(scheme.EqualsLiteral("jar"), NS_ERROR_MALFORMED_URI); + + nsACString::const_iterator begin, end; + aSpec.BeginReading(begin); + aSpec.EndReading(end); + + while (begin != end && *begin != ':') ++begin; + + ++begin; // now we're past the "jar:" + + nsACString::const_iterator delim_begin = begin; + nsACString::const_iterator delim_end = end; + nsACString::const_iterator frag = begin; + + if (FindInReadable(NS_JAR_DELIMITER, delim_begin, delim_end)) { + frag = delim_end; + } + while (frag != end && (*frag != '#' && *frag != '?')) { + ++frag; + } + if (frag != end) { + // there was a fragment or query, mark that as the end of the URL to scan + end = frag; + } + + // Search backward from the end for the "!/" delimiter. Remember, jar URLs + // can nest, e.g.: + // jar:jar:http://www.foo.com/bar.jar!/a.jar!/b.html + // This gets the b.html document from out of the a.jar file, that's + // contained within the bar.jar file. + // Also, the outermost "inner" URI may be a relative URI: + // jar:../relative.jar!/a.html + + delim_begin = begin; + delim_end = end; + + if (!RFindInReadable(NS_JAR_DELIMITER, delim_begin, delim_end)) { + return NS_ERROR_MALFORMED_URI; + } + + rv = ioServ->NewURI(Substring(begin, delim_begin), mCharsetHint.get(), + aBaseURL, getter_AddRefs(mJARFile)); + if (NS_FAILED(rv)) return rv; + + // skip over any extra '/' chars + while (*delim_end == '/') ++delim_end; + + aSpec.EndReading(end); // set to the original 'end' + return SetJAREntry(Substring(delim_end, end)); +} + +NS_IMETHODIMP +nsJARURI::GetPrePath(nsACString& prePath) { + prePath = NS_JAR_SCHEME; + return NS_OK; +} + +NS_IMETHODIMP +nsJARURI::GetScheme(nsACString& aScheme) { + aScheme = "jar"; + return NS_OK; +} + +nsresult nsJARURI::SetScheme(const nsACString& aScheme) { + // doesn't make sense to set the scheme of a jar: URL + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsJARURI::GetUserPass(nsACString& aUserPass) { return NS_ERROR_FAILURE; } + +nsresult nsJARURI::SetUserPass(const nsACString& aUserPass) { + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsJARURI::GetUsername(nsACString& aUsername) { return NS_ERROR_FAILURE; } + +nsresult nsJARURI::SetUsername(const nsACString& aUsername) { + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsJARURI::GetPassword(nsACString& aPassword) { return NS_ERROR_FAILURE; } + +nsresult nsJARURI::SetPassword(const nsACString& aPassword) { + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsJARURI::GetHostPort(nsACString& aHostPort) { return NS_ERROR_FAILURE; } + +nsresult nsJARURI::SetHostPort(const nsACString& aHostPort) { + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsJARURI::GetHost(nsACString& aHost) { return NS_ERROR_FAILURE; } + +nsresult nsJARURI::SetHost(const nsACString& aHost) { return NS_ERROR_FAILURE; } + +NS_IMETHODIMP +nsJARURI::GetPort(int32_t* aPort) { return NS_ERROR_FAILURE; } + +nsresult nsJARURI::SetPort(int32_t aPort) { return NS_ERROR_FAILURE; } + +nsresult nsJARURI::GetPathQueryRef(nsACString& aPath) { + nsAutoCString entrySpec; + mJAREntry->GetSpec(entrySpec); + return FormatSpec(entrySpec, aPath, false); +} + +nsresult nsJARURI::SetPathQueryRef(const nsACString& aPath) { + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsJARURI::GetAsciiSpec(nsACString& aSpec) { + // XXX Shouldn't this like... make sure it returns ASCII or something? + return GetSpec(aSpec); +} + +NS_IMETHODIMP +nsJARURI::GetAsciiHostPort(nsACString& aHostPort) { return NS_ERROR_FAILURE; } + +NS_IMETHODIMP +nsJARURI::GetAsciiHost(nsACString& aHost) { return NS_ERROR_FAILURE; } + +NS_IMETHODIMP +nsJARURI::Equals(nsIURI* other, bool* result) { + return EqualsInternal(other, eHonorRef, result); +} + +NS_IMETHODIMP +nsJARURI::EqualsExceptRef(nsIURI* other, bool* result) { + return EqualsInternal(other, eIgnoreRef, result); +} + +// Helper method: +/* virtual */ +nsresult nsJARURI::EqualsInternal(nsIURI* other, + nsJARURI::RefHandlingEnum refHandlingMode, + bool* result) { + *result = false; + + if (!other) return NS_OK; // not equal + + RefPtr<nsJARURI> otherJAR = do_QueryObject(other); + if (!otherJAR) return NS_OK; // not equal + + bool equal; + nsresult rv = mJARFile->Equals(otherJAR->mJARFile, &equal); + if (NS_FAILED(rv) || !equal) { + return rv; // not equal + } + + return refHandlingMode == eHonorRef + ? mJAREntry->Equals(otherJAR->mJAREntry, result) + : mJAREntry->EqualsExceptRef(otherJAR->mJAREntry, result); +} + +NS_IMETHODIMP +nsJARURI::SchemeIs(const char* i_Scheme, bool* o_Equals) { + MOZ_ASSERT(o_Equals); + if (!i_Scheme) { + *o_Equals = false; + return NS_OK; + } + + *o_Equals = nsCRT::strcasecmp("jar", i_Scheme) == 0; + return NS_OK; +} + +nsresult nsJARURI::Clone(nsIURI** result) { + RefPtr<nsJARURI> uri = new nsJARURI(); + uri->mJARFile = mJARFile; + uri->mJAREntry = mJAREntry; + uri.forget(result); + + return NS_OK; +} + +NS_IMETHODIMP +nsJARURI::Resolve(const nsACString& relativePath, nsACString& result) { + nsresult rv; + + nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv)); + if (NS_FAILED(rv)) return rv; + + nsAutoCString scheme; + rv = ioServ->ExtractScheme(relativePath, scheme); + if (NS_SUCCEEDED(rv)) { + // then aSpec is absolute + result = relativePath; + return NS_OK; + } + + nsAutoCString resolvedPath; + mJAREntry->Resolve(relativePath, resolvedPath); + + return FormatSpec(resolvedPath, result); +} + +//////////////////////////////////////////////////////////////////////////////// +// nsIURL methods: + +NS_IMETHODIMP +nsJARURI::GetFilePath(nsACString& filePath) { + return mJAREntry->GetFilePath(filePath); +} + +nsresult nsJARURI::SetFilePath(const nsACString& filePath) { + return NS_MutateURI(mJAREntry).SetFilePath(filePath).Finalize(mJAREntry); +} + +NS_IMETHODIMP +nsJARURI::GetQuery(nsACString& query) { return mJAREntry->GetQuery(query); } + +nsresult nsJARURI::SetQuery(const nsACString& query) { + return NS_MutateURI(mJAREntry).SetQuery(query).Finalize(mJAREntry); +} + +nsresult nsJARURI::SetQueryWithEncoding(const nsACString& query, + const mozilla::Encoding* encoding) { + return NS_MutateURI(mJAREntry) + .SetQueryWithEncoding(query, encoding) + .Finalize(mJAREntry); +} + +NS_IMETHODIMP +nsJARURI::GetRef(nsACString& ref) { return mJAREntry->GetRef(ref); } + +nsresult nsJARURI::SetRef(const nsACString& ref) { + return NS_MutateURI(mJAREntry).SetRef(ref).Finalize(mJAREntry); +} + +NS_IMETHODIMP +nsJARURI::GetDirectory(nsACString& directory) { + return mJAREntry->GetDirectory(directory); +} + +NS_IMETHODIMP +nsJARURI::GetFileName(nsACString& fileName) { + return mJAREntry->GetFileName(fileName); +} + +nsresult nsJARURI::SetFileNameInternal(const nsACString& fileName) { + return NS_MutateURI(mJAREntry) + .Apply(&nsIURLMutator::SetFileName, fileName, nullptr) + .Finalize(mJAREntry); +} + +NS_IMETHODIMP +nsJARURI::GetFileBaseName(nsACString& fileBaseName) { + return mJAREntry->GetFileBaseName(fileBaseName); +} + +nsresult nsJARURI::SetFileBaseNameInternal(const nsACString& fileBaseName) { + return NS_MutateURI(mJAREntry) + .Apply(&nsIURLMutator::SetFileBaseName, fileBaseName, nullptr) + .Finalize(mJAREntry); +} + +NS_IMETHODIMP +nsJARURI::GetFileExtension(nsACString& fileExtension) { + return mJAREntry->GetFileExtension(fileExtension); +} + +nsresult nsJARURI::SetFileExtensionInternal(const nsACString& fileExtension) { + return NS_MutateURI(mJAREntry) + .Apply(&nsIURLMutator::SetFileExtension, fileExtension, nullptr) + .Finalize(mJAREntry); +} + +NS_IMETHODIMP +nsJARURI::GetCommonBaseSpec(nsIURI* uriToCompare, nsACString& commonSpec) { + commonSpec.Truncate(); + + NS_ENSURE_ARG_POINTER(uriToCompare); + + commonSpec.Truncate(); + nsCOMPtr<nsIJARURI> otherJARURI(do_QueryInterface(uriToCompare)); + if (!otherJARURI) { + // Nothing in common + return NS_OK; + } + + nsCOMPtr<nsIURI> otherJARFile; + nsresult rv = otherJARURI->GetJARFile(getter_AddRefs(otherJARFile)); + if (NS_FAILED(rv)) return rv; + + bool equal; + rv = mJARFile->Equals(otherJARFile, &equal); + if (NS_FAILED(rv)) return rv; + + if (!equal) { + // See what the JAR file URIs have in common + nsCOMPtr<nsIURL> ourJARFileURL(do_QueryInterface(mJARFile)); + if (!ourJARFileURL) { + // Not a URL, so nothing in common + return NS_OK; + } + nsAutoCString common; + rv = ourJARFileURL->GetCommonBaseSpec(otherJARFile, common); + if (NS_FAILED(rv)) return rv; + + commonSpec = NS_JAR_SCHEME + common; + return NS_OK; + } + + // At this point we have the same JAR file. Compare the JAREntrys + nsAutoCString otherEntry; + rv = otherJARURI->GetJAREntry(otherEntry); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr<nsIURL> url; + rv = CreateEntryURL(otherEntry, nullptr, getter_AddRefs(url)); + if (NS_FAILED(rv)) return rv; + + nsAutoCString common; + rv = mJAREntry->GetCommonBaseSpec(url, common); + if (NS_FAILED(rv)) return rv; + + rv = FormatSpec(common, commonSpec); + return rv; +} + +NS_IMETHODIMP +nsJARURI::GetRelativeSpec(nsIURI* uriToCompare, nsACString& relativeSpec) { + GetSpec(relativeSpec); + + NS_ENSURE_ARG_POINTER(uriToCompare); + + nsCOMPtr<nsIJARURI> otherJARURI(do_QueryInterface(uriToCompare)); + if (!otherJARURI) { + // Nothing in common + return NS_OK; + } + + nsCOMPtr<nsIURI> otherJARFile; + nsresult rv = otherJARURI->GetJARFile(getter_AddRefs(otherJARFile)); + if (NS_FAILED(rv)) return rv; + + bool equal; + rv = mJARFile->Equals(otherJARFile, &equal); + if (NS_FAILED(rv)) return rv; + + if (!equal) { + // We live in different JAR files. Nothing in common. + return rv; + } + + // Same JAR file. Compare the JAREntrys + nsAutoCString otherEntry; + rv = otherJARURI->GetJAREntry(otherEntry); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr<nsIURL> url; + rv = CreateEntryURL(otherEntry, nullptr, getter_AddRefs(url)); + if (NS_FAILED(rv)) return rv; + + nsAutoCString relativeEntrySpec; + rv = mJAREntry->GetRelativeSpec(url, relativeEntrySpec); + if (NS_FAILED(rv)) return rv; + + if (!StringBeginsWith(relativeEntrySpec, NS_BOGUS_ENTRY_SCHEME)) { + // An actual relative spec! + relativeSpec = relativeEntrySpec; + } + return rv; +} + +//////////////////////////////////////////////////////////////////////////////// +// nsIJARURI methods: + +NS_IMETHODIMP +nsJARURI::GetJARFile(nsIURI** jarFile) { return GetInnerURI(jarFile); } + +NS_IMETHODIMP +nsJARURI::GetJAREntry(nsACString& entryPath) { + nsAutoCString filePath; + mJAREntry->GetFilePath(filePath); + NS_ASSERTION(filePath.Length() > 0, "path should never be empty!"); + // Trim off the leading '/' + entryPath = Substring(filePath, 1, filePath.Length() - 1); + return NS_OK; +} + +nsresult nsJARURI::SetJAREntry(const nsACString& entryPath) { + return CreateEntryURL(entryPath, mCharsetHint.get(), + getter_AddRefs(mJAREntry)); +} + +//////////////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP +nsJARURI::GetInnerURI(nsIURI** aURI) { + nsCOMPtr<nsIURI> uri = mJARFile; + uri.forget(aURI); + return NS_OK; +} + +NS_IMETHODIMP +nsJARURI::GetInnermostURI(nsIURI** uri) { + return NS_ImplGetInnermostURI(this, uri); +} + +void nsJARURI::Serialize(URIParams& aParams) { + JARURIParams params; + + SerializeURI(mJARFile, params.jarFile()); + SerializeURI(mJAREntry, params.jarEntry()); + params.charset() = mCharsetHint; + + aParams = params; +} + +bool nsJARURI::Deserialize(const URIParams& aParams) { + if (aParams.type() != URIParams::TJARURIParams) { + NS_ERROR("Received unknown parameters from the other process!"); + return false; + } + + const JARURIParams& params = aParams.get_JARURIParams(); + + nsCOMPtr<nsIURI> file = DeserializeURI(params.jarFile()); + if (!file) { + NS_ERROR("Couldn't deserialize jar file URI!"); + return false; + } + + nsCOMPtr<nsIURI> entry = DeserializeURI(params.jarEntry()); + if (!entry) { + NS_ERROR("Couldn't deserialize jar entry URI!"); + return false; + } + + nsCOMPtr<nsIURL> entryURL = do_QueryInterface(entry); + if (!entryURL) { + NS_ERROR("Couldn't QI jar entry URI to nsIURL!"); + return false; + } + + mJARFile.swap(file); + mJAREntry.swap(entryURL); + mCharsetHint = params.charset(); + + return true; +} |