1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "base/basictypes.h"
7
8 #include "nsNetCID.h"
9 #include "nsNetUtil.h"
10 #include "nsSimpleNestedURI.h"
11 #include "nsIObjectInputStream.h"
12 #include "nsIObjectOutputStream.h"
13
14 #include "mozilla/ipc/URIUtils.h"
15
16 namespace mozilla {
17 namespace net {
18
NS_IMPL_CLASSINFO(nsSimpleNestedURI,nullptr,nsIClassInfo::THREADSAFE,NS_SIMPLENESTEDURI_CID)19 NS_IMPL_CLASSINFO(nsSimpleNestedURI, nullptr, nsIClassInfo::THREADSAFE,
20 NS_SIMPLENESTEDURI_CID)
21 // Empty CI getter. We only need nsIClassInfo for Serialization
22 NS_IMPL_CI_INTERFACE_GETTER0(nsSimpleNestedURI)
23
24 NS_IMPL_ADDREF_INHERITED(nsSimpleNestedURI, nsSimpleURI)
25 NS_IMPL_RELEASE_INHERITED(nsSimpleNestedURI, nsSimpleURI)
26 NS_IMPL_QUERY_INTERFACE_CI_INHERITED(nsSimpleNestedURI, nsSimpleURI,
27 nsINestedURI)
28
29 nsSimpleNestedURI::nsSimpleNestedURI(nsIURI* innerURI) : mInnerURI(innerURI) {
30 NS_ASSERTION(innerURI, "Must have inner URI");
31 }
32
SetPathQueryRef(const nsACString & aPathQueryRef)33 nsresult nsSimpleNestedURI::SetPathQueryRef(const nsACString& aPathQueryRef) {
34 NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
35
36 nsCOMPtr<nsIURI> inner;
37 nsresult rv =
38 NS_MutateURI(mInnerURI).SetPathQueryRef(aPathQueryRef).Finalize(inner);
39 NS_ENSURE_SUCCESS(rv, rv);
40 rv = nsSimpleURI::SetPathQueryRef(aPathQueryRef);
41 NS_ENSURE_SUCCESS(rv, rv);
42 // If the regular SetPathQueryRef worked, also set it on the inner URI
43 mInnerURI = inner;
44 return NS_OK;
45 }
46
SetQuery(const nsACString & aQuery)47 nsresult nsSimpleNestedURI::SetQuery(const nsACString& aQuery) {
48 NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
49
50 nsCOMPtr<nsIURI> inner;
51 nsresult rv = NS_MutateURI(mInnerURI).SetQuery(aQuery).Finalize(inner);
52 NS_ENSURE_SUCCESS(rv, rv);
53 rv = nsSimpleURI::SetQuery(aQuery);
54 NS_ENSURE_SUCCESS(rv, rv);
55 // If the regular SetQuery worked, also set it on the inner URI
56 mInnerURI = inner;
57 return NS_OK;
58 }
59
SetRef(const nsACString & aRef)60 nsresult nsSimpleNestedURI::SetRef(const nsACString& aRef) {
61 NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
62
63 nsCOMPtr<nsIURI> inner;
64 nsresult rv = NS_MutateURI(mInnerURI).SetRef(aRef).Finalize(inner);
65 NS_ENSURE_SUCCESS(rv, rv);
66 rv = nsSimpleURI::SetRef(aRef);
67 NS_ENSURE_SUCCESS(rv, rv);
68 // If the regular SetRef worked, also set it on the inner URI
69 mInnerURI = inner;
70 return NS_OK;
71 }
72
73 // nsISerializable
74
75 NS_IMETHODIMP
Read(nsIObjectInputStream * aStream)76 nsSimpleNestedURI::Read(nsIObjectInputStream* aStream) {
77 MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead");
78 return NS_ERROR_NOT_IMPLEMENTED;
79 }
80
ReadPrivate(nsIObjectInputStream * aStream)81 nsresult nsSimpleNestedURI::ReadPrivate(nsIObjectInputStream* aStream) {
82 nsresult rv = nsSimpleURI::ReadPrivate(aStream);
83 if (NS_FAILED(rv)) return rv;
84
85 nsCOMPtr<nsISupports> supports;
86 rv = aStream->ReadObject(true, getter_AddRefs(supports));
87 if (NS_FAILED(rv)) return rv;
88
89 mInnerURI = do_QueryInterface(supports, &rv);
90 if (NS_FAILED(rv)) return rv;
91
92 return rv;
93 }
94
95 NS_IMETHODIMP
Write(nsIObjectOutputStream * aStream)96 nsSimpleNestedURI::Write(nsIObjectOutputStream* aStream) {
97 nsCOMPtr<nsISerializable> serializable = do_QueryInterface(mInnerURI);
98 if (!serializable) {
99 // We can't serialize ourselves
100 return NS_ERROR_NOT_AVAILABLE;
101 }
102
103 nsresult rv = nsSimpleURI::Write(aStream);
104 if (NS_FAILED(rv)) return rv;
105
106 rv = aStream->WriteCompoundObject(mInnerURI, NS_GET_IID(nsIURI), true);
107 return rv;
108 }
109
NS_IMETHODIMP_(void)110 NS_IMETHODIMP_(void)
111 nsSimpleNestedURI::Serialize(mozilla::ipc::URIParams& aParams) {
112 using namespace mozilla::ipc;
113
114 SimpleNestedURIParams params;
115 URIParams simpleParams;
116
117 nsSimpleURI::Serialize(simpleParams);
118 params.simpleParams() = simpleParams;
119
120 SerializeURI(mInnerURI, params.innerURI());
121
122 aParams = params;
123 }
124
Deserialize(const mozilla::ipc::URIParams & aParams)125 bool nsSimpleNestedURI::Deserialize(const mozilla::ipc::URIParams& aParams) {
126 using namespace mozilla::ipc;
127
128 if (aParams.type() != URIParams::TSimpleNestedURIParams) {
129 NS_ERROR("Received unknown parameters from the other process!");
130 return false;
131 }
132
133 const SimpleNestedURIParams& params = aParams.get_SimpleNestedURIParams();
134 if (!nsSimpleURI::Deserialize(params.simpleParams())) return false;
135
136 mInnerURI = DeserializeURI(params.innerURI());
137 return true;
138 }
139
140 // nsINestedURI
141
142 NS_IMETHODIMP
GetInnerURI(nsIURI ** aURI)143 nsSimpleNestedURI::GetInnerURI(nsIURI** aURI) {
144 NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
145
146 nsCOMPtr<nsIURI> uri = mInnerURI;
147 uri.forget(aURI);
148 return NS_OK;
149 }
150
151 NS_IMETHODIMP
GetInnermostURI(nsIURI ** uri)152 nsSimpleNestedURI::GetInnermostURI(nsIURI** uri) {
153 return NS_ImplGetInnermostURI(this, uri);
154 }
155
156 // nsSimpleURI overrides
157 /* virtual */
EqualsInternal(nsIURI * other,nsSimpleURI::RefHandlingEnum refHandlingMode,bool * result)158 nsresult nsSimpleNestedURI::EqualsInternal(
159 nsIURI* other, nsSimpleURI::RefHandlingEnum refHandlingMode, bool* result) {
160 *result = false;
161 NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
162
163 if (other) {
164 bool correctScheme;
165 nsresult rv = other->SchemeIs(mScheme.get(), &correctScheme);
166 NS_ENSURE_SUCCESS(rv, rv);
167
168 if (correctScheme) {
169 nsCOMPtr<nsINestedURI> nest = do_QueryInterface(other);
170 if (nest) {
171 nsCOMPtr<nsIURI> otherInner;
172 rv = nest->GetInnerURI(getter_AddRefs(otherInner));
173 NS_ENSURE_SUCCESS(rv, rv);
174
175 return (refHandlingMode == eHonorRef)
176 ? otherInner->Equals(mInnerURI, result)
177 : otherInner->EqualsExceptRef(mInnerURI, result);
178 }
179 }
180 }
181
182 return NS_OK;
183 }
184
185 /* virtual */
StartClone(nsSimpleURI::RefHandlingEnum refHandlingMode,const nsACString & newRef)186 nsSimpleURI* nsSimpleNestedURI::StartClone(
187 nsSimpleURI::RefHandlingEnum refHandlingMode, const nsACString& newRef) {
188 NS_ENSURE_TRUE(mInnerURI, nullptr);
189
190 nsCOMPtr<nsIURI> innerClone;
191 nsresult rv = NS_OK;
192 if (refHandlingMode == eHonorRef) {
193 innerClone = mInnerURI;
194 } else if (refHandlingMode == eReplaceRef) {
195 rv = NS_GetURIWithNewRef(mInnerURI, newRef, getter_AddRefs(innerClone));
196 } else {
197 rv = NS_GetURIWithoutRef(mInnerURI, getter_AddRefs(innerClone));
198 }
199
200 if (NS_FAILED(rv)) {
201 return nullptr;
202 }
203
204 nsSimpleNestedURI* url = new nsSimpleNestedURI(innerClone);
205 SetRefOnClone(url, refHandlingMode, newRef);
206
207 return url;
208 }
209
210 // Queries this list of interfaces. If none match, it queries mURI.
NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsSimpleNestedURI::Mutator,nsIURISetters,nsIURIMutator,nsISerializable,nsINestedURIMutator)211 NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsSimpleNestedURI::Mutator, nsIURISetters,
212 nsIURIMutator, nsISerializable,
213 nsINestedURIMutator)
214
215 NS_IMETHODIMP
216 nsSimpleNestedURI::Mutate(nsIURIMutator** aMutator) {
217 RefPtr<nsSimpleNestedURI::Mutator> mutator = new nsSimpleNestedURI::Mutator();
218 nsresult rv = mutator->InitFromURI(this);
219 if (NS_FAILED(rv)) {
220 return rv;
221 }
222 mutator.forget(aMutator);
223 return NS_OK;
224 }
225
226 } // namespace net
227 } // namespace mozilla
228