1#include <js_native_api.h>
2
3#include "../common.h"
4#include "test_null.h"
5
6#define GEN_NULL_CHECK_BINDING(binding_name, output_type, api)            \
7  static napi_value binding_name(napi_env env, napi_callback_info info) { \
8    napi_value return_value;                                              \
9    output_type result;                                                   \
10    NODE_API_CALL(env, napi_create_object(env, &return_value));           \
11    add_returned_status(env,                                              \
12                        "envIsNull",                                      \
13                        return_value,                                     \
14                        "Invalid argument",                               \
15                        napi_invalid_arg,                                 \
16                        api(NULL, return_value, &result));                \
17    api(env, NULL, &result);                                              \
18    add_last_status(env, "valueIsNull", return_value);                    \
19    api(env, return_value, NULL);                                         \
20    add_last_status(env, "resultIsNull", return_value);                   \
21    api(env, return_value, &result);                                      \
22    add_last_status(env, "inputTypeCheck", return_value);                 \
23    return return_value;                                                  \
24  }
25
26GEN_NULL_CHECK_BINDING(GetValueBool, bool, napi_get_value_bool)
27GEN_NULL_CHECK_BINDING(GetValueInt32, int32_t, napi_get_value_int32)
28GEN_NULL_CHECK_BINDING(GetValueUint32, uint32_t, napi_get_value_uint32)
29GEN_NULL_CHECK_BINDING(GetValueInt64, int64_t, napi_get_value_int64)
30GEN_NULL_CHECK_BINDING(GetValueDouble, double, napi_get_value_double)
31GEN_NULL_CHECK_BINDING(CoerceToBool, napi_value, napi_coerce_to_bool)
32GEN_NULL_CHECK_BINDING(CoerceToObject, napi_value, napi_coerce_to_object)
33GEN_NULL_CHECK_BINDING(CoerceToString, napi_value, napi_coerce_to_string)
34
35#define GEN_NULL_CHECK_STRING_BINDING(binding_name, arg_type, api)         \
36  static napi_value binding_name(napi_env env, napi_callback_info info) {  \
37    napi_value return_value;                                               \
38    NODE_API_CALL(env, napi_create_object(env, &return_value));            \
39    arg_type buf1[4];                                                      \
40    size_t length1 = 3;                                                    \
41    add_returned_status(env,                                               \
42                        "envIsNull",                                       \
43                        return_value,                                      \
44                        "Invalid argument",                                \
45                        napi_invalid_arg,                                  \
46                        api(NULL, return_value, buf1, length1, &length1)); \
47    arg_type buf2[4];                                                      \
48    size_t length2 = 3;                                                    \
49    api(env, NULL, buf2, length2, &length2);                               \
50    add_last_status(env, "valueIsNull", return_value);                     \
51    api(env, return_value, NULL, 3, NULL);                                 \
52    add_last_status(env, "wrongTypeIn", return_value);                     \
53    napi_value string;                                                     \
54    NODE_API_CALL(env,                                                     \
55              napi_create_string_utf8(env,                                 \
56                                      "Something",                         \
57                                      NAPI_AUTO_LENGTH,                    \
58                                      &string));                           \
59    api(env, string, NULL, 3, NULL);                                       \
60    add_last_status(env, "bufAndOutLengthIsNull", return_value);           \
61    return return_value;                                                   \
62  }
63
64GEN_NULL_CHECK_STRING_BINDING(GetValueStringUtf8,
65                              char,
66                              napi_get_value_string_utf8)
67GEN_NULL_CHECK_STRING_BINDING(GetValueStringLatin1,
68                              char,
69                              napi_get_value_string_latin1)
70GEN_NULL_CHECK_STRING_BINDING(GetValueStringUtf16,
71                              char16_t,
72                              napi_get_value_string_utf16)
73
74void init_test_null(napi_env env, napi_value exports) {
75  napi_value test_null;
76
77  const napi_property_descriptor test_null_props[] = {
78    DECLARE_NODE_API_PROPERTY("getValueBool", GetValueBool),
79    DECLARE_NODE_API_PROPERTY("getValueInt32", GetValueInt32),
80    DECLARE_NODE_API_PROPERTY("getValueUint32", GetValueUint32),
81    DECLARE_NODE_API_PROPERTY("getValueInt64", GetValueInt64),
82    DECLARE_NODE_API_PROPERTY("getValueDouble", GetValueDouble),
83    DECLARE_NODE_API_PROPERTY("coerceToBool", CoerceToBool),
84    DECLARE_NODE_API_PROPERTY("coerceToObject", CoerceToObject),
85    DECLARE_NODE_API_PROPERTY("coerceToString", CoerceToString),
86    DECLARE_NODE_API_PROPERTY("getValueStringUtf8", GetValueStringUtf8),
87    DECLARE_NODE_API_PROPERTY("getValueStringLatin1", GetValueStringLatin1),
88    DECLARE_NODE_API_PROPERTY("getValueStringUtf16", GetValueStringUtf16),
89  };
90
91  NODE_API_CALL_RETURN_VOID(env, napi_create_object(env, &test_null));
92  NODE_API_CALL_RETURN_VOID(env, napi_define_properties(
93      env, test_null, sizeof(test_null_props) / sizeof(*test_null_props),
94      test_null_props));
95
96  const napi_property_descriptor test_null_set = {
97    "testNull", NULL, NULL, NULL, NULL, test_null, napi_enumerable, NULL
98  };
99
100  NODE_API_CALL_RETURN_VOID(env,
101      napi_define_properties(env, exports, 1, &test_null_set));
102}
103