/* -*- 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 "nsNetCID.h" #include "nsNetUtil.h" #include "nsSimpleNestedURI.h" #include "nsIObjectInputStream.h" #include "nsIObjectOutputStream.h" #include "mozilla/ipc/URIUtils.h" namespace mozilla { namespace net { NS_IMPL_CLASSINFO(nsSimpleNestedURI, nullptr, nsIClassInfo::THREADSAFE, NS_SIMPLENESTEDURI_CID) // Empty CI getter. We only need nsIClassInfo for Serialization NS_IMPL_CI_INTERFACE_GETTER0(nsSimpleNestedURI) NS_IMPL_ADDREF_INHERITED(nsSimpleNestedURI, nsSimpleURI) NS_IMPL_RELEASE_INHERITED(nsSimpleNestedURI, nsSimpleURI) NS_IMPL_QUERY_INTERFACE_CI_INHERITED(nsSimpleNestedURI, nsSimpleURI, nsINestedURI) nsSimpleNestedURI::nsSimpleNestedURI(nsIURI* innerURI) : mInnerURI(innerURI) { NS_ASSERTION(innerURI, "Must have inner URI"); } nsresult nsSimpleNestedURI::SetPathQueryRef(const nsACString& aPathQueryRef) { NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED); nsCOMPtr inner; nsresult rv = NS_MutateURI(mInnerURI).SetPathQueryRef(aPathQueryRef).Finalize(inner); NS_ENSURE_SUCCESS(rv, rv); rv = nsSimpleURI::SetPathQueryRef(aPathQueryRef); NS_ENSURE_SUCCESS(rv, rv); // If the regular SetPathQueryRef worked, also set it on the inner URI mInnerURI = inner; return NS_OK; } nsresult nsSimpleNestedURI::SetQuery(const nsACString& aQuery) { NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED); nsCOMPtr inner; nsresult rv = NS_MutateURI(mInnerURI).SetQuery(aQuery).Finalize(inner); NS_ENSURE_SUCCESS(rv, rv); rv = nsSimpleURI::SetQuery(aQuery); NS_ENSURE_SUCCESS(rv, rv); // If the regular SetQuery worked, also set it on the inner URI mInnerURI = inner; return NS_OK; } nsresult nsSimpleNestedURI::SetRef(const nsACString& aRef) { NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED); nsCOMPtr inner; nsresult rv = NS_MutateURI(mInnerURI).SetRef(aRef).Finalize(inner); NS_ENSURE_SUCCESS(rv, rv); rv = nsSimpleURI::SetRef(aRef); NS_ENSURE_SUCCESS(rv, rv); // If the regular SetRef worked, also set it on the inner URI mInnerURI = inner; return NS_OK; } // nsISerializable NS_IMETHODIMP nsSimpleNestedURI::Read(nsIObjectInputStream* aStream) { MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead"); return NS_ERROR_NOT_IMPLEMENTED; } nsresult nsSimpleNestedURI::ReadPrivate(nsIObjectInputStream* aStream) { nsresult rv = nsSimpleURI::ReadPrivate(aStream); if (NS_FAILED(rv)) return rv; nsCOMPtr supports; rv = aStream->ReadObject(true, getter_AddRefs(supports)); if (NS_FAILED(rv)) return rv; mInnerURI = do_QueryInterface(supports, &rv); if (NS_FAILED(rv)) return rv; return rv; } NS_IMETHODIMP nsSimpleNestedURI::Write(nsIObjectOutputStream* aStream) { nsCOMPtr serializable = do_QueryInterface(mInnerURI); if (!serializable) { // We can't serialize ourselves return NS_ERROR_NOT_AVAILABLE; } nsresult rv = nsSimpleURI::Write(aStream); if (NS_FAILED(rv)) return rv; rv = aStream->WriteCompoundObject(mInnerURI, NS_GET_IID(nsIURI), true); return rv; } NS_IMETHODIMP_(void) nsSimpleNestedURI::Serialize(mozilla::ipc::URIParams& aParams) { using namespace mozilla::ipc; SimpleNestedURIParams params; URIParams simpleParams; nsSimpleURI::Serialize(simpleParams); params.simpleParams() = simpleParams; SerializeURI(mInnerURI, params.innerURI()); aParams = params; } bool nsSimpleNestedURI::Deserialize(const mozilla::ipc::URIParams& aParams) { using namespace mozilla::ipc; if (aParams.type() != URIParams::TSimpleNestedURIParams) { NS_ERROR("Received unknown parameters from the other process!"); return false; } const SimpleNestedURIParams& params = aParams.get_SimpleNestedURIParams(); if (!nsSimpleURI::Deserialize(params.simpleParams())) return false; mInnerURI = DeserializeURI(params.innerURI()); return true; } // nsINestedURI NS_IMETHODIMP nsSimpleNestedURI::GetInnerURI(nsIURI** aURI) { NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED); nsCOMPtr uri = mInnerURI; uri.forget(aURI); return NS_OK; } NS_IMETHODIMP nsSimpleNestedURI::GetInnermostURI(nsIURI** uri) { return NS_ImplGetInnermostURI(this, uri); } // nsSimpleURI overrides /* virtual */ nsresult nsSimpleNestedURI::EqualsInternal( nsIURI* other, nsSimpleURI::RefHandlingEnum refHandlingMode, bool* result) { *result = false; NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED); if (other) { bool correctScheme; nsresult rv = other->SchemeIs(mScheme.get(), &correctScheme); NS_ENSURE_SUCCESS(rv, rv); if (correctScheme) { nsCOMPtr nest = do_QueryInterface(other); if (nest) { nsCOMPtr otherInner; rv = nest->GetInnerURI(getter_AddRefs(otherInner)); NS_ENSURE_SUCCESS(rv, rv); return (refHandlingMode == eHonorRef) ? otherInner->Equals(mInnerURI, result) : otherInner->EqualsExceptRef(mInnerURI, result); } } } return NS_OK; } /* virtual */ nsSimpleURI* nsSimpleNestedURI::StartClone( nsSimpleURI::RefHandlingEnum refHandlingMode, const nsACString& newRef) { NS_ENSURE_TRUE(mInnerURI, nullptr); nsCOMPtr innerClone; nsresult rv = NS_OK; if (refHandlingMode == eHonorRef) { innerClone = mInnerURI; } else if (refHandlingMode == eReplaceRef) { rv = NS_GetURIWithNewRef(mInnerURI, newRef, getter_AddRefs(innerClone)); } else { rv = NS_GetURIWithoutRef(mInnerURI, getter_AddRefs(innerClone)); } if (NS_FAILED(rv)) { return nullptr; } nsSimpleNestedURI* url = new nsSimpleNestedURI(innerClone); SetRefOnClone(url, refHandlingMode, newRef); return url; } // Queries this list of interfaces. If none match, it queries mURI. NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsSimpleNestedURI::Mutator, nsIURISetters, nsIURIMutator, nsISerializable, nsINestedURIMutator) NS_IMETHODIMP nsSimpleNestedURI::Mutate(nsIURIMutator** aMutator) { RefPtr mutator = new nsSimpleNestedURI::Mutator(); nsresult rv = mutator->InitFromURI(this); if (NS_FAILED(rv)) { return rv; } mutator.forget(aMutator); return NS_OK; } } // namespace net } // namespace mozilla