Line data Source code
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/. */
4 :
5 : #include "xpctest_private.h"
6 : #include "xpctest_interfaces.h"
7 : #include "js/Value.h"
8 :
9 0 : NS_IMPL_ISUPPORTS(nsXPCTestParams, nsIXPCTestParams)
10 :
11 0 : nsXPCTestParams::nsXPCTestParams()
12 : {
13 0 : }
14 :
15 0 : nsXPCTestParams::~nsXPCTestParams()
16 : {
17 0 : }
18 :
19 : #define GENERIC_METHOD_IMPL { \
20 : *_retval = *b; \
21 : *b = a; \
22 : return NS_OK; \
23 : }
24 :
25 : #define STRING_METHOD_IMPL { \
26 : _retval.Assign(b); \
27 : b.Assign(a); \
28 : return NS_OK; \
29 : }
30 :
31 : #define TAKE_OWNERSHIP_NOOP(val) {}
32 : #define TAKE_OWNERSHIP_INTERFACE(val) {static_cast<nsISupports*>(val)->AddRef();}
33 : #define TAKE_OWNERSHIP_STRING(val) { \
34 : nsDependentCString vprime(val); \
35 : val = ToNewCString(vprime); \
36 : }
37 : #define TAKE_OWNERSHIP_WSTRING(val) { \
38 : nsDependentString vprime(val); \
39 : val = ToNewUnicode(vprime); \
40 : }
41 :
42 : // Macro for our buffer-oriented types:
43 : // 'type' is the type of element that the buffer contains.
44 : // 'padding' is an offset added to length, allowing us to handle
45 : // null-terminated strings.
46 : // 'TAKE_OWNERSHIP' is one of the macros above.
47 : #define BUFFER_METHOD_IMPL(type, padding, TAKE_OWNERSHIP) { \
48 : uint32_t elemSize = sizeof(type); \
49 : \
50 : /* Copy b into rv. */ \
51 : *rvLength = *bLength; \
52 : *rv = static_cast<type*>(moz_xmalloc(elemSize * (*bLength + padding))); \
53 : if (!*rv) \
54 : return NS_ERROR_OUT_OF_MEMORY; \
55 : memcpy(*rv, *b, elemSize * (*bLength + padding)); \
56 : \
57 : /* Copy a into b. */ \
58 : *bLength = aLength; \
59 : free(*b); \
60 : *b = static_cast<type*>(moz_xmalloc(elemSize * (aLength + padding))); \
61 : if (!*b) \
62 : return NS_ERROR_OUT_OF_MEMORY; \
63 : memcpy(*b, a, elemSize * (aLength + padding)); \
64 : \
65 : /* We need to take ownership of the data we got from a, \
66 : since the caller owns it. */ \
67 : for (unsigned i = 0; i < *bLength + padding; ++i) \
68 : TAKE_OWNERSHIP((*b)[i]); \
69 : \
70 : return NS_OK; \
71 : }
72 :
73 0 : NS_IMETHODIMP nsXPCTestParams::TestBoolean(bool a, bool* b, bool* _retval)
74 : {
75 0 : GENERIC_METHOD_IMPL;
76 : }
77 :
78 0 : NS_IMETHODIMP nsXPCTestParams::TestOctet(uint8_t a, uint8_t* b, uint8_t* _retval)
79 : {
80 0 : GENERIC_METHOD_IMPL;
81 : }
82 :
83 0 : NS_IMETHODIMP nsXPCTestParams::TestShort(int16_t a, int16_t* b, int16_t* _retval)
84 : {
85 0 : GENERIC_METHOD_IMPL;
86 : }
87 :
88 0 : NS_IMETHODIMP nsXPCTestParams::TestLong(int32_t a, int32_t* b, int32_t* _retval)
89 : {
90 0 : GENERIC_METHOD_IMPL;
91 : }
92 :
93 0 : NS_IMETHODIMP nsXPCTestParams::TestLongLong(int64_t a, int64_t* b, int64_t* _retval)
94 : {
95 0 : GENERIC_METHOD_IMPL;
96 : }
97 :
98 0 : NS_IMETHODIMP nsXPCTestParams::TestUnsignedShort(uint16_t a, uint16_t* b, uint16_t* _retval)
99 : {
100 0 : GENERIC_METHOD_IMPL;
101 : }
102 :
103 0 : NS_IMETHODIMP nsXPCTestParams::TestUnsignedLong(uint32_t a, uint32_t* b, uint32_t* _retval)
104 : {
105 0 : GENERIC_METHOD_IMPL;
106 : }
107 :
108 0 : NS_IMETHODIMP nsXPCTestParams::TestUnsignedLongLong(uint64_t a, uint64_t* b, uint64_t* _retval)
109 : {
110 0 : GENERIC_METHOD_IMPL;
111 : }
112 :
113 0 : NS_IMETHODIMP nsXPCTestParams::TestFloat(float a, float* b, float* _retval)
114 : {
115 0 : GENERIC_METHOD_IMPL;
116 : }
117 :
118 0 : NS_IMETHODIMP nsXPCTestParams::TestDouble(double a, float* b, double* _retval)
119 : {
120 0 : GENERIC_METHOD_IMPL;
121 : }
122 :
123 0 : NS_IMETHODIMP nsXPCTestParams::TestChar(char a, char* b, char* _retval)
124 : {
125 0 : GENERIC_METHOD_IMPL;
126 : }
127 :
128 0 : NS_IMETHODIMP nsXPCTestParams::TestString(const char * a, char * *b, char * *_retval)
129 : {
130 0 : nsDependentCString aprime(a);
131 0 : nsDependentCString bprime(*b);
132 0 : *_retval = ToNewCString(bprime);
133 0 : *b = ToNewCString(aprime);
134 :
135 : // XPCOM ownership rules dictate that overwritten inout params must be callee-freed.
136 : // See https://developer.mozilla.org/en/XPIDL
137 0 : free(const_cast<char*>(bprime.get()));
138 :
139 0 : return NS_OK;
140 : }
141 :
142 0 : NS_IMETHODIMP nsXPCTestParams::TestWchar(char16_t a, char16_t* b, char16_t* _retval)
143 : {
144 0 : GENERIC_METHOD_IMPL;
145 : }
146 :
147 0 : NS_IMETHODIMP nsXPCTestParams::TestWstring(const char16_t * a, char16_t * *b, char16_t * *_retval)
148 : {
149 0 : nsDependentString aprime(a);
150 0 : nsDependentString bprime(*b);
151 0 : *_retval = ToNewUnicode(bprime);
152 0 : *b = ToNewUnicode(aprime);
153 :
154 : // XPCOM ownership rules dictate that overwritten inout params must be callee-freed.
155 : // See https://developer.mozilla.org/en/XPIDL
156 0 : free((void*)bprime.get());
157 :
158 0 : return NS_OK;
159 : }
160 :
161 0 : NS_IMETHODIMP nsXPCTestParams::TestDOMString(const nsAString & a, nsAString & b, nsAString & _retval)
162 : {
163 0 : STRING_METHOD_IMPL;
164 : }
165 :
166 :
167 0 : NS_IMETHODIMP nsXPCTestParams::TestAString(const nsAString & a, nsAString & b, nsAString & _retval)
168 : {
169 0 : STRING_METHOD_IMPL;
170 : }
171 :
172 0 : NS_IMETHODIMP nsXPCTestParams::TestAUTF8String(const nsACString & a, nsACString & b, nsACString & _retval)
173 : {
174 0 : STRING_METHOD_IMPL;
175 : }
176 :
177 0 : NS_IMETHODIMP nsXPCTestParams::TestACString(const nsACString & a, nsACString & b, nsACString & _retval)
178 : {
179 0 : STRING_METHOD_IMPL;
180 : }
181 :
182 0 : NS_IMETHODIMP nsXPCTestParams::TestJsval(JS::Handle<JS::Value> a,
183 : JS::MutableHandle<JS::Value> b,
184 : JS::MutableHandle<JS::Value> _retval)
185 : {
186 0 : _retval.set(b);
187 0 : b.set(a);
188 0 : return NS_OK;
189 : }
190 :
191 0 : NS_IMETHODIMP nsXPCTestParams::TestShortArray(uint32_t aLength, int16_t* a,
192 : uint32_t* bLength, int16_t** b,
193 : uint32_t* rvLength, int16_t** rv)
194 : {
195 0 : BUFFER_METHOD_IMPL(int16_t, 0, TAKE_OWNERSHIP_NOOP);
196 : }
197 :
198 0 : NS_IMETHODIMP nsXPCTestParams::TestDoubleArray(uint32_t aLength, double* a,
199 : uint32_t* bLength, double** b,
200 : uint32_t* rvLength, double** rv)
201 : {
202 0 : BUFFER_METHOD_IMPL(double, 0, TAKE_OWNERSHIP_NOOP);
203 : }
204 :
205 0 : NS_IMETHODIMP nsXPCTestParams::TestStringArray(uint32_t aLength, const char * *a,
206 : uint32_t* bLength, char * **b,
207 : uint32_t* rvLength, char * **rv)
208 : {
209 0 : BUFFER_METHOD_IMPL(char*, 0, TAKE_OWNERSHIP_STRING);
210 : }
211 :
212 0 : NS_IMETHODIMP nsXPCTestParams::TestWstringArray(uint32_t aLength, const char16_t * *a,
213 : uint32_t* bLength, char16_t * **b,
214 : uint32_t* rvLength, char16_t * **rv)
215 : {
216 0 : BUFFER_METHOD_IMPL(char16_t*, 0, TAKE_OWNERSHIP_WSTRING);
217 : }
218 :
219 0 : NS_IMETHODIMP nsXPCTestParams::TestInterfaceArray(uint32_t aLength, nsIXPCTestInterfaceA** a,
220 : uint32_t* bLength, nsIXPCTestInterfaceA * **b,
221 : uint32_t* rvLength, nsIXPCTestInterfaceA * **rv)
222 : {
223 0 : BUFFER_METHOD_IMPL(nsIXPCTestInterfaceA*, 0, TAKE_OWNERSHIP_INTERFACE);
224 : }
225 :
226 0 : NS_IMETHODIMP nsXPCTestParams::TestSizedString(uint32_t aLength, const char * a,
227 : uint32_t* bLength, char * *b,
228 : uint32_t* rvLength, char * *rv)
229 : {
230 0 : BUFFER_METHOD_IMPL(char, 1, TAKE_OWNERSHIP_NOOP);
231 : }
232 :
233 0 : NS_IMETHODIMP nsXPCTestParams::TestSizedWstring(uint32_t aLength, const char16_t * a,
234 : uint32_t* bLength, char16_t * *b,
235 : uint32_t* rvLength, char16_t * *rv)
236 : {
237 0 : BUFFER_METHOD_IMPL(char16_t, 1, TAKE_OWNERSHIP_NOOP);
238 : }
239 :
240 0 : NS_IMETHODIMP nsXPCTestParams::TestInterfaceIs(const nsIID* aIID, void* a,
241 : nsIID** bIID, void** b,
242 : nsIID** rvIID, void** rv)
243 : {
244 : //
245 : // Getting the buffers and ownership right here can be a little tricky.
246 : //
247 :
248 : // The interface pointers are heap-allocated, and b has been AddRef'd
249 : // by XPConnect for the duration of the call. If we snatch it away from b
250 : // and leave no trace, XPConnect won't Release it. Since we also need to
251 : // return an already-AddRef'd pointer in rv, we don't need to do anything
252 : // special here.
253 0 : *rv = *b;
254 :
255 : // rvIID is out-only, so nobody allocated an IID buffer for us. Do that now,
256 : // and store b's IID in the new buffer.
257 0 : *rvIID = static_cast<nsIID*>(moz_xmalloc(sizeof(nsID)));
258 0 : if (!*rvIID)
259 0 : return NS_ERROR_OUT_OF_MEMORY;
260 0 : **rvIID = **bIID;
261 :
262 : // Copy the interface pointer from a to b. Since a is in-only, XPConnect will
263 : // release it upon completion of the call. AddRef it for b.
264 0 : *b = a;
265 0 : static_cast<nsISupports*>(*b)->AddRef();
266 :
267 : // We already had a buffer allocated for b's IID, so we can re-use it.
268 0 : **bIID = *aIID;
269 :
270 0 : return NS_OK;
271 : }
272 :
273 0 : NS_IMETHODIMP nsXPCTestParams::TestInterfaceIsArray(uint32_t aLength, const nsIID* aIID,
274 : void** a,
275 : uint32_t* bLength, nsIID** bIID,
276 : void*** b,
277 : uint32_t* rvLength, nsIID** rvIID,
278 : void*** rv)
279 : {
280 : // Transfer the IIDs. See the comments in TestInterfaceIs (above) for an
281 : // explanation of what we're doing.
282 0 : *rvIID = static_cast<nsIID*>(moz_xmalloc(sizeof(nsID)));
283 0 : if (!*rvIID)
284 0 : return NS_ERROR_OUT_OF_MEMORY;
285 0 : **rvIID = **bIID;
286 0 : **bIID = *aIID;
287 :
288 : // The macro is agnostic to the actual interface types, so we can re-use code here.
289 : //
290 : // Do this second, since the macro returns.
291 0 : BUFFER_METHOD_IMPL(void*, 0, TAKE_OWNERSHIP_INTERFACE);
292 : }
293 :
294 0 : NS_IMETHODIMP nsXPCTestParams::TestOutAString(nsAString & o)
295 : {
296 0 : o.AssignLiteral("out");
297 0 : return NS_OK;
298 : }
299 :
300 0 : NS_IMETHODIMP nsXPCTestParams::TestStringArrayOptionalSize(const char * *a, uint32_t length, nsACString& out)
301 : {
302 0 : out.Truncate();
303 0 : for (uint32_t i = 0; i < length; ++i) {
304 0 : out.Append(a[i]);
305 : }
306 :
307 0 : return NS_OK;
308 : }
|