1 : /* ***** BEGIN LICENSE BLOCK *****
2 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 : *
4 : * The contents of this file are subject to the Mozilla Public License Version
5 : * 1.1 (the "License"); you may not use this file except in compliance with
6 : * the License. You may obtain a copy of the License at
7 : * http://www.mozilla.org/MPL/
8 : *
9 : * Software distributed under the License is distributed on an "AS IS" basis,
10 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 : * for the specific language governing rights and limitations under the
12 : * License.
13 : *
14 : * The Original Code is XPConnect Test Code.
15 : *
16 : * The Initial Developer of the Original Code is The Mozilla Foundation.
17 : * Portions created by the Initial Developer are Copyright (C) 2011
18 : * the Initial Developer. All Rights Reserved.
19 : *
20 : * Contributor(s):
21 : * Bobby Holley <bobbyholley@gmail.com>
22 : *
23 : * Alternatively, the contents of this file may be used under the terms of
24 : * either the GNU General Public License Version 2 or later (the "GPL"), or
25 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 : * in which case the provisions of the GPL or the LGPL are applicable instead
27 : * of those above. If you wish to allow use of your version of this file only
28 : * under the terms of either the GPL or the LGPL, and not to allow others to
29 : * use your version of this file under the terms of the MPL, indicate your
30 : * decision by deleting the provisions above and replace them with the notice
31 : * and other provisions required by the GPL or the LGPL. If you do not delete
32 : * the provisions above, a recipient may use your version of this file under
33 : * the terms of any one of the MPL, the GPL or the LGPL.
34 : *
35 : * ***** END LICENSE BLOCK ***** */
36 :
37 : #include "xpctest_private.h"
38 : #include "xpctest_interfaces.h"
39 :
40 18 : NS_IMPL_ISUPPORTS1(nsXPCTestParams, nsIXPCTestParams)
41 :
42 1 : nsXPCTestParams::nsXPCTestParams()
43 : {
44 1 : }
45 :
46 1 : nsXPCTestParams::~nsXPCTestParams()
47 : {
48 1 : }
49 :
50 : #define GENERIC_METHOD_IMPL { \
51 : *_retval = *b; \
52 : *b = a; \
53 : return NS_OK; \
54 : }
55 :
56 : #define STRING_METHOD_IMPL { \
57 : _retval.Assign(b); \
58 : b.Assign(a); \
59 : return NS_OK; \
60 : }
61 :
62 : #define TAKE_OWNERSHIP_NOOP(val) {}
63 : #define TAKE_OWNERSHIP_INTERFACE(val) {static_cast<nsISupports*>(val)->AddRef();}
64 : #define TAKE_OWNERSHIP_STRING(val) { \
65 : nsDependentCString vprime(val); \
66 : val = ToNewCString(vprime); \
67 : }
68 : #define TAKE_OWNERSHIP_WSTRING(val) { \
69 : nsDependentString vprime(val); \
70 : val = ToNewUnicode(vprime); \
71 : }
72 :
73 : // Macro for our buffer-oriented types:
74 : // 'type' is the type of element that the buffer contains.
75 : // 'padding' is an offset added to length, allowing us to handle
76 : // null-terminated strings.
77 : // 'TAKE_OWNERSHIP' is one of the macros above.
78 : #define BUFFER_METHOD_IMPL(type, padding, TAKE_OWNERSHIP) { \
79 : PRUint32 elemSize = sizeof(type); \
80 : \
81 : /* Copy b into rv. */ \
82 : *rvLength = *bLength; \
83 : *rv = static_cast<type*>(NS_Alloc(elemSize * (*bLength + padding))); \
84 : if (!*rv) \
85 : return NS_ERROR_OUT_OF_MEMORY; \
86 : memcpy(*rv, *b, elemSize * (*bLength + padding)); \
87 : \
88 : /* Copy a into b. */ \
89 : *bLength = aLength; \
90 : NS_Free(*b); \
91 : *b = static_cast<type*>(NS_Alloc(elemSize * (aLength + padding))); \
92 : if (!*b) \
93 : return NS_ERROR_OUT_OF_MEMORY; \
94 : memcpy(*b, a, elemSize * (aLength + padding)); \
95 : \
96 : /* We need to take ownership of the data we got from a, \
97 : since the caller owns it. */ \
98 : for (unsigned i = 0; i < *bLength + padding; ++i) \
99 : TAKE_OWNERSHIP((*b)[i]); \
100 : \
101 : return NS_OK; \
102 : }
103 :
104 : /* boolean testBoolean (in boolean a, inout boolean b); */
105 1 : NS_IMETHODIMP nsXPCTestParams::TestBoolean(bool a, bool *b NS_INOUTPARAM, bool *_retval NS_OUTPARAM)
106 : {
107 1 : GENERIC_METHOD_IMPL;
108 : }
109 :
110 : /* octet testOctet (in octet a, inout octet b); */
111 1 : NS_IMETHODIMP nsXPCTestParams::TestOctet(PRUint8 a, PRUint8 *b NS_INOUTPARAM, PRUint8 *_retval NS_OUTPARAM)
112 : {
113 1 : GENERIC_METHOD_IMPL;
114 : }
115 :
116 : /* short testShort (in short a, inout short b); */
117 1 : NS_IMETHODIMP nsXPCTestParams::TestShort(PRInt16 a, PRInt16 *b NS_INOUTPARAM, PRInt16 *_retval NS_OUTPARAM)
118 : {
119 1 : GENERIC_METHOD_IMPL;
120 : }
121 :
122 : /* long testLong (in long a, inout long b); */
123 1 : NS_IMETHODIMP nsXPCTestParams::TestLong(PRInt32 a, PRInt32 *b NS_INOUTPARAM, PRInt32 *_retval NS_OUTPARAM)
124 : {
125 1 : GENERIC_METHOD_IMPL;
126 : }
127 :
128 : /* long long testLongLong (in long long a, inout long long b); */
129 1 : NS_IMETHODIMP nsXPCTestParams::TestLongLong(PRInt64 a, PRInt64 *b NS_INOUTPARAM, PRInt64 *_retval NS_OUTPARAM)
130 : {
131 1 : GENERIC_METHOD_IMPL;
132 : }
133 :
134 : /* unsigned short testUnsignedShort (in unsigned short a, inout unsigned short b); */
135 1 : NS_IMETHODIMP nsXPCTestParams::TestUnsignedShort(PRUint16 a, PRUint16 *b NS_INOUTPARAM, PRUint16 *_retval NS_OUTPARAM)
136 : {
137 1 : GENERIC_METHOD_IMPL;
138 : }
139 :
140 : /* unsigned long testUnsignedLong (in unsigned long a, inout unsigned long b); */
141 1 : NS_IMETHODIMP nsXPCTestParams::TestUnsignedLong(PRUint32 a, PRUint32 *b NS_INOUTPARAM, PRUint32 *_retval NS_OUTPARAM)
142 : {
143 1 : GENERIC_METHOD_IMPL;
144 : }
145 :
146 : /* unsigned long long testUnsignedLongLong (in unsigned long long a, inout unsigned long long b); */
147 1 : NS_IMETHODIMP nsXPCTestParams::TestUnsignedLongLong(PRUint64 a, PRUint64 *b NS_INOUTPARAM, PRUint64 *_retval NS_OUTPARAM)
148 : {
149 1 : GENERIC_METHOD_IMPL;
150 : }
151 :
152 : /* float testFloat (in float a, inout float b); */
153 1 : NS_IMETHODIMP nsXPCTestParams::TestFloat(float a, float *b NS_INOUTPARAM, float *_retval NS_OUTPARAM)
154 : {
155 1 : GENERIC_METHOD_IMPL;
156 : }
157 :
158 : /* double testDouble (in double a, inout float b); */
159 1 : NS_IMETHODIMP nsXPCTestParams::TestDouble(double a, float *b NS_INOUTPARAM, double *_retval NS_OUTPARAM)
160 : {
161 1 : GENERIC_METHOD_IMPL;
162 : }
163 :
164 : /* char testChar (in char a, inout char b); */
165 1 : NS_IMETHODIMP nsXPCTestParams::TestChar(char a, char *b NS_INOUTPARAM, char *_retval NS_OUTPARAM)
166 : {
167 1 : GENERIC_METHOD_IMPL;
168 : }
169 :
170 : /* string testString (in string a, inout string b); */
171 1 : NS_IMETHODIMP nsXPCTestParams::TestString(const char * a, char * *b NS_INOUTPARAM, char * *_retval NS_OUTPARAM)
172 : {
173 2 : nsDependentCString aprime(a);
174 2 : nsDependentCString bprime(*b);
175 1 : *_retval = ToNewCString(bprime);
176 1 : *b = ToNewCString(aprime);
177 :
178 : // XPCOM ownership rules dictate that overwritten inout params must be callee-freed.
179 : // See https://developer.mozilla.org/en/XPIDL
180 1 : NS_Free(const_cast<char*>(bprime.get()));
181 :
182 1 : return NS_OK;
183 : }
184 :
185 : /* wchar testWchar (in wchar a, inout wchar b); */
186 1 : NS_IMETHODIMP nsXPCTestParams::TestWchar(PRUnichar a, PRUnichar *b NS_INOUTPARAM, PRUnichar *_retval NS_OUTPARAM)
187 : {
188 1 : GENERIC_METHOD_IMPL;
189 : }
190 :
191 : /* wstring testWstring (in wstring a, inout wstring b); */
192 1 : NS_IMETHODIMP nsXPCTestParams::TestWstring(const PRUnichar * a, PRUnichar * *b NS_INOUTPARAM, PRUnichar * *_retval NS_OUTPARAM)
193 : {
194 2 : nsDependentString aprime(a);
195 2 : nsDependentString bprime(*b);
196 1 : *_retval = ToNewUnicode(bprime);
197 1 : *b = ToNewUnicode(aprime);
198 :
199 : // XPCOM ownership rules dictate that overwritten inout params must be callee-freed.
200 : // See https://developer.mozilla.org/en/XPIDL
201 1 : NS_Free(const_cast<PRUnichar*>(bprime.get()));
202 :
203 1 : return NS_OK;
204 : }
205 :
206 : /* DOMString testDOMString (in DOMString a, inout DOMString b); */
207 1 : NS_IMETHODIMP nsXPCTestParams::TestDOMString(const nsAString & a, nsAString & b NS_INOUTPARAM, nsAString & _retval NS_OUTPARAM)
208 : {
209 1 : STRING_METHOD_IMPL;
210 : }
211 :
212 :
213 : /* AString testAString (in AString a, inout AString b); */
214 1 : NS_IMETHODIMP nsXPCTestParams::TestAString(const nsAString & a, nsAString & b NS_INOUTPARAM, nsAString & _retval NS_OUTPARAM)
215 : {
216 1 : STRING_METHOD_IMPL;
217 : }
218 :
219 : /* AUTF8String testAUTF8String (in AUTF8String a, inout AUTF8String b); */
220 1 : NS_IMETHODIMP nsXPCTestParams::TestAUTF8String(const nsACString & a, nsACString & b NS_INOUTPARAM, nsACString & _retval NS_OUTPARAM)
221 : {
222 1 : STRING_METHOD_IMPL;
223 : }
224 :
225 : /* ACString testACString (in ACString a, inout ACString b); */
226 1 : NS_IMETHODIMP nsXPCTestParams::TestACString(const nsACString & a, nsACString & b NS_INOUTPARAM, nsACString & _retval NS_OUTPARAM)
227 : {
228 1 : STRING_METHOD_IMPL;
229 : }
230 :
231 : /* jsval testJsval (in jsval a, inout jsval b); */
232 1 : NS_IMETHODIMP nsXPCTestParams::TestJsval(const jsval & a, jsval & b NS_INOUTPARAM, jsval *_retval NS_OUTPARAM)
233 : {
234 1 : *_retval = b;
235 1 : b = a;
236 1 : return NS_OK;
237 : }
238 :
239 : /* void testShortArray (in unsigned long aLength, [array, size_is (aLength)] in short a,
240 : * inout unsigned long bLength, [array, size_is (bLength)] inout short b,
241 : * out unsigned long rvLength, [array, size_is (rvLength), retval] out short rv); */
242 2 : NS_IMETHODIMP nsXPCTestParams::TestShortArray(PRUint32 aLength, PRInt16 *a,
243 : PRUint32 *bLength NS_INOUTPARAM, PRInt16 **b NS_INOUTPARAM,
244 : PRUint32 *rvLength NS_OUTPARAM, PRInt16 **rv NS_OUTPARAM)
245 : {
246 2 : BUFFER_METHOD_IMPL(PRInt16, 0, TAKE_OWNERSHIP_NOOP);
247 : }
248 :
249 : /* void testDoubleArray (in unsigned long aLength, [array, size_is (aLength)] in double a,
250 : * inout unsigned long bLength, [array, size_is (bLength)] inout double b,
251 : * out unsigned long rvLength, [array, size_is (rvLength), retval] out double rv); */
252 2 : NS_IMETHODIMP nsXPCTestParams::TestDoubleArray(PRUint32 aLength, double *a,
253 : PRUint32 *bLength NS_INOUTPARAM, double **b NS_INOUTPARAM,
254 : PRUint32 *rvLength NS_OUTPARAM, double **rv NS_OUTPARAM)
255 : {
256 2 : BUFFER_METHOD_IMPL(double, 0, TAKE_OWNERSHIP_NOOP);
257 : }
258 :
259 : /* void testStringArray (in unsigned long aLength, [array, size_is (aLength)] in string a,
260 : * inout unsigned long bLength, [array, size_is (bLength)] inout string b,
261 : * out unsigned long rvLength, [array, size_is (rvLength), retval] out string rv); */
262 1 : NS_IMETHODIMP nsXPCTestParams::TestStringArray(PRUint32 aLength, const char * *a,
263 : PRUint32 *bLength NS_INOUTPARAM, char * **b NS_INOUTPARAM,
264 : PRUint32 *rvLength NS_OUTPARAM, char * **rv NS_OUTPARAM)
265 : {
266 1 : BUFFER_METHOD_IMPL(char*, 0, TAKE_OWNERSHIP_STRING);
267 : }
268 :
269 : /* void testWstringArray (in unsigned long aLength, [array, size_is (aLength)] in wstring a,
270 : * inout unsigned long bLength, [array, size_is (bLength)] inout wstring b,
271 : * out unsigned long rvLength, [array, size_is (rvLength), retval] out wstring rv); */
272 1 : NS_IMETHODIMP nsXPCTestParams::TestWstringArray(PRUint32 aLength, const PRUnichar * *a,
273 : PRUint32 *bLength NS_INOUTPARAM, PRUnichar * **b NS_INOUTPARAM,
274 : PRUint32 *rvLength NS_OUTPARAM, PRUnichar * **rv NS_OUTPARAM)
275 : {
276 1 : BUFFER_METHOD_IMPL(PRUnichar*, 0, TAKE_OWNERSHIP_WSTRING);
277 : }
278 :
279 : /* void testInterfaceArray (in unsigned long aLength, [array, size_is (aLength)] in nsIXPCTestInterfaceA a,
280 : * inout unsigned long bLength, [array, size_is (bLength)] inout nsIXPCTestInterfaceA b,
281 : * out unsigned long rvLength, [array, size_is (rvLength), retval] out nsIXPCTestInterfaceA rv); */
282 1 : NS_IMETHODIMP nsXPCTestParams::TestInterfaceArray(PRUint32 aLength, nsIXPCTestInterfaceA **a,
283 : PRUint32 *bLength NS_INOUTPARAM, nsIXPCTestInterfaceA * **b NS_INOUTPARAM,
284 : PRUint32 *rvLength NS_OUTPARAM, nsIXPCTestInterfaceA * **rv NS_OUTPARAM)
285 : {
286 1 : BUFFER_METHOD_IMPL(nsIXPCTestInterfaceA*, 0, TAKE_OWNERSHIP_INTERFACE);
287 : }
288 :
289 : /* void testSizedString (in unsigned long aLength, [size_is (aLength)] in string a,
290 : * inout unsigned long bLength, [size_is (bLength)] inout string b,
291 : * out unsigned long rvLength, [size_is (rvLength), retval] out string rv); */
292 1 : NS_IMETHODIMP nsXPCTestParams::TestSizedString(PRUint32 aLength, const char * a,
293 : PRUint32 *bLength NS_INOUTPARAM, char * *b NS_INOUTPARAM,
294 : PRUint32 *rvLength NS_OUTPARAM, char * *rv NS_OUTPARAM)
295 : {
296 1 : BUFFER_METHOD_IMPL(char, 1, TAKE_OWNERSHIP_NOOP);
297 : }
298 :
299 : /* void testSizedWstring (in unsigned long aLength, [size_is (aLength)] in wstring a,
300 : * inout unsigned long bLength, [size_is (bLength)] inout wstring b,
301 : * out unsigned long rvLength, [size_is (rvLength), retval] out wstring rv); */
302 1 : NS_IMETHODIMP nsXPCTestParams::TestSizedWstring(PRUint32 aLength, const PRUnichar * a,
303 : PRUint32 *bLength NS_INOUTPARAM, PRUnichar * *b NS_INOUTPARAM,
304 : PRUint32 *rvLength NS_OUTPARAM, PRUnichar * *rv NS_OUTPARAM)
305 : {
306 1 : BUFFER_METHOD_IMPL(PRUnichar, 1, TAKE_OWNERSHIP_NOOP);
307 : }
308 :
309 : /* void testInterfaceIs (in nsIIDPtr aIID, [iid_is (aIID)] in nsQIResult a,
310 : * inout nsIIDPtr bIID, [iid_is (bIID)] inout nsQIResult b,
311 : * out nsIIDPtr rvIID, [iid_is (rvIID), retval] out nsQIResult rv); */
312 1 : NS_IMETHODIMP nsXPCTestParams::TestInterfaceIs(const nsIID *aIID, void *a,
313 : nsIID **bIID NS_INOUTPARAM, void **b NS_INOUTPARAM,
314 : nsIID **rvIID NS_OUTPARAM, void **rv NS_OUTPARAM)
315 : {
316 : //
317 : // Getting the buffers and ownership right here can be a little tricky.
318 : //
319 :
320 : // The interface pointers are heap-allocated, and b has been AddRef'd
321 : // by XPConnect for the duration of the call. If we snatch it away from b
322 : // and leave no trace, XPConnect won't Release it. Since we also need to
323 : // return an already-AddRef'd pointer in rv, we don't need to do anything
324 : // special here.
325 1 : *rv = *b;
326 :
327 : // rvIID is out-only, so nobody allocated an IID buffer for us. Do that now,
328 : // and store b's IID in the new buffer.
329 1 : *rvIID = static_cast<nsIID*>(NS_Alloc(sizeof(nsID)));
330 1 : if (!*rvIID)
331 0 : return NS_ERROR_OUT_OF_MEMORY;
332 1 : **rvIID = **bIID;
333 :
334 : // Copy the interface pointer from a to b. Since a is in-only, XPConnect will
335 : // release it upon completion of the call. AddRef it for b.
336 1 : *b = a;
337 1 : static_cast<nsISupports*>(*b)->AddRef();
338 :
339 : // We already had a buffer allocated for b's IID, so we can re-use it.
340 1 : **bIID = *aIID;
341 :
342 1 : return NS_OK;
343 : }
344 :
345 : /* void testInterfaceIsArray (in unsigned long aLength, in nsIIDPtr aIID,
346 : * [array, size_is (aLength), iid_is (aIID)] in nsQIResult a,
347 : * inout unsigned long bLength, inout nsIIDPtr bIID,
348 : * [array, size_is (bLength), iid_is (bIID)] inout nsQIResult b,
349 : * out unsigned long rvLength, out nsIIDPtr rvIID,
350 : * [retval, array, size_is (rvLength), iid_is (rvIID)] out nsQIResult rv); */
351 1 : NS_IMETHODIMP nsXPCTestParams::TestInterfaceIsArray(PRUint32 aLength, const nsIID *aIID,
352 : void **a,
353 : PRUint32 *bLength NS_INOUTPARAM, nsIID **bIID NS_INOUTPARAM,
354 : void ***b NS_INOUTPARAM,
355 : PRUint32 *rvLength NS_OUTPARAM, nsIID **rvIID NS_OUTPARAM,
356 : void ***rv NS_OUTPARAM)
357 : {
358 : // Transfer the IIDs. See the comments in TestInterfaceIs (above) for an
359 : // explanation of what we're doing.
360 1 : *rvIID = static_cast<nsIID*>(NS_Alloc(sizeof(nsID)));
361 1 : if (!*rvIID)
362 0 : return NS_ERROR_OUT_OF_MEMORY;
363 1 : **rvIID = **bIID;
364 1 : **bIID = *aIID;
365 :
366 : // The macro is agnostic to the actual interface types, so we can re-use code here.
367 : //
368 : // Do this second, since the macro returns.
369 1 : BUFFER_METHOD_IMPL(void*, 0, TAKE_OWNERSHIP_INTERFACE);
370 : }
|