| 316 | } |
| 317 | |
| 318 | bool VariantUtilities::ExecuteToJsonMethod(VARIANT object_to_serialize, |
| 319 | VARIANT* json_object_variant) { |
| 320 | CComVariant to_json_method; |
| 321 | bool has_to_json_property = GetVariantObjectPropertyValue(object_to_serialize.pdispVal, |
| 322 | L"toJSON", |
| 323 | &to_json_method); |
| 324 | if (!has_to_json_property) { |
| 325 | LOG(DEBUG) << "No toJSON property found on IDispatch"; |
| 326 | return false; |
| 327 | } |
| 328 | |
| 329 | // Grab the "call" method out of the returned function |
| 330 | DISPID call_member_id; |
| 331 | OLECHAR FAR* call_member_name = L"call"; |
| 332 | HRESULT hr = to_json_method.pdispVal->GetIDsOfNames(IID_NULL, |
| 333 | &call_member_name, |
| 334 | 1, |
| 335 | LOCALE_USER_DEFAULT, |
| 336 | &call_member_id); |
| 337 | if (FAILED(hr)) { |
| 338 | LOGHR(WARN, hr) << "Cannot locate call method on toJSON function"; |
| 339 | return false; |
| 340 | } |
| 341 | |
| 342 | // IDispatch::Invoke() expects the arguments to be passed into it |
| 343 | // in reverse order. To accomplish this, we create a new variant |
| 344 | // array of size n + 1 where n is the number of arguments we have. |
| 345 | // we copy each element of arguments_array_ into the new array in |
| 346 | // reverse order, and add an extra argument, the window object, |
| 347 | // to the end of the array to use as the "this" parameter for the |
| 348 | // function invocation. |
| 349 | std::vector<CComVariant> argument_array(1); |
| 350 | argument_array[0].Copy(&object_to_serialize); |
| 351 | |
| 352 | DISPPARAMS call_parameters = { 0 }; |
| 353 | memset(&call_parameters, 0, sizeof call_parameters); |
| 354 | call_parameters.cArgs = static_cast<unsigned int>(argument_array.size()); |
| 355 | call_parameters.rgvarg = &argument_array[0]; |
| 356 | |
| 357 | CComBSTR error_description = L""; |
| 358 | |
| 359 | int return_code = WD_SUCCESS; |
| 360 | EXCEPINFO exception; |
| 361 | memset(&exception, 0, sizeof exception); |
| 362 | hr = to_json_method.pdispVal->Invoke(call_member_id, |
| 363 | IID_NULL, |
| 364 | LOCALE_USER_DEFAULT, |
| 365 | DISPATCH_METHOD, |
| 366 | &call_parameters, |
| 367 | json_object_variant, |
| 368 | &exception, |
| 369 | 0); |
| 370 | |
| 371 | if (FAILED(hr)) { |
| 372 | if (DISP_E_EXCEPTION == hr) { |
| 373 | error_description = exception.bstrDescription ? exception.bstrDescription : L"EUNEXPECTEDJSERROR"; |
| 374 | CComBSTR error_source(exception.bstrSource ? exception.bstrSource : L"EUNEXPECTEDJSERROR"); |
| 375 | LOG(INFO) << "Exception message was: '" << error_description << "'"; |