#include #undef NAPI_STATUS_THROWS #define NAPI_STATUS_THROWS(call) \ if ((call) != napi_ok) { \ napi_throw_error(env, NULL, #call " failed!"); \ } #define NAPI_DCN_CONTEXT() \ dcn_context_t* dcn_context; \ NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], (void**)&dcn_context)); \ if (!dcn_context) { \ const char* msg = "Provided dnc_context is null"; \ NAPI_STATUS_THROWS(napi_throw_type_error(env, NULL, msg)); \ } \ if (!dcn_context->dc_context) { \ const char* msg = "Provided dc_context is null, did you close the context or not open it?"; \ NAPI_STATUS_THROWS(napi_throw_type_error(env, NULL, msg)); \ } #define NAPI_DCN_ACCOUNTS() \ dcn_accounts_t* dcn_accounts; \ NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], (void**)&dcn_accounts)); \ if (!dcn_accounts) { \ const char* msg = "Provided dcn_acounts is null"; \ NAPI_STATUS_THROWS(napi_throw_type_error(env, NULL, msg)); \ } \ if (!dcn_accounts->dc_accounts) { \ const char* msg = "Provided dc_accounts is null, did you unref the accounts object?"; \ NAPI_STATUS_THROWS(napi_throw_type_error(env, NULL, msg)); \ } #define NAPI_DC_CHAT() \ dc_chat_t* dc_chat; \ NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], (void**)&dc_chat)); #define NAPI_DC_CHATLIST() \ dc_chatlist_t* dc_chatlist; \ NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], (void**)&dc_chatlist)); #define NAPI_DC_CONTACT() \ dc_contact_t* dc_contact; \ NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], (void**)&dc_contact)); #define NAPI_DC_LOT() \ dc_lot_t* dc_lot; \ NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], (void**)&dc_lot)); #define NAPI_DC_MSG() \ dc_msg_t* dc_msg; \ NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], (void**)&dc_msg)); #define NAPI_ARGV_DC_MSG(name, position) \ dc_msg_t* name; \ NAPI_STATUS_THROWS(napi_get_value_external(env, argv[position], (void**)&name)); #define NAPI_DC_PROVIDER() \ dc_provider_t* dc_provider; \ NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], (void**)&dc_provider)); #define NAPI_DC_ARRAY() \ dc_array_t* dc_array; \ NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], (void**)&dc_array)); #define NAPI_RETURN_UNDEFINED() \ return 0; #define NAPI_RETURN_UINT64(name) \ napi_value return_int64; \ NAPI_STATUS_THROWS(napi_create_bigint_int64(env, name, &return_int64)); \ return return_int64; #define NAPI_RETURN_INT64(name) \ napi_value return_int64; \ NAPI_STATUS_THROWS(napi_create_int64(env, name, &return_int64)); \ return return_int64; #define NAPI_RETURN_AND_UNREF_STRING(name) \ napi_value return_value; \ if (name == NULL) { \ NAPI_STATUS_THROWS(napi_get_null(env, &return_value)); \ return return_value; \ } \ NAPI_STATUS_THROWS(napi_create_string_utf8(env, name, NAPI_AUTO_LENGTH, &return_value)); \ dc_str_unref(name); \ return return_value; #define NAPI_ASYNC_CARRIER_BEGIN(name) \ typedef struct name##_carrier_t { \ napi_ref callback_ref; \ napi_async_work async_work; \ dcn_context_t* dcn_context; #define NAPI_ASYNC_CARRIER_END(name) \ } name##_carrier_t; #define NAPI_ASYNC_EXECUTE(name) \ static void name##_execute(napi_env env, void* data) #define NAPI_ASYNC_GET_CARRIER(name) \ name##_carrier_t* carrier = (name##_carrier_t*)data; #define NAPI_ASYNC_COMPLETE(name) \ static void name##_complete(napi_env env, napi_status status, void* data) #define NAPI_ASYNC_CALL_AND_DELETE_CB() \ napi_value global; \ NAPI_STATUS_THROWS(napi_get_global(env, &global)); \ napi_value callback; \ NAPI_STATUS_THROWS(napi_get_reference_value(env, carrier->callback_ref, &callback)); \ NAPI_STATUS_THROWS(napi_call_function(env, global, callback, argc, argv, NULL)); \ NAPI_STATUS_THROWS(napi_delete_reference(env, carrier->callback_ref)); \ NAPI_STATUS_THROWS(napi_delete_async_work(env, carrier->async_work)); #define NAPI_ASYNC_NEW_CARRIER(name) \ name##_carrier_t* carrier = calloc(1, sizeof(name##_carrier_t)); \ carrier->dcn_context = dcn_context; #define NAPI_ASYNC_QUEUE_WORK(name, cb) \ napi_value callback = cb; \ napi_value async_resource_name; \ NAPI_STATUS_THROWS(napi_create_reference(env, callback, 1, &carrier->callback_ref)); \ NAPI_STATUS_THROWS(napi_create_string_utf8(env, #name "_callback", \ NAPI_AUTO_LENGTH, \ &async_resource_name)); \ NAPI_STATUS_THROWS(napi_create_async_work(env, callback, async_resource_name, \ name##_execute, name##_complete, \ carrier, &carrier->async_work)); \ NAPI_STATUS_THROWS(napi_queue_async_work(env, carrier->async_work)); /*** this could/should be moved to napi-macros ***/ #define NAPI_DOUBLE(name, val) \ double name; \ if (napi_get_value_double(env, val, &name) != napi_ok) { \ napi_throw_error(env, "EINVAL", "Expected double"); \ return NULL; \ } #define NAPI_ARGV_DOUBLE(name, i) \ NAPI_DOUBLE(name, argv[i])