1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/xpconnect/tests/components/native/xpctest_params.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,341 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "xpctest_private.h" 1.9 +#include "xpctest_interfaces.h" 1.10 +#include "js/Value.h" 1.11 + 1.12 +NS_IMPL_ISUPPORTS(nsXPCTestParams, nsIXPCTestParams) 1.13 + 1.14 +nsXPCTestParams::nsXPCTestParams() 1.15 +{ 1.16 +} 1.17 + 1.18 +nsXPCTestParams::~nsXPCTestParams() 1.19 +{ 1.20 +} 1.21 + 1.22 +#define GENERIC_METHOD_IMPL { \ 1.23 + *_retval = *b; \ 1.24 + *b = a; \ 1.25 + return NS_OK; \ 1.26 +} 1.27 + 1.28 +#define STRING_METHOD_IMPL { \ 1.29 + _retval.Assign(b); \ 1.30 + b.Assign(a); \ 1.31 + return NS_OK; \ 1.32 +} 1.33 + 1.34 +#define TAKE_OWNERSHIP_NOOP(val) {} 1.35 +#define TAKE_OWNERSHIP_INTERFACE(val) {static_cast<nsISupports*>(val)->AddRef();} 1.36 +#define TAKE_OWNERSHIP_STRING(val) { \ 1.37 + nsDependentCString vprime(val); \ 1.38 + val = ToNewCString(vprime); \ 1.39 +} 1.40 +#define TAKE_OWNERSHIP_WSTRING(val) { \ 1.41 + nsDependentString vprime(val); \ 1.42 + val = ToNewUnicode(vprime); \ 1.43 +} 1.44 + 1.45 +// Macro for our buffer-oriented types: 1.46 +// 'type' is the type of element that the buffer contains. 1.47 +// 'padding' is an offset added to length, allowing us to handle 1.48 +// null-terminated strings. 1.49 +// 'TAKE_OWNERSHIP' is one of the macros above. 1.50 +#define BUFFER_METHOD_IMPL(type, padding, TAKE_OWNERSHIP) { \ 1.51 + uint32_t elemSize = sizeof(type); \ 1.52 + \ 1.53 + /* Copy b into rv. */ \ 1.54 + *rvLength = *bLength; \ 1.55 + *rv = static_cast<type*>(NS_Alloc(elemSize * (*bLength + padding))); \ 1.56 + if (!*rv) \ 1.57 + return NS_ERROR_OUT_OF_MEMORY; \ 1.58 + memcpy(*rv, *b, elemSize * (*bLength + padding)); \ 1.59 + \ 1.60 + /* Copy a into b. */ \ 1.61 + *bLength = aLength; \ 1.62 + NS_Free(*b); \ 1.63 + *b = static_cast<type*>(NS_Alloc(elemSize * (aLength + padding))); \ 1.64 + if (!*b) \ 1.65 + return NS_ERROR_OUT_OF_MEMORY; \ 1.66 + memcpy(*b, a, elemSize * (aLength + padding)); \ 1.67 + \ 1.68 + /* We need to take ownership of the data we got from a, \ 1.69 + since the caller owns it. */ \ 1.70 + for (unsigned i = 0; i < *bLength + padding; ++i) \ 1.71 + TAKE_OWNERSHIP((*b)[i]); \ 1.72 + \ 1.73 + return NS_OK; \ 1.74 +} 1.75 + 1.76 +/* boolean testBoolean (in boolean a, inout boolean b); */ 1.77 +NS_IMETHODIMP nsXPCTestParams::TestBoolean(bool a, bool *b, bool *_retval) 1.78 +{ 1.79 + GENERIC_METHOD_IMPL; 1.80 +} 1.81 + 1.82 +/* octet testOctet (in octet a, inout octet b); */ 1.83 +NS_IMETHODIMP nsXPCTestParams::TestOctet(uint8_t a, uint8_t *b, uint8_t *_retval) 1.84 +{ 1.85 + GENERIC_METHOD_IMPL; 1.86 +} 1.87 + 1.88 +/* short testShort (in short a, inout short b); */ 1.89 +NS_IMETHODIMP nsXPCTestParams::TestShort(int16_t a, int16_t *b, int16_t *_retval) 1.90 +{ 1.91 + GENERIC_METHOD_IMPL; 1.92 +} 1.93 + 1.94 +/* long testLong (in long a, inout long b); */ 1.95 +NS_IMETHODIMP nsXPCTestParams::TestLong(int32_t a, int32_t *b, int32_t *_retval) 1.96 +{ 1.97 + GENERIC_METHOD_IMPL; 1.98 +} 1.99 + 1.100 +/* long long testLongLong (in long long a, inout long long b); */ 1.101 +NS_IMETHODIMP nsXPCTestParams::TestLongLong(int64_t a, int64_t *b, int64_t *_retval) 1.102 +{ 1.103 + GENERIC_METHOD_IMPL; 1.104 +} 1.105 + 1.106 +/* unsigned short testUnsignedShort (in unsigned short a, inout unsigned short b); */ 1.107 +NS_IMETHODIMP nsXPCTestParams::TestUnsignedShort(uint16_t a, uint16_t *b, uint16_t *_retval) 1.108 +{ 1.109 + GENERIC_METHOD_IMPL; 1.110 +} 1.111 + 1.112 +/* unsigned long testUnsignedLong (in unsigned long a, inout unsigned long b); */ 1.113 +NS_IMETHODIMP nsXPCTestParams::TestUnsignedLong(uint32_t a, uint32_t *b, uint32_t *_retval) 1.114 +{ 1.115 + GENERIC_METHOD_IMPL; 1.116 +} 1.117 + 1.118 +/* unsigned long long testUnsignedLongLong (in unsigned long long a, inout unsigned long long b); */ 1.119 +NS_IMETHODIMP nsXPCTestParams::TestUnsignedLongLong(uint64_t a, uint64_t *b, uint64_t *_retval) 1.120 +{ 1.121 + GENERIC_METHOD_IMPL; 1.122 +} 1.123 + 1.124 +/* float testFloat (in float a, inout float b); */ 1.125 +NS_IMETHODIMP nsXPCTestParams::TestFloat(float a, float *b, float *_retval) 1.126 +{ 1.127 + GENERIC_METHOD_IMPL; 1.128 +} 1.129 + 1.130 +/* double testDouble (in double a, inout float b); */ 1.131 +NS_IMETHODIMP nsXPCTestParams::TestDouble(double a, float *b, double *_retval) 1.132 +{ 1.133 + GENERIC_METHOD_IMPL; 1.134 +} 1.135 + 1.136 +/* char testChar (in char a, inout char b); */ 1.137 +NS_IMETHODIMP nsXPCTestParams::TestChar(char a, char *b, char *_retval) 1.138 +{ 1.139 + GENERIC_METHOD_IMPL; 1.140 +} 1.141 + 1.142 +/* string testString (in string a, inout string b); */ 1.143 +NS_IMETHODIMP nsXPCTestParams::TestString(const char * a, char * *b, char * *_retval) 1.144 +{ 1.145 + nsDependentCString aprime(a); 1.146 + nsDependentCString bprime(*b); 1.147 + *_retval = ToNewCString(bprime); 1.148 + *b = ToNewCString(aprime); 1.149 + 1.150 + // XPCOM ownership rules dictate that overwritten inout params must be callee-freed. 1.151 + // See https://developer.mozilla.org/en/XPIDL 1.152 + NS_Free(const_cast<char*>(bprime.get())); 1.153 + 1.154 + return NS_OK; 1.155 +} 1.156 + 1.157 +/* wchar testWchar (in wchar a, inout wchar b); */ 1.158 +NS_IMETHODIMP nsXPCTestParams::TestWchar(char16_t a, char16_t *b, char16_t *_retval) 1.159 +{ 1.160 + GENERIC_METHOD_IMPL; 1.161 +} 1.162 + 1.163 +/* wstring testWstring (in wstring a, inout wstring b); */ 1.164 +NS_IMETHODIMP nsXPCTestParams::TestWstring(const char16_t * a, char16_t * *b, char16_t * *_retval) 1.165 +{ 1.166 + nsDependentString aprime(a); 1.167 + nsDependentString bprime(*b); 1.168 + *_retval = ToNewUnicode(bprime); 1.169 + *b = ToNewUnicode(aprime); 1.170 + 1.171 + // XPCOM ownership rules dictate that overwritten inout params must be callee-freed. 1.172 + // See https://developer.mozilla.org/en/XPIDL 1.173 + NS_Free((void*)bprime.get()); 1.174 + 1.175 + return NS_OK; 1.176 +} 1.177 + 1.178 +/* DOMString testDOMString (in DOMString a, inout DOMString b); */ 1.179 +NS_IMETHODIMP nsXPCTestParams::TestDOMString(const nsAString & a, nsAString & b, nsAString & _retval) 1.180 +{ 1.181 + STRING_METHOD_IMPL; 1.182 +} 1.183 + 1.184 + 1.185 +/* AString testAString (in AString a, inout AString b); */ 1.186 +NS_IMETHODIMP nsXPCTestParams::TestAString(const nsAString & a, nsAString & b, nsAString & _retval) 1.187 +{ 1.188 + STRING_METHOD_IMPL; 1.189 +} 1.190 + 1.191 +/* AUTF8String testAUTF8String (in AUTF8String a, inout AUTF8String b); */ 1.192 +NS_IMETHODIMP nsXPCTestParams::TestAUTF8String(const nsACString & a, nsACString & b, nsACString & _retval) 1.193 +{ 1.194 + STRING_METHOD_IMPL; 1.195 +} 1.196 + 1.197 +/* ACString testACString (in ACString a, inout ACString b); */ 1.198 +NS_IMETHODIMP nsXPCTestParams::TestACString(const nsACString & a, nsACString & b, nsACString & _retval) 1.199 +{ 1.200 + STRING_METHOD_IMPL; 1.201 +} 1.202 + 1.203 +/* jsval testJsval (in jsval a, in jsval b); */ 1.204 +NS_IMETHODIMP nsXPCTestParams::TestJsval(JS::Handle<JS::Value> a, 1.205 + JS::MutableHandle<JS::Value> b, 1.206 + JS::MutableHandle<JS::Value> _retval) 1.207 +{ 1.208 + _retval.set(b); 1.209 + b.set(a); 1.210 + return NS_OK; 1.211 +} 1.212 + 1.213 +/* void testShortArray (in unsigned long aLength, [array, size_is (aLength)] in short a, 1.214 + * inout unsigned long bLength, [array, size_is (bLength)] inout short b, 1.215 + * out unsigned long rvLength, [array, size_is (rvLength), retval] out short rv); */ 1.216 +NS_IMETHODIMP nsXPCTestParams::TestShortArray(uint32_t aLength, int16_t *a, 1.217 + uint32_t *bLength, int16_t **b, 1.218 + uint32_t *rvLength, int16_t **rv) 1.219 +{ 1.220 + BUFFER_METHOD_IMPL(int16_t, 0, TAKE_OWNERSHIP_NOOP); 1.221 +} 1.222 + 1.223 +/* void testDoubleArray (in unsigned long aLength, [array, size_is (aLength)] in double a, 1.224 + * inout unsigned long bLength, [array, size_is (bLength)] inout double b, 1.225 + * out unsigned long rvLength, [array, size_is (rvLength), retval] out double rv); */ 1.226 +NS_IMETHODIMP nsXPCTestParams::TestDoubleArray(uint32_t aLength, double *a, 1.227 + uint32_t *bLength, double **b, 1.228 + uint32_t *rvLength, double **rv) 1.229 +{ 1.230 + BUFFER_METHOD_IMPL(double, 0, TAKE_OWNERSHIP_NOOP); 1.231 +} 1.232 + 1.233 +/* void testStringArray (in unsigned long aLength, [array, size_is (aLength)] in string a, 1.234 + * inout unsigned long bLength, [array, size_is (bLength)] inout string b, 1.235 + * out unsigned long rvLength, [array, size_is (rvLength), retval] out string rv); */ 1.236 +NS_IMETHODIMP nsXPCTestParams::TestStringArray(uint32_t aLength, const char * *a, 1.237 + uint32_t *bLength, char * **b, 1.238 + uint32_t *rvLength, char * **rv) 1.239 +{ 1.240 + BUFFER_METHOD_IMPL(char*, 0, TAKE_OWNERSHIP_STRING); 1.241 +} 1.242 + 1.243 +/* void testWstringArray (in unsigned long aLength, [array, size_is (aLength)] in wstring a, 1.244 + * inout unsigned long bLength, [array, size_is (bLength)] inout wstring b, 1.245 + * out unsigned long rvLength, [array, size_is (rvLength), retval] out wstring rv); */ 1.246 +NS_IMETHODIMP nsXPCTestParams::TestWstringArray(uint32_t aLength, const char16_t * *a, 1.247 + uint32_t *bLength, char16_t * **b, 1.248 + uint32_t *rvLength, char16_t * **rv) 1.249 +{ 1.250 + BUFFER_METHOD_IMPL(char16_t*, 0, TAKE_OWNERSHIP_WSTRING); 1.251 +} 1.252 + 1.253 +/* void testInterfaceArray (in unsigned long aLength, [array, size_is (aLength)] in nsIXPCTestInterfaceA a, 1.254 + * inout unsigned long bLength, [array, size_is (bLength)] inout nsIXPCTestInterfaceA b, 1.255 + * out unsigned long rvLength, [array, size_is (rvLength), retval] out nsIXPCTestInterfaceA rv); */ 1.256 +NS_IMETHODIMP nsXPCTestParams::TestInterfaceArray(uint32_t aLength, nsIXPCTestInterfaceA **a, 1.257 + uint32_t *bLength, nsIXPCTestInterfaceA * **b, 1.258 + uint32_t *rvLength, nsIXPCTestInterfaceA * **rv) 1.259 +{ 1.260 + BUFFER_METHOD_IMPL(nsIXPCTestInterfaceA*, 0, TAKE_OWNERSHIP_INTERFACE); 1.261 +} 1.262 + 1.263 +/* void testSizedString (in unsigned long aLength, [size_is (aLength)] in string a, 1.264 + * inout unsigned long bLength, [size_is (bLength)] inout string b, 1.265 + * out unsigned long rvLength, [size_is (rvLength), retval] out string rv); */ 1.266 +NS_IMETHODIMP nsXPCTestParams::TestSizedString(uint32_t aLength, const char * a, 1.267 + uint32_t *bLength, char * *b, 1.268 + uint32_t *rvLength, char * *rv) 1.269 +{ 1.270 + BUFFER_METHOD_IMPL(char, 1, TAKE_OWNERSHIP_NOOP); 1.271 +} 1.272 + 1.273 +/* void testSizedWstring (in unsigned long aLength, [size_is (aLength)] in wstring a, 1.274 + * inout unsigned long bLength, [size_is (bLength)] inout wstring b, 1.275 + * out unsigned long rvLength, [size_is (rvLength), retval] out wstring rv); */ 1.276 +NS_IMETHODIMP nsXPCTestParams::TestSizedWstring(uint32_t aLength, const char16_t * a, 1.277 + uint32_t *bLength, char16_t * *b, 1.278 + uint32_t *rvLength, char16_t * *rv) 1.279 +{ 1.280 + BUFFER_METHOD_IMPL(char16_t, 1, TAKE_OWNERSHIP_NOOP); 1.281 +} 1.282 + 1.283 +/* void testInterfaceIs (in nsIIDPtr aIID, [iid_is (aIID)] in nsQIResult a, 1.284 + * inout nsIIDPtr bIID, [iid_is (bIID)] inout nsQIResult b, 1.285 + * out nsIIDPtr rvIID, [iid_is (rvIID), retval] out nsQIResult rv); */ 1.286 +NS_IMETHODIMP nsXPCTestParams::TestInterfaceIs(const nsIID *aIID, void *a, 1.287 + nsIID **bIID, void **b, 1.288 + nsIID **rvIID, void **rv) 1.289 +{ 1.290 + // 1.291 + // Getting the buffers and ownership right here can be a little tricky. 1.292 + // 1.293 + 1.294 + // The interface pointers are heap-allocated, and b has been AddRef'd 1.295 + // by XPConnect for the duration of the call. If we snatch it away from b 1.296 + // and leave no trace, XPConnect won't Release it. Since we also need to 1.297 + // return an already-AddRef'd pointer in rv, we don't need to do anything 1.298 + // special here. 1.299 + *rv = *b; 1.300 + 1.301 + // rvIID is out-only, so nobody allocated an IID buffer for us. Do that now, 1.302 + // and store b's IID in the new buffer. 1.303 + *rvIID = static_cast<nsIID*>(NS_Alloc(sizeof(nsID))); 1.304 + if (!*rvIID) 1.305 + return NS_ERROR_OUT_OF_MEMORY; 1.306 + **rvIID = **bIID; 1.307 + 1.308 + // Copy the interface pointer from a to b. Since a is in-only, XPConnect will 1.309 + // release it upon completion of the call. AddRef it for b. 1.310 + *b = a; 1.311 + static_cast<nsISupports*>(*b)->AddRef(); 1.312 + 1.313 + // We already had a buffer allocated for b's IID, so we can re-use it. 1.314 + **bIID = *aIID; 1.315 + 1.316 + return NS_OK; 1.317 +} 1.318 + 1.319 +/* void testInterfaceIsArray (in unsigned long aLength, in nsIIDPtr aIID, 1.320 + * [array, size_is (aLength), iid_is (aIID)] in nsQIResult a, 1.321 + * inout unsigned long bLength, inout nsIIDPtr bIID, 1.322 + * [array, size_is (bLength), iid_is (bIID)] inout nsQIResult b, 1.323 + * out unsigned long rvLength, out nsIIDPtr rvIID, 1.324 + * [retval, array, size_is (rvLength), iid_is (rvIID)] out nsQIResult rv); */ 1.325 +NS_IMETHODIMP nsXPCTestParams::TestInterfaceIsArray(uint32_t aLength, const nsIID *aIID, 1.326 + void **a, 1.327 + uint32_t *bLength, nsIID **bIID, 1.328 + void ***b, 1.329 + uint32_t *rvLength, nsIID **rvIID, 1.330 + void ***rv) 1.331 +{ 1.332 + // Transfer the IIDs. See the comments in TestInterfaceIs (above) for an 1.333 + // explanation of what we're doing. 1.334 + *rvIID = static_cast<nsIID*>(NS_Alloc(sizeof(nsID))); 1.335 + if (!*rvIID) 1.336 + return NS_ERROR_OUT_OF_MEMORY; 1.337 + **rvIID = **bIID; 1.338 + **bIID = *aIID; 1.339 + 1.340 + // The macro is agnostic to the actual interface types, so we can re-use code here. 1.341 + // 1.342 + // Do this second, since the macro returns. 1.343 + BUFFER_METHOD_IMPL(void*, 0, TAKE_OWNERSHIP_INTERFACE); 1.344 +}