1+ using System . Collections . Generic ;
2+ using System . IO ;
3+ using CppSharp . AST ;
4+ using CppSharp . Generators . C ;
5+
6+ namespace CppSharp . Generators . Cpp
7+ {
8+ /// <summary>
9+ /// Generates a common Node N-API C/C++ common files.
10+ /// N-API documentation: https://nodejs.org/api/n-api.html
11+ /// </summary>
12+ public class NAPIHelpers : CppHeaders
13+ {
14+ public NAPIHelpers ( BindingContext context )
15+ : base ( context , null )
16+ {
17+ }
18+
19+ public override void Process ( )
20+ {
21+ GenerateFilePreamble ( CommentKind . BCPL ) ;
22+
23+ WriteLine ( "#pragma once" ) ;
24+ NewLine ( ) ;
25+
26+ WriteInclude ( "math.h" , CInclude . IncludeKind . Angled ) ;
27+ WriteInclude ( "limits.h" , CInclude . IncludeKind . Angled ) ;
28+ NewLine ( ) ;
29+
30+ GenerateHelpers ( ) ;
31+ return ;
32+ }
33+
34+ private void GenerateHelpers ( )
35+ {
36+ WriteLine ( @"#define NAPI_CALL(env, call) \
37+ do { \
38+ napi_status status = (call); \
39+ if (status != napi_ok) { \
40+ const napi_extended_error_info* error_info = NULL; \
41+ napi_get_last_error_info((env), &error_info); \
42+ bool is_pending; \
43+ napi_is_exception_pending((env), &is_pending); \
44+ if (!is_pending) { \
45+ const char* message = (error_info->error_message == NULL) \
46+ ? ""empty error message"" \
47+ : error_info->error_message; \
48+ napi_throw_error((env), NULL, message); \
49+ return NULL; \
50+ } \
51+ } \
52+ } while(0)" ) ;
53+ NewLine ( ) ;
54+
55+ WriteLine ( @"#define NAPI_CALL_NORET(env, call) \
56+ do { \
57+ napi_status status = (call); \
58+ if (status != napi_ok) { \
59+ const napi_extended_error_info* error_info = NULL; \
60+ napi_get_last_error_info((env), &error_info); \
61+ bool is_pending; \
62+ napi_is_exception_pending((env), &is_pending); \
63+ if (!is_pending) { \
64+ const char* message = (error_info->error_message == NULL) \
65+ ? ""empty error message"" \
66+ : error_info->error_message; \
67+ napi_throw_error((env), NULL, message); \
68+ return; \
69+ } \
70+ } \
71+ } while(0)" ) ;
72+ NewLine ( ) ;
73+
74+ WriteLine ( @"static int napi_is_int32(napi_env env, napi_value value, int* integer) {
75+ double temp = 0;
76+ if (
77+ // We get the value as a double so we can check for NaN, Infinity and float:
78+ // https://github.com/nodejs/node/issues/26323
79+ napi_get_value_double(env, value, &temp) != napi_ok ||
80+ // Reject NaN:
81+ isnan(temp) ||
82+ // Reject Infinity and avoid undefined behavior when casting double to int:
83+ // https://groups.google.com/forum/#!topic/comp.lang.c/rhPzd4bgKJk
84+ temp < INT_MIN ||
85+ temp > INT_MAX ||
86+ // Reject float by casting double to int:
87+ (double) ((int) temp) != temp
88+ ) {
89+ //napi_throw_error(env, NULL, ""argument must be an integer"");
90+ return 0;
91+ }
92+ if (integer)
93+ *integer = (int) temp;
94+ return 1;
95+ }" ) ;
96+ NewLine ( ) ;
97+
98+ WriteLine ( @"static int napi_is_uint32(napi_env env, napi_value value, int* integer) {
99+ double temp = 0;
100+ if (
101+ // We get the value as a double so we can check for NaN, Infinity and float:
102+ // https://github.com/nodejs/node/issues/26323
103+ napi_get_value_double(env, value, &temp) != napi_ok ||
104+ // Reject NaN:
105+ isnan(temp) ||
106+ // Reject Infinity and avoid undefined behavior when casting double to int:
107+ // https://groups.google.com/forum/#!topic/comp.lang.c/rhPzd4bgKJk
108+ temp < 0 ||
109+ temp > ULONG_MAX ||
110+ // Reject float by casting double to int:
111+ (double) ((unsigned long) temp) != temp
112+ ) {
113+ //napi_throw_error(env, NULL, ""argument must be an integer"");
114+ return 0;
115+ }
116+ if (integer)
117+ *integer = (int) temp;
118+ return 1;
119+ }" ) ;
120+ NewLine ( ) ;
121+
122+ WriteLine ( @"#define NAPI_IS_BOOL(valuetype) (valuetype == napi_boolean)" ) ;
123+ WriteLine ( @"#define NAPI_IS_NULL(valuetype) (valuetype == napi_null)" ) ;
124+ WriteLine ( @"#define NAPI_IS_NUMBER(valuetype) (valuetype == napi_number)" ) ;
125+ WriteLine ( @"#define NAPI_IS_BIGINT(valuetype) (valuetype == napi_bigint)" ) ;
126+ WriteLine ( @"#define NAPI_IS_INT32(valuetype, value) (NAPI_IS_NUMBER(valuetype) && napi_is_int32(env, value, nullptr))" ) ;
127+ WriteLine ( @"#define NAPI_IS_UINT32(valuetype, value) (NAPI_IS_NUMBER(valuetype) && napi_is_uint32(env, value, nullptr))" ) ;
128+ WriteLine ( @"#define NAPI_IS_INT64(valuetype, value) (NAPI_IS_BIGINT(valuetype))" ) ;
129+ WriteLine ( @"#define NAPI_IS_UINT64(valuetype, value) (NAPI_IS_BIGINT(valuetype))" ) ;
130+ NewLine ( ) ;
131+ }
132+ }
133+ }
0 commit comments