xpctest_params.cpp 11 KB

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