UNPKG

3.68 kBtext/x-cView Raw
1#define NAPI_VERSION 1
2#include <assert.h>
3#include <node_api.h>
4
5napi_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 // Alignment preamble.
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 // Realign mask and convert to 64 bit.
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 // Apply 64 bit mask in 8 byte chunks.
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 // Apply mask to remaining data.
74 //
75 uint8_t *pmaskAlignedArray = maskAlignedArray;
76
77 length %= 8;
78 while (length--) {
79 *destination++ = *source++ ^ *pmaskAlignedArray++;
80 }
81
82 return NULL;
83}
84
85napi_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 // Alignment preamble.
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 // Realign mask and convert to 64 bit.
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 // Apply 64 bit mask in 8 byte chunks.
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 // Apply mask to remaining data.
140 //
141 uint8_t *pmaskAlignedArray = maskAlignedArray;
142
143 length %= 8;
144 while (length--) {
145 *source++ ^= *pmaskAlignedArray++;
146 }
147
148 return NULL;
149}
150
151napi_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
171NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)