1 | #define NAPI_VERSION 1
|
2 | #include <assert.h>
|
3 | #include <node_api.h>
|
4 |
|
5 | napi_value Mask(napi_env env, napi_callback_info info) {
|
6 | napi_status status;
|
7 | size_t argc = 5;
|
8 | napi_value argv[5];
|
9 |
|
10 | status = napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
11 | assert(status == napi_ok);
|
12 |
|
13 | uint8_t *source;
|
14 | uint8_t *mask;
|
15 | uint8_t *destination;
|
16 | uint32_t offset;
|
17 | uint32_t length;
|
18 |
|
19 | status = napi_get_buffer_info(env, argv[0], (void **)&source, NULL);
|
20 | assert(status == napi_ok);
|
21 |
|
22 | status = napi_get_buffer_info(env, argv[1], (void **)&mask, NULL);
|
23 | assert(status == napi_ok);
|
24 |
|
25 | status = napi_get_buffer_info(env, argv[2], (void **)&destination, NULL);
|
26 | assert(status == napi_ok);
|
27 |
|
28 | status = napi_get_value_uint32(env, argv[3], &offset);
|
29 | assert(status == napi_ok);
|
30 |
|
31 | status = napi_get_value_uint32(env, argv[4], &length);
|
32 | assert(status == napi_ok);
|
33 |
|
34 | destination += offset;
|
35 | uint32_t index = 0;
|
36 |
|
37 |
|
38 |
|
39 |
|
40 | while (index < length && ((size_t)source % 8)) {
|
41 | *destination++ = *source++ ^ mask[index % 4];
|
42 | index++;
|
43 | }
|
44 |
|
45 | length -= index;
|
46 | if (!length)
|
47 | return NULL;
|
48 |
|
49 |
|
50 |
|
51 |
|
52 | uint8_t maskAlignedArray[8];
|
53 |
|
54 | for (uint8_t i = 0; i < 8; i++, index++) {
|
55 | maskAlignedArray[i] = mask[index % 4];
|
56 | }
|
57 |
|
58 |
|
59 |
|
60 |
|
61 | uint32_t loop = length / 8;
|
62 | uint64_t *pMask8 = (uint64_t *)maskAlignedArray;
|
63 |
|
64 | while (loop--) {
|
65 | uint64_t *pFrom8 = (uint64_t *)source;
|
66 | uint64_t *pTo8 = (uint64_t *)destination;
|
67 | *pTo8 = *pFrom8 ^ *pMask8;
|
68 | source += 8;
|
69 | destination += 8;
|
70 | }
|
71 |
|
72 |
|
73 |
|
74 |
|
75 | uint8_t *pmaskAlignedArray = maskAlignedArray;
|
76 |
|
77 | length %= 8;
|
78 | while (length--) {
|
79 | *destination++ = *source++ ^ *pmaskAlignedArray++;
|
80 | }
|
81 |
|
82 | return NULL;
|
83 | }
|
84 |
|
85 | napi_value Unmask(napi_env env, napi_callback_info info) {
|
86 | napi_status status;
|
87 | size_t argc = 2;
|
88 | napi_value argv[2];
|
89 |
|
90 | status = napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
91 | assert(status == napi_ok);
|
92 |
|
93 | uint8_t *source;
|
94 | size_t length;
|
95 | uint8_t *mask;
|
96 |
|
97 | status = napi_get_buffer_info(env, argv[0], (void **)&source, &length);
|
98 | assert(status == napi_ok);
|
99 |
|
100 | status = napi_get_buffer_info(env, argv[1], (void **)&mask, NULL);
|
101 | assert(status == napi_ok);
|
102 |
|
103 | uint32_t index = 0;
|
104 |
|
105 |
|
106 |
|
107 |
|
108 | while (index < length && ((size_t)source % 8)) {
|
109 | *source++ ^= mask[index % 4];
|
110 | index++;
|
111 | }
|
112 |
|
113 | length -= index;
|
114 | if (!length)
|
115 | return NULL;
|
116 |
|
117 |
|
118 |
|
119 |
|
120 | uint8_t maskAlignedArray[8];
|
121 |
|
122 | for (uint8_t i = 0; i < 8; i++, index++) {
|
123 | maskAlignedArray[i] = mask[index % 4];
|
124 | }
|
125 |
|
126 |
|
127 |
|
128 |
|
129 | uint32_t loop = length / 8;
|
130 | uint64_t *pMask8 = (uint64_t *)maskAlignedArray;
|
131 |
|
132 | while (loop--) {
|
133 | uint64_t *pSource8 = (uint64_t *)source;
|
134 | *pSource8 ^= *pMask8;
|
135 | source += 8;
|
136 | }
|
137 |
|
138 |
|
139 |
|
140 |
|
141 | uint8_t *pmaskAlignedArray = maskAlignedArray;
|
142 |
|
143 | length %= 8;
|
144 | while (length--) {
|
145 | *source++ ^= *pmaskAlignedArray++;
|
146 | }
|
147 |
|
148 | return NULL;
|
149 | }
|
150 |
|
151 | napi_value Init(napi_env env, napi_value exports) {
|
152 | napi_status status;
|
153 | napi_value mask;
|
154 | napi_value unmask;
|
155 |
|
156 | status = napi_create_function(env, NULL, 0, Mask, NULL, &mask);
|
157 | assert(status == napi_ok);
|
158 |
|
159 | status = napi_create_function(env, NULL, 0, Unmask, NULL, &unmask);
|
160 | assert(status == napi_ok);
|
161 |
|
162 | status = napi_set_named_property(env, exports, "mask", mask);
|
163 | assert(status == napi_ok);
|
164 |
|
165 | status = napi_set_named_property(env, exports, "unmask", unmask);
|
166 | assert(status == napi_ok);
|
167 |
|
168 | return exports;
|
169 | }
|
170 |
|
171 | NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
|