no bug - Import translations from android-l10n r=release a=l10n CLOSED TREE
[gecko.git] / js / xpconnect / tests / components / native / xpctest_params.cpp
blob4d1924de05933eb765f5b07022208fde32edc393
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "xpctest_private.h"
6 #include "xpctest_interfaces.h"
7 #include "mozilla/Casting.h"
8 #include "js/Value.h"
10 #include "nsCOMPtr.h"
11 #include "nsComponentManagerUtils.h"
12 #include "nsIURI.h"
14 using namespace mozilla;
16 NS_IMPL_ISUPPORTS(nsXPCTestParams, nsIXPCTestParams)
18 #define GENERIC_METHOD_IMPL \
19 { \
20 *_retval = *b; \
21 *b = a; \
22 return NS_OK; \
25 #define STRING_METHOD_IMPL \
26 { \
27 _retval.Assign(b); \
28 b.Assign(a); \
29 return NS_OK; \
32 #define SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP) \
33 { \
34 _retval = std::move(b); \
35 b = a.Clone(); \
36 for (uint32_t i = 0; i < b.Length(); ++i) TAKE_OWNERSHIP(b[i]); \
37 return NS_OK; \
40 #define TAKE_OWNERSHIP_NOOP(val) \
42 #define TAKE_OWNERSHIP_INTERFACE(val) \
43 { static_cast<nsISupports*>(val)->AddRef(); }
44 #define TAKE_OWNERSHIP_STRING(val) \
45 { \
46 nsDependentCString vprime(val); \
47 val = ToNewCString(vprime); \
49 #define TAKE_OWNERSHIP_WSTRING(val) \
50 { \
51 nsDependentString vprime(val); \
52 val = ToNewUnicode(vprime); \
55 // Macro for our buffer-oriented types:
56 // 'type' is the type of element that the buffer contains.
57 // 'padding' is an offset added to length, allowing us to handle
58 // null-terminated strings.
59 // 'TAKE_OWNERSHIP' is one of the macros above.
60 #define BUFFER_METHOD_IMPL(type, padding, TAKE_OWNERSHIP) \
61 { \
62 uint32_t elemSize = sizeof(type); \
64 /* Copy b into rv. */ \
65 *rvLength = *bLength; \
66 *rv = static_cast<type*>(moz_xmalloc(elemSize * (*bLength + padding))); \
67 memcpy(*rv, *b, elemSize*(*bLength + padding)); \
69 /* Copy a into b. */ \
70 *bLength = aLength; \
71 free(*b); \
72 *b = static_cast<type*>(moz_xmalloc(elemSize * (aLength + padding))); \
73 memcpy(*b, a, elemSize*(aLength + padding)); \
75 /* We need to take ownership of the data we got from a, \
76 since the caller owns it. */ \
77 for (unsigned i = 0; i < *bLength + padding; ++i) TAKE_OWNERSHIP((*b)[i]); \
79 return NS_OK; \
82 NS_IMETHODIMP nsXPCTestParams::TestBoolean(bool a, bool* b, bool* _retval) {
83 GENERIC_METHOD_IMPL;
86 NS_IMETHODIMP nsXPCTestParams::TestOctet(uint8_t a, uint8_t* b,
87 uint8_t* _retval) {
88 GENERIC_METHOD_IMPL;
91 NS_IMETHODIMP nsXPCTestParams::TestShort(int16_t a, int16_t* b,
92 int16_t* _retval) {
93 GENERIC_METHOD_IMPL;
96 NS_IMETHODIMP nsXPCTestParams::TestLong(int32_t a, int32_t* b,
97 int32_t* _retval) {
98 GENERIC_METHOD_IMPL;
101 NS_IMETHODIMP nsXPCTestParams::TestLongLong(int64_t a, int64_t* b,
102 int64_t* _retval) {
103 GENERIC_METHOD_IMPL;
106 NS_IMETHODIMP nsXPCTestParams::TestUnsignedShort(uint16_t a, uint16_t* b,
107 uint16_t* _retval) {
108 GENERIC_METHOD_IMPL;
111 NS_IMETHODIMP nsXPCTestParams::TestUnsignedLong(uint32_t a, uint32_t* b,
112 uint32_t* _retval) {
113 GENERIC_METHOD_IMPL;
116 NS_IMETHODIMP nsXPCTestParams::TestUnsignedLongLong(uint64_t a, uint64_t* b,
117 uint64_t* _retval) {
118 GENERIC_METHOD_IMPL;
121 NS_IMETHODIMP nsXPCTestParams::TestFloat(float a, float* b, float* _retval) {
122 GENERIC_METHOD_IMPL;
125 NS_IMETHODIMP nsXPCTestParams::TestDouble(double a, float* b, double* _retval) {
126 GENERIC_METHOD_IMPL;
129 NS_IMETHODIMP nsXPCTestParams::TestChar(char a, char* b, char* _retval) {
130 GENERIC_METHOD_IMPL;
133 NS_IMETHODIMP nsXPCTestParams::TestString(const char* a, char** b,
134 char** _retval) {
135 nsDependentCString aprime(a);
136 nsDependentCString bprime(*b);
137 *_retval = ToNewCString(bprime);
138 *b = ToNewCString(aprime);
140 // XPCOM ownership rules dictate that overwritten inout params must be
141 // callee-freed. See https://developer.mozilla.org/en/XPIDL
142 free(const_cast<char*>(bprime.get()));
144 return NS_OK;
147 NS_IMETHODIMP nsXPCTestParams::TestWchar(char16_t a, char16_t* b,
148 char16_t* _retval) {
149 GENERIC_METHOD_IMPL;
152 NS_IMETHODIMP nsXPCTestParams::TestWstring(const char16_t* a, char16_t** b,
153 char16_t** _retval) {
154 nsDependentString aprime(a);
155 nsDependentString bprime(*b);
156 *_retval = ToNewUnicode(bprime);
157 *b = ToNewUnicode(aprime);
159 // XPCOM ownership rules dictate that overwritten inout params must be
160 // callee-freed. See https://developer.mozilla.org/en/XPIDL
161 free((void*)bprime.get());
163 return NS_OK;
166 NS_IMETHODIMP nsXPCTestParams::TestAString(const nsAString& a, nsAString& b,
167 nsAString& _retval) {
168 STRING_METHOD_IMPL;
171 NS_IMETHODIMP nsXPCTestParams::TestAUTF8String(const nsACString& a,
172 nsACString& b,
173 nsACString& _retval) {
174 STRING_METHOD_IMPL;
177 NS_IMETHODIMP nsXPCTestParams::TestACString(const nsACString& a, nsACString& b,
178 nsACString& _retval) {
179 STRING_METHOD_IMPL;
182 NS_IMETHODIMP nsXPCTestParams::TestJsval(JS::Handle<JS::Value> a,
183 JS::MutableHandle<JS::Value> b,
184 JS::MutableHandle<JS::Value> _retval) {
185 _retval.set(b);
186 b.set(a);
187 return NS_OK;
190 NS_IMETHODIMP nsXPCTestParams::TestShortArray(uint32_t aLength, int16_t* a,
191 uint32_t* bLength, int16_t** b,
192 uint32_t* rvLength,
193 int16_t** rv) {
194 BUFFER_METHOD_IMPL(int16_t, 0, TAKE_OWNERSHIP_NOOP);
197 NS_IMETHODIMP nsXPCTestParams::TestDoubleArray(uint32_t aLength, double* a,
198 uint32_t* bLength, double** b,
199 uint32_t* rvLength,
200 double** rv) {
201 BUFFER_METHOD_IMPL(double, 0, TAKE_OWNERSHIP_NOOP);
204 NS_IMETHODIMP nsXPCTestParams::TestByteArrayOptionalLength(uint8_t* a,
205 uint32_t aLength,
206 uint32_t* rv) {
207 *rv = aLength;
208 return NS_OK;
211 NS_IMETHODIMP nsXPCTestParams::TestStringArray(uint32_t aLength, const char** a,
212 uint32_t* bLength, char*** b,
213 uint32_t* rvLength, char*** rv) {
214 BUFFER_METHOD_IMPL(char*, 0, TAKE_OWNERSHIP_STRING);
217 NS_IMETHODIMP nsXPCTestParams::TestWstringArray(
218 uint32_t aLength, const char16_t** a, uint32_t* bLength, char16_t*** b,
219 uint32_t* rvLength, char16_t*** rv) {
220 BUFFER_METHOD_IMPL(char16_t*, 0, TAKE_OWNERSHIP_WSTRING);
223 NS_IMETHODIMP nsXPCTestParams::TestInterfaceArray(
224 uint32_t aLength, nsIXPCTestInterfaceA** a, uint32_t* bLength,
225 nsIXPCTestInterfaceA*** b, uint32_t* rvLength, nsIXPCTestInterfaceA*** rv) {
226 BUFFER_METHOD_IMPL(nsIXPCTestInterfaceA*, 0, TAKE_OWNERSHIP_INTERFACE);
229 NS_IMETHODIMP nsXPCTestParams::TestJsvalArray(uint32_t aLength, JS::Value* a,
230 uint32_t* bLength, JS::Value** b,
231 uint32_t* rvLength,
232 JS::Value** rv) {
233 BUFFER_METHOD_IMPL(JS::Value, 0, TAKE_OWNERSHIP_NOOP);
236 NS_IMETHODIMP nsXPCTestParams::TestSizedString(uint32_t aLength, const char* a,
237 uint32_t* bLength, char** b,
238 uint32_t* rvLength, char** rv) {
239 BUFFER_METHOD_IMPL(char, 1, TAKE_OWNERSHIP_NOOP);
242 NS_IMETHODIMP nsXPCTestParams::TestSizedWstring(uint32_t aLength,
243 const char16_t* a,
244 uint32_t* bLength, char16_t** b,
245 uint32_t* rvLength,
246 char16_t** rv) {
247 BUFFER_METHOD_IMPL(char16_t, 1, TAKE_OWNERSHIP_NOOP);
250 NS_IMETHODIMP nsXPCTestParams::TestInterfaceIs(const nsIID* aIID, void* a,
251 nsIID** bIID, void** b,
252 nsIID** rvIID, void** rv) {
254 // Getting the buffers and ownership right here can be a little tricky.
257 // The interface pointers are heap-allocated, and b has been AddRef'd
258 // by XPConnect for the duration of the call. If we snatch it away from b
259 // and leave no trace, XPConnect won't Release it. Since we also need to
260 // return an already-AddRef'd pointer in rv, we don't need to do anything
261 // special here.
262 *rv = *b;
264 // rvIID is out-only, so nobody allocated an IID buffer for us. Do that now,
265 // and store b's IID in the new buffer.
266 *rvIID = static_cast<nsIID*>(moz_xmalloc(sizeof(nsID)));
267 **rvIID = **bIID;
269 // Copy the interface pointer from a to b. Since a is in-only, XPConnect will
270 // release it upon completion of the call. AddRef it for b.
271 *b = a;
272 static_cast<nsISupports*>(*b)->AddRef();
274 // We already had a buffer allocated for b's IID, so we can re-use it.
275 **bIID = *aIID;
277 return NS_OK;
280 NS_IMETHODIMP nsXPCTestParams::TestInterfaceIsArray(
281 uint32_t aLength, const nsIID* aIID, void** a, uint32_t* bLength,
282 nsIID** bIID, void*** b, uint32_t* rvLength, nsIID** rvIID, void*** rv) {
283 // Transfer the IIDs. See the comments in TestInterfaceIs (above) for an
284 // explanation of what we're doing.
285 *rvIID = static_cast<nsIID*>(moz_xmalloc(sizeof(nsID)));
286 **rvIID = **bIID;
287 **bIID = *aIID;
289 // The macro is agnostic to the actual interface types, so we can re-use code
290 // here.
292 // Do this second, since the macro returns.
293 BUFFER_METHOD_IMPL(void*, 0, TAKE_OWNERSHIP_INTERFACE);
296 NS_IMETHODIMP nsXPCTestParams::TestOutAString(nsAString& o) {
297 o.AssignLiteral("out");
298 return NS_OK;
301 NS_IMETHODIMP nsXPCTestParams::TestStringArrayOptionalSize(const char** a,
302 uint32_t length,
303 nsACString& out) {
304 out.Truncate();
305 for (uint32_t i = 0; i < length; ++i) {
306 out.Append(a[i]);
309 return NS_OK;
312 NS_IMETHODIMP
313 nsXPCTestParams::TestShortSequence(const nsTArray<short>& a, nsTArray<short>& b,
314 nsTArray<short>& _retval) {
315 SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP);
318 NS_IMETHODIMP
319 nsXPCTestParams::TestDoubleSequence(const nsTArray<double>& a,
320 nsTArray<double>& b,
321 nsTArray<double>& _retval) {
322 SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP);
325 NS_IMETHODIMP
326 nsXPCTestParams::TestInterfaceSequence(
327 const nsTArray<RefPtr<nsIXPCTestInterfaceA>>& a,
328 nsTArray<RefPtr<nsIXPCTestInterfaceA>>& b,
329 nsTArray<RefPtr<nsIXPCTestInterfaceA>>& _retval) {
330 SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP);
333 NS_IMETHODIMP
334 nsXPCTestParams::TestAStringSequence(const nsTArray<nsString>& a,
335 nsTArray<nsString>& b,
336 nsTArray<nsString>& _retval) {
337 SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP);
340 NS_IMETHODIMP
341 nsXPCTestParams::TestACStringSequence(const nsTArray<nsCString>& a,
342 nsTArray<nsCString>& b,
343 nsTArray<nsCString>& _retval) {
344 SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP);
347 NS_IMETHODIMP
348 nsXPCTestParams::TestJsvalSequence(const nsTArray<JS::Value>& a,
349 nsTArray<JS::Value>& b,
350 nsTArray<JS::Value>& _retval) {
351 SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP);
354 NS_IMETHODIMP
355 nsXPCTestParams::TestSequenceSequence(const nsTArray<nsTArray<short>>& a,
356 nsTArray<nsTArray<short>>& b,
357 nsTArray<nsTArray<short>>& _retval) {
358 _retval = std::move(b);
359 for (const auto& element : a) {
360 b.AppendElement(element.Clone());
362 return NS_OK;
365 NS_IMETHODIMP
366 nsXPCTestParams::TestInterfaceIsSequence(const nsIID* aIID,
367 const nsTArray<void*>& a, nsIID** bIID,
368 nsTArray<void*>& b, nsIID** rvIID,
369 nsTArray<void*>& _retval) {
370 // Shuffle around our nsIIDs
371 *rvIID = (*bIID)->Clone();
372 *bIID = aIID->Clone();
374 // Perform the generic sequence shuffle.
375 SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_INTERFACE);
378 NS_IMETHODIMP
379 nsXPCTestParams::TestOptionalSequence(const nsTArray<uint8_t>& aInArr,
380 nsTArray<uint8_t>& aReturnArr) {
381 aReturnArr = aInArr.Clone();
382 return NS_OK;
385 NS_IMETHODIMP
386 nsXPCTestParams::TestOmittedOptionalOut(nsIXPCTestParams* aJSObj,
387 nsIURI** aOut) {
388 MOZ_ASSERT(!(*aOut), "Unexpected value received");
389 // Call the js component, to check XPConnect won't crash when passing nullptr
390 // as the optional out parameter, and that the out object is built regardless.
391 nsresult rv;
392 // Invoke it directly passing nullptr.
393 rv = aJSObj->TestOmittedOptionalOut(nullptr, nullptr);
394 NS_ENSURE_SUCCESS(rv, rv);
395 // Also invoke it with a ref pointer.
396 nsCOMPtr<nsIURI> someURI;
397 rv = aJSObj->TestOmittedOptionalOut(nullptr, getter_AddRefs(someURI));
398 NS_ENSURE_SUCCESS(rv, rv);
399 nsAutoCString spec;
400 rv = someURI->GetSpec(spec);
401 if (!spec.EqualsLiteral("http://example.com/")) {
402 return NS_ERROR_UNEXPECTED;
404 someURI.forget(aOut);
405 return NS_OK;
408 NS_IMETHODIMP
409 nsXPCTestParams::GetTestNaN(double* aResult) {
410 *aResult =
411 BitwiseCast<double>((uint64_t(JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT) + 1);
412 return NS_OK;