1 | /* |
2 | * Copyright 2008-2018 Aerospike, Inc. |
3 | * |
4 | * Portions may be licensed to Aerospike, Inc. under one or more contributor |
5 | * license agreements. |
6 | * |
7 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
8 | * use this file except in compliance with the License. You may obtain a copy of |
9 | * the License at http://www.apache.org/licenses/LICENSE-2.0 |
10 | * |
11 | * Unless required by applicable law or agreed to in writing, software |
12 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
14 | * License for the specific language governing permissions and limitations under |
15 | * the License. |
16 | */ |
17 | #include <aerospike/mod_lua_bytes.h> |
18 | #include <aerospike/as_val.h> |
19 | #include <aerospike/mod_lua_val.h> |
20 | #include <aerospike/mod_lua_iterator.h> |
21 | #include <aerospike/mod_lua_reg.h> |
22 | #include <citrusleaf/alloc.h> |
23 | #include <citrusleaf/cf_byte_order.h> |
24 | #include <stddef.h> |
25 | #include <string.h> |
26 | |
27 | #include "internal.h" |
28 | |
29 | /******************************************************************************* |
30 | * MACROS |
31 | ******************************************************************************/ |
32 | |
33 | #define OBJECT_NAME "bytes" |
34 | #define CLASS_NAME "Bytes" |
35 | |
36 | /******************************************************************************* |
37 | * BOX FUNCTIONS |
38 | ******************************************************************************/ |
39 | |
40 | as_bytes * mod_lua_tobytes(lua_State * l, int index) { |
41 | mod_lua_box * box = mod_lua_tobox(l, index, CLASS_NAME); |
42 | return (as_bytes *) mod_lua_box_value(box); |
43 | } |
44 | |
45 | as_bytes * mod_lua_pushbytes(lua_State * l, as_bytes * b) { |
46 | mod_lua_box * box = mod_lua_pushbox(l, MOD_LUA_SCOPE_LUA, b, CLASS_NAME); |
47 | return (as_bytes *) mod_lua_box_value(box); |
48 | } |
49 | |
50 | static as_bytes * mod_lua_checkbytes(lua_State * l, int index) { |
51 | mod_lua_box * box = mod_lua_checkbox(l, index, CLASS_NAME); |
52 | return (as_bytes *) mod_lua_box_value(box); |
53 | } |
54 | |
55 | static int mod_lua_bytes_gc(lua_State * l) { |
56 | mod_lua_freebox(l, 1, CLASS_NAME); |
57 | return 0; |
58 | } |
59 | |
60 | /******************************************************************************* |
61 | * FUNCTIONS |
62 | ******************************************************************************/ |
63 | |
64 | static int mod_lua_bytes_size(lua_State * l) |
65 | { |
66 | // we expect 1 arg |
67 | if ( lua_gettop(l) != 1 ) { |
68 | lua_pushinteger(l, 0); |
69 | return 1; |
70 | } |
71 | |
72 | as_bytes * b = mod_lua_checkbytes(l, 1); |
73 | |
74 | // check preconditions: |
75 | // - b != NULL |
76 | if ( !b ) { |
77 | lua_pushinteger(l, 0); |
78 | return 1; |
79 | } |
80 | |
81 | lua_pushinteger(l, as_bytes_size(b)); |
82 | return 1; |
83 | } |
84 | |
85 | /* |
86 | static int mod_lua_bytes_capacity(lua_State * l) |
87 | { |
88 | // we expect 1 arg |
89 | if ( lua_gettop(l) != 1 ) { |
90 | lua_pushinteger(l, 0); |
91 | return 1; |
92 | } |
93 | |
94 | as_bytes * b = mod_lua_checkbytes(l, 1); |
95 | |
96 | // check preconditions: |
97 | // - b != NULL |
98 | if ( !b ) { |
99 | lua_pushinteger(l, 0); |
100 | return 1; |
101 | } |
102 | |
103 | lua_pushinteger(l, as_bytes_capacity(b)); |
104 | return 1; |
105 | } |
106 | */ |
107 | |
108 | static int mod_lua_bytes_ensure(lua_State *l) |
109 | { |
110 | // we expect 2 args |
111 | if ( lua_gettop(l) != 2) { |
112 | lua_pushboolean(l, false); |
113 | return 1; |
114 | } |
115 | |
116 | as_bytes * b = mod_lua_checkbytes(l, 1); |
117 | lua_Integer c = luaL_optinteger(l, 2, 0); |
118 | int r = luaL_optint(l, 3, 0); |
119 | |
120 | // check preconditions: |
121 | // - b != NULL |
122 | // - 0 <= c <= INT32_MAX |
123 | if ( !b || |
124 | c < 0 || c > UINT32_MAX || |
125 | r < 0 || r > 1) { |
126 | lua_pushboolean(l, false); |
127 | return 1; |
128 | } |
129 | |
130 | bool res = as_bytes_ensure(b, (uint32_t) c, r==1); |
131 | lua_pushboolean(l, res); |
132 | return 1; |
133 | } |
134 | |
135 | /* |
136 | static int mod_lua_bytes_truncate(lua_State *l) |
137 | { |
138 | // we expect 2 args |
139 | if ( lua_gettop(l) != 2) { |
140 | lua_pushboolean(l, false); |
141 | return 1; |
142 | } |
143 | |
144 | as_bytes * b = mod_lua_checkbytes(l, 1); |
145 | lua_Integer n = luaL_optinteger(l, 2, 0); |
146 | |
147 | // check preconditions: |
148 | // - b != NULL |
149 | // - 0 <= v <= INT32_MAX |
150 | if ( !b || |
151 | n < 0 || n > UINT32_MAX ) { |
152 | lua_pushboolean(l, false); |
153 | return 1; |
154 | } |
155 | |
156 | bool res = as_bytes_truncate(b, (uint32_t) n); |
157 | lua_pushboolean(l, res); |
158 | return 1; |
159 | } |
160 | */ |
161 | |
162 | static int mod_lua_bytes_new(lua_State * l) |
163 | { |
164 | int argc = lua_gettop(l); |
165 | |
166 | as_bytes * bytes = NULL; |
167 | |
168 | if ( argc == 1 ) { |
169 | // no arguments |
170 | bytes = as_bytes_new(0); |
171 | } |
172 | else if ( argc == 2 ) { |
173 | // single integer argument for capacity |
174 | lua_Integer n = luaL_optinteger(l, 2, 0); |
175 | bytes = as_bytes_new((uint32_t) n); |
176 | } |
177 | |
178 | if ( !bytes ) { |
179 | return 0; |
180 | } |
181 | |
182 | mod_lua_pushbytes(l, bytes); |
183 | return 1; |
184 | } |
185 | |
186 | static int mod_lua_bytes_tostring(lua_State * l) |
187 | { |
188 | // we expect 1 arg |
189 | if ( lua_gettop(l) != 1 ) { |
190 | lua_pushinteger(l, 0); |
191 | return 1; |
192 | } |
193 | |
194 | mod_lua_box * box = mod_lua_checkbox(l, 1, CLASS_NAME); |
195 | as_val * val = mod_lua_box_value(box); |
196 | char * str = NULL; |
197 | |
198 | if ( val ) { |
199 | str = as_val_tostring(val); |
200 | } |
201 | |
202 | if ( str ) { |
203 | lua_pushstring(l, str); |
204 | cf_free(str); |
205 | } |
206 | else { |
207 | lua_pushstring(l, "Bytes()" ); |
208 | } |
209 | |
210 | return 1; |
211 | } |
212 | |
213 | /** |
214 | * Get the type of bytes: |
215 | * |
216 | * ----------{.c} |
217 | * uint bytes.type(bytes b) |
218 | * ---------- |
219 | * |
220 | */ |
221 | static int mod_lua_bytes_get_type(lua_State * l) |
222 | { |
223 | // we expect atleast 1 arg |
224 | if ( lua_gettop(l) < 1 ) { |
225 | return 0; |
226 | } |
227 | |
228 | as_bytes * b = mod_lua_checkbytes(l, 1); |
229 | |
230 | // check preconditions: |
231 | // - b != NULL |
232 | if ( !b ) { |
233 | return 0; |
234 | } |
235 | |
236 | lua_pushinteger(l, as_bytes_get_type(b)); |
237 | return 1; |
238 | } |
239 | |
240 | /** |
241 | * Set the type of bytes: |
242 | * |
243 | * ----------{.c} |
244 | * bool bytes.type(bytes b, uint 5) |
245 | * ---------- |
246 | */ |
247 | static int mod_lua_bytes_set_type(lua_State * l) |
248 | { |
249 | // we expect 2 args |
250 | if ( lua_gettop(l) != 2 ) { |
251 | lua_pushboolean(l, false); |
252 | return 1; |
253 | } |
254 | |
255 | as_bytes * b = mod_lua_checkbytes(l, 1); |
256 | lua_Integer t = luaL_optinteger(l, 2, 0); |
257 | |
258 | // check preconditions: |
259 | // - b != NULL |
260 | if ( !b || !t ) { |
261 | lua_pushboolean(l, false); |
262 | return 1; |
263 | } |
264 | |
265 | as_bytes_set_type(b, (as_bytes_type)t); |
266 | lua_pushboolean(l, true); |
267 | return 1; |
268 | } |
269 | |
270 | |
271 | /****************************************************************************** |
272 | * APPEND FUNCTIONS |
273 | *****************************************************************************/ |
274 | |
275 | /** |
276 | * Append a byte value. |
277 | * |
278 | * ----------{.c} |
279 | * bool bytes.append_byte(bytes b, uint8 v) |
280 | * ---------- |
281 | * |
282 | * @param b The bytes to set a value in. |
283 | * @param v The uint8_t value append to b. |
284 | * |
285 | * @return On success, true. Otherwise, false on error. |
286 | */ |
287 | static int mod_lua_bytes_append_byte(lua_State * l) |
288 | { |
289 | // we expect 2 args |
290 | if ( lua_gettop(l) != 2 ) { |
291 | lua_pushboolean(l, false); |
292 | return 1; |
293 | } |
294 | |
295 | as_bytes * b = mod_lua_checkbytes(l, 1); |
296 | lua_Integer v = luaL_optinteger(l, 2, 0); |
297 | |
298 | // check preconditions: |
299 | // - b != NULL |
300 | // - UINT8_MIN <= v <= UINT8_MAX |
301 | if ( !b || |
302 | v < 0 || v > UINT8_MAX ) { |
303 | lua_pushboolean(l, false); |
304 | return 1; |
305 | } |
306 | |
307 | bool res = false; |
308 | uint32_t pos = b->size; |
309 | uint32_t size = 1; |
310 | |
311 | // ensure we have capacity, if not, then resize |
312 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
313 | // write the bytes |
314 | res = as_bytes_append_byte(b, (uint8_t)v); |
315 | } |
316 | |
317 | lua_pushboolean(l, res); |
318 | return 1; |
319 | } |
320 | |
321 | /** |
322 | * Append a big endian int16 value. |
323 | * |
324 | * ----------{.c} |
325 | * bool bytes.append_int16_be(bytes b, int16 v) |
326 | * ---------- |
327 | * |
328 | * @param b The bytes to set a value in. |
329 | * @param v The int16_t value to append to b. |
330 | * |
331 | * @return On success, true. Otherwise, false on error. |
332 | */ |
333 | static int mod_lua_bytes_append_int16_be(lua_State * l) |
334 | { |
335 | // we expect 2 args |
336 | if ( lua_gettop(l) != 2 ) { |
337 | lua_pushboolean(l, false); |
338 | return 1; |
339 | } |
340 | |
341 | as_bytes * b = mod_lua_checkbytes(l, 1); |
342 | lua_Integer v = luaL_optinteger(l, 2, 0); |
343 | |
344 | // check preconditions: |
345 | // - b != NULL |
346 | // - INT32_MIN <= v <= INT32_MAX |
347 | if ( !b || |
348 | v < INT16_MIN || v > INT16_MAX ) { |
349 | lua_pushboolean(l, false); |
350 | return 1; |
351 | } |
352 | |
353 | bool res = false; |
354 | uint32_t pos = b->size; |
355 | uint32_t size = 2; |
356 | |
357 | // ensure we have capacity, if not, then resize |
358 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
359 | // write the bytes |
360 | int16_t val = cf_swap_to_be16((int16_t) v); |
361 | res = as_bytes_append_int16(b, val); |
362 | } |
363 | |
364 | lua_pushboolean(l, res); |
365 | return 1; |
366 | } |
367 | |
368 | /** |
369 | * Append a little endian int16 value. |
370 | * |
371 | * ----------{.c} |
372 | * bool bytes.append_int16_le(bytes b, int16 v) |
373 | * ---------- |
374 | * |
375 | * @param b The bytes to set a value in. |
376 | * @param v The int16_t value to append to b. |
377 | * |
378 | * @return On success, true. Otherwise, false on error. |
379 | */ |
380 | static int mod_lua_bytes_append_int16_le(lua_State * l) |
381 | { |
382 | // we expect 2 args |
383 | if ( lua_gettop(l) != 2 ) { |
384 | lua_pushboolean(l, false); |
385 | return 1; |
386 | } |
387 | |
388 | as_bytes * b = mod_lua_checkbytes(l, 1); |
389 | lua_Integer v = luaL_optinteger(l, 2, 0); |
390 | |
391 | // check preconditions: |
392 | // - b != NULL |
393 | // - INT32_MIN <= v <= INT32_MAX |
394 | if ( !b || |
395 | v < INT16_MIN || v > INT16_MAX ) { |
396 | lua_pushboolean(l, false); |
397 | return 1; |
398 | } |
399 | |
400 | bool res = false; |
401 | uint32_t pos = b->size; |
402 | uint32_t size = 2; |
403 | |
404 | // ensure we have capacity, if not, then resize |
405 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
406 | // write the bytes |
407 | int16_t val = cf_swap_to_le16((int16_t) v); |
408 | res = as_bytes_append_int16(b, val); |
409 | } |
410 | |
411 | lua_pushboolean(l, res); |
412 | return 1; |
413 | } |
414 | |
415 | /** |
416 | * Append a big endian int32 value. |
417 | * |
418 | * ----------{.c} |
419 | * bool bytes.append_int32_be(b, v) |
420 | * ---------- |
421 | * |
422 | * @param b The bytes to set a value in. |
423 | * @param v The int32_t value to append to b. |
424 | * |
425 | * @return On success, true. Otherwise, false on error. |
426 | */ |
427 | static int mod_lua_bytes_append_int32_be(lua_State * l) |
428 | { |
429 | // we expect 2 args |
430 | if ( lua_gettop(l) != 2 ) { |
431 | lua_pushboolean(l, false); |
432 | return 1; |
433 | } |
434 | |
435 | as_bytes * b = mod_lua_checkbytes(l, 1); |
436 | lua_Integer v = luaL_optinteger(l, 2, 0); |
437 | |
438 | // check preconditions: |
439 | // - b != NULL |
440 | // - INT32_MIN <= v <= INT32_MAX |
441 | if ( !b || |
442 | v < INT32_MIN || v > INT32_MAX ) { |
443 | lua_pushboolean(l, false); |
444 | return 1; |
445 | } |
446 | |
447 | bool res = false; |
448 | uint32_t pos = b->size; |
449 | uint32_t size = 4; |
450 | |
451 | // ensure we have capacity, if not, then resize |
452 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
453 | // write the bytes |
454 | int32_t val = cf_swap_to_be32((int32_t) v); |
455 | res = as_bytes_append_int32(b, val); |
456 | } |
457 | |
458 | lua_pushboolean(l, res); |
459 | return 1; |
460 | } |
461 | |
462 | /** |
463 | * Append a little endian int32 value. |
464 | * |
465 | * ----------{.c} |
466 | * bool bytes.append_int32_le(b, v) |
467 | * ---------- |
468 | * |
469 | * @param b The bytes to set a value in. |
470 | * @param v The int32_t value to append to b. |
471 | * |
472 | * @return On success, true. Otherwise, false on error. |
473 | */ |
474 | static int mod_lua_bytes_append_int32_le(lua_State * l) |
475 | { |
476 | // we expect 2 args |
477 | if ( lua_gettop(l) != 2 ) { |
478 | lua_pushboolean(l, false); |
479 | return 1; |
480 | } |
481 | |
482 | as_bytes * b = mod_lua_checkbytes(l, 1); |
483 | lua_Integer v = luaL_optinteger(l, 2, 0); |
484 | |
485 | // check preconditions: |
486 | // - b != NULL |
487 | // - INT32_MIN <= v <= INT32_MAX |
488 | if ( !b || |
489 | v < INT32_MIN || v > INT32_MAX ) { |
490 | lua_pushboolean(l, false); |
491 | return 1; |
492 | } |
493 | |
494 | bool res = false; |
495 | uint32_t pos = b->size; |
496 | uint32_t size = 4; |
497 | |
498 | // ensure we have capacity, if not, then resize |
499 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
500 | // write the bytes |
501 | int32_t val = cf_swap_to_le32((int32_t) v); |
502 | res = as_bytes_append_int32(b, val); |
503 | } |
504 | |
505 | lua_pushboolean(l, res); |
506 | return 1; |
507 | } |
508 | |
509 | /** |
510 | * Append a big endian int64 value. |
511 | * |
512 | * ----------{.c} |
513 | * bool bytes.append_int64_be(b, v) |
514 | * ---------- |
515 | * |
516 | * @param b The bytes to set a value in. |
517 | * @param v The int64_t value to append to b. |
518 | * |
519 | * @return On success, true. Otherwise, false on error. |
520 | */ |
521 | static int mod_lua_bytes_append_int64_be(lua_State * l) |
522 | { |
523 | // we expect 2 args |
524 | if ( lua_gettop(l) != 2 ) { |
525 | lua_pushboolean(l, false); |
526 | return 1; |
527 | } |
528 | |
529 | as_bytes * b = mod_lua_checkbytes(l, 1); |
530 | lua_Integer v = luaL_optinteger(l, 2, 0); |
531 | |
532 | // check preconditions: |
533 | // - b != NULL |
534 | if ( !b ) { |
535 | lua_pushboolean(l, false); |
536 | return 1; |
537 | } |
538 | |
539 | bool res = false; |
540 | uint32_t pos = b->size; |
541 | uint32_t size = 8; |
542 | |
543 | // ensure we have capacity, if not, then resize |
544 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
545 | // write the bytes |
546 | int64_t val = cf_swap_to_be64((int64_t) v); |
547 | res = as_bytes_append_int64(b, val); |
548 | } |
549 | |
550 | lua_pushboolean(l, res); |
551 | return 1; |
552 | } |
553 | |
554 | /** |
555 | * Append a little endian int64 value. |
556 | * |
557 | * ----------{.c} |
558 | * bool bytes.append_int64_le(b, v) |
559 | * ---------- |
560 | * |
561 | * @param b The bytes to set a value in. |
562 | * @param v The int64_t value to append to b. |
563 | * |
564 | * @return On success, true. Otherwise, false on error. |
565 | */ |
566 | static int mod_lua_bytes_append_int64_le(lua_State * l) |
567 | { |
568 | // we expect 2 args |
569 | if ( lua_gettop(l) != 2 ) { |
570 | lua_pushboolean(l, false); |
571 | return 1; |
572 | } |
573 | |
574 | as_bytes * b = mod_lua_checkbytes(l, 1); |
575 | lua_Integer v = luaL_optinteger(l, 2, 0); |
576 | |
577 | // check preconditions: |
578 | // - b != NULL |
579 | if ( !b ) { |
580 | lua_pushboolean(l, false); |
581 | return 1; |
582 | } |
583 | |
584 | bool res = false; |
585 | uint32_t pos = b->size; |
586 | uint32_t size = 8; |
587 | |
588 | // ensure we have capacity, if not, then resize |
589 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
590 | // write the bytes |
591 | int64_t val = cf_swap_to_le64((int64_t) v); |
592 | res = as_bytes_append_int64(b, val); |
593 | } |
594 | |
595 | lua_pushboolean(l, res); |
596 | return 1; |
597 | } |
598 | |
599 | /** |
600 | * Append an integer in variable 7-bit format at specified index. |
601 | * The high bit indicates if more bytes are used. |
602 | * |
603 | * ----------{.c} |
604 | * bool bytes.append_var_int(b, v) |
605 | * ---------- |
606 | * |
607 | * @param b The bytes to set a value in. |
608 | * @param v The integer value to append to b. |
609 | * |
610 | * @return number of bytes used to store integer |
611 | */ |
612 | static int mod_lua_bytes_append_var_int(lua_State * l) |
613 | { |
614 | // we expect 2 args |
615 | if ( lua_gettop(l) != 2 ) { |
616 | lua_pushinteger(l, 0); |
617 | return 1; |
618 | } |
619 | |
620 | as_bytes * b = mod_lua_checkbytes(l, 1); |
621 | lua_Integer v = luaL_optinteger(l, 2, 0); |
622 | |
623 | // check preconditions: |
624 | // - b != NULL |
625 | // - INT32_MIN <= v <= INT32_MAX |
626 | if ( !b || |
627 | v < INT32_MIN || v > INT32_MAX ) { |
628 | lua_pushinteger(l, 0); |
629 | return 1; |
630 | } |
631 | |
632 | uint32_t size = 0; |
633 | uint32_t pos = b->size; |
634 | |
635 | // ensure we have capacity, if not, then resize |
636 | if ( as_bytes_ensure(b, pos + 5, true) == true ) { |
637 | size = as_bytes_set_var_int(b, pos, (uint32_t)v); |
638 | } |
639 | |
640 | lua_pushinteger(l, size); |
641 | return 1; |
642 | } |
643 | |
644 | /** |
645 | * Append a NULL-terminated string value. |
646 | * |
647 | * ----------{.c} |
648 | * bool bytes.append_string(bytes b, string v) |
649 | * ---------- |
650 | * |
651 | * @param b The bytes to set a value in. |
652 | * @param v The NULL-terminated string value to append to b. |
653 | * |
654 | * @return On success, true. Otherwise, false on error. |
655 | */ |
656 | static int mod_lua_bytes_append_string(lua_State * l) |
657 | { |
658 | // we expect 2 args |
659 | if ( lua_gettop(l) != 2 ) { |
660 | lua_pushboolean(l, false); |
661 | return 1; |
662 | } |
663 | |
664 | as_bytes * b = mod_lua_checkbytes(l, 1); |
665 | size_t n = 0; |
666 | const char * v = luaL_optlstring(l, 2, NULL, &n); |
667 | |
668 | // check preconditions: |
669 | // - b != NULL |
670 | // - v != NULL |
671 | // - n != 0 |
672 | if ( !b || !v || !n ) { |
673 | lua_pushboolean(l, false); |
674 | return 1; |
675 | } |
676 | |
677 | bool res = false; |
678 | uint32_t pos = b->size; |
679 | uint32_t size = (uint32_t)n; |
680 | |
681 | // ensure we have capacity, if not, then resize |
682 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
683 | // write the bytes |
684 | res = as_bytes_append(b, (uint8_t *) v, size); |
685 | } |
686 | |
687 | lua_pushboolean(l, res); |
688 | return 1; |
689 | } |
690 | |
691 | /** |
692 | * Append a NULL-terminated string value. |
693 | * |
694 | * ----------{.c} |
695 | * bool bytes.append_string(bytes b, bytes v, uint32 n) |
696 | * ---------- |
697 | * |
698 | * @param b The bytes to set a value in. |
699 | * @param v The bytes value to append to b. |
700 | * @param n The number of bytes to append to b. |
701 | * |
702 | * @return On success, true. Otherwise, false on error. |
703 | */ |
704 | static int mod_lua_bytes_append_bytes(lua_State * l) |
705 | { |
706 | // we expect 3 args |
707 | if ( lua_gettop(l) != 3 ) { |
708 | lua_pushboolean(l, false); |
709 | return 1; |
710 | } |
711 | |
712 | as_bytes * b = mod_lua_checkbytes(l, 1); |
713 | as_bytes * v = mod_lua_checkbytes(l, 2); |
714 | lua_Integer n = luaL_optinteger(l, 3, 0); |
715 | |
716 | // check preconditions: |
717 | // - b != NULL |
718 | // - v != NULL |
719 | // - UINT32_MIN <= n <= UINT32_MAX |
720 | if ( !b || |
721 | !v || |
722 | n < 0 || n > UINT32_MAX ) { |
723 | lua_pushboolean(l, false); |
724 | return 1; |
725 | } |
726 | |
727 | bool res = false; |
728 | uint32_t pos = b->size; |
729 | uint32_t size = n > v->size ? v->size : (uint32_t)n; |
730 | |
731 | // ensure we have capacity, if not, then resize |
732 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
733 | // write the bytes |
734 | res = as_bytes_append(b, (uint8_t *) v->value, size); |
735 | } |
736 | |
737 | lua_pushboolean(l, res); |
738 | return 1; |
739 | } |
740 | |
741 | /****************************************************************************** |
742 | * SET FUNCTIONS |
743 | *****************************************************************************/ |
744 | |
745 | /** |
746 | * Set a byte value at specified index. |
747 | * |
748 | * ----------{.c} |
749 | * bool bytes.set_byte(bytes b, uint32 i, uint8 v) |
750 | * ---------- |
751 | * |
752 | * @param b The bytes to set a value in. |
753 | * @param i The index in b to set the value of. |
754 | * @param v The uint8_t value to set at i. |
755 | * |
756 | * @return On success, true. Otherwise, false on error. |
757 | */ |
758 | static int mod_lua_bytes_set_byte(lua_State * l) |
759 | { |
760 | // we expect 3 args |
761 | if ( lua_gettop(l) != 3 ) { |
762 | lua_pushboolean(l, false); |
763 | return 1; |
764 | } |
765 | |
766 | as_bytes * b = mod_lua_checkbytes(l, 1); |
767 | lua_Integer i = luaL_optinteger(l, 2, 0); |
768 | lua_Integer v = luaL_optinteger(l, 3, 0); |
769 | |
770 | // check preconditions: |
771 | // - b != NULL |
772 | // - 1 <= i <= UINT32_MAX |
773 | // - 0 <= v <= UINT8_MAX |
774 | if ( !b || |
775 | i < 1 || i > UINT32_MAX || |
776 | v < 0 || v > UINT8_MAX ) { |
777 | lua_pushboolean(l, false); |
778 | return 1; |
779 | } |
780 | |
781 | bool res = false; |
782 | uint32_t pos = (uint32_t)(i - 1); |
783 | uint32_t size = 1; |
784 | |
785 | // ensure we have capacity, if not, then resize |
786 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
787 | // write the bytes |
788 | res = as_bytes_set_byte(b, pos, (uint8_t)v); |
789 | } |
790 | |
791 | lua_pushboolean(l, res); |
792 | return 1; |
793 | } |
794 | |
795 | /** |
796 | * Set a big endian int16 value at specified index. |
797 | * |
798 | * ----------{.c} |
799 | * bool bytes.set_int16_be(bytes b, uint32 i, int16 v) |
800 | * ---------- |
801 | * |
802 | * @param b The bytes to set a value in. |
803 | * @param i The index in b to set the value of. |
804 | * @param v The int16_t value to set at i. |
805 | * |
806 | * @return On success, true. Otherwise, false on error. |
807 | */ |
808 | static int mod_lua_bytes_set_int16_be(lua_State * l) |
809 | { |
810 | // we expect 3 args |
811 | if ( lua_gettop(l) != 3 ) { |
812 | lua_pushboolean(l, false); |
813 | return 1; |
814 | } |
815 | |
816 | as_bytes * b = mod_lua_checkbytes(l, 1); |
817 | lua_Integer i = luaL_optinteger(l, 2, 0); |
818 | lua_Integer v = luaL_optinteger(l, 3, 0); |
819 | |
820 | // check preconditions: |
821 | // - b != NULL |
822 | // - 1 <= i <= UINT32_MAX |
823 | // - INT16_MIN <= v <= INT16_MAX |
824 | if ( !b || |
825 | i < 1 || i > UINT32_MAX || |
826 | v < INT16_MIN || v > INT16_MAX ) { |
827 | lua_pushboolean(l, false); |
828 | return 1; |
829 | } |
830 | |
831 | bool res = false; |
832 | uint32_t pos = (uint32_t)(i - 1); |
833 | uint32_t size = 2; |
834 | |
835 | // ensure we have capacity, if not, then resize |
836 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
837 | // write the bytes |
838 | int16_t val = cf_swap_to_be16((int16_t) v); |
839 | res = as_bytes_set_int16(b, pos, val); |
840 | } |
841 | |
842 | lua_pushboolean(l, res); |
843 | return 1; |
844 | } |
845 | |
846 | /** |
847 | * Set a little endian int16 value at specified index. |
848 | * |
849 | * ----------{.c} |
850 | * bool bytes.set_int16_le(bytes b, uint32 i, int16 v) |
851 | * ---------- |
852 | * |
853 | * @param b The bytes to set a value in. |
854 | * @param i The index in b to set the value of. |
855 | * @param v The int16_t value to set at i. |
856 | * |
857 | * @return On success, true. Otherwise, false on error. |
858 | */ |
859 | static int mod_lua_bytes_set_int16_le(lua_State * l) |
860 | { |
861 | // we expect 3 args |
862 | if ( lua_gettop(l) != 3 ) { |
863 | lua_pushboolean(l, false); |
864 | return 1; |
865 | } |
866 | |
867 | as_bytes * b = mod_lua_checkbytes(l, 1); |
868 | lua_Integer i = luaL_optinteger(l, 2, 0); |
869 | lua_Integer v = luaL_optinteger(l, 3, 0); |
870 | |
871 | // check preconditions: |
872 | // - b != NULL |
873 | // - 1 <= i <= UINT32_MAX |
874 | // - INT16_MIN <= v <= INT16_MAX |
875 | if ( !b || |
876 | i < 1 || i > UINT32_MAX || |
877 | v < INT16_MIN || v > INT16_MAX ) { |
878 | lua_pushboolean(l, false); |
879 | return 1; |
880 | } |
881 | |
882 | bool res = false; |
883 | uint32_t pos = (uint32_t)(i - 1); |
884 | uint32_t size = 2; |
885 | |
886 | // ensure we have capacity, if not, then resize |
887 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
888 | // write the bytes |
889 | int16_t val = cf_swap_to_le16((int16_t) v); |
890 | res = as_bytes_set_int16(b, pos, val); |
891 | } |
892 | |
893 | lua_pushboolean(l, res); |
894 | return 1; |
895 | } |
896 | |
897 | /** |
898 | * Set a big endian int32 value at specified index. |
899 | * |
900 | * ----------{.c} |
901 | * bool bytes.set_int32_be(bytes b, uint32 i, int32 v) |
902 | * ---------- |
903 | * |
904 | * @param b The bytes to set a value in. |
905 | * @param i The index in b to set the value of. |
906 | * @param v The int32_t value to set at i. |
907 | * |
908 | * @return On success, true. Otherwise, false on error. |
909 | */ |
910 | static int mod_lua_bytes_set_int32_be(lua_State * l) |
911 | { |
912 | // we expect 3 args |
913 | if ( lua_gettop(l) != 3 ) { |
914 | lua_pushboolean(l, false); |
915 | return 1; |
916 | } |
917 | |
918 | as_bytes * b = mod_lua_checkbytes(l, 1); |
919 | lua_Integer i = luaL_optinteger(l, 2, 0); |
920 | lua_Integer v = luaL_optinteger(l, 3, 0); |
921 | |
922 | // check preconditions: |
923 | // - b != NULL |
924 | // - 1 <= i <= UINT32_MAX |
925 | // - INT32_MIN <= v <= INT32_MAX |
926 | if ( !b || |
927 | i < 1 || i > UINT32_MAX || |
928 | v < INT32_MIN || v > INT32_MAX ) { |
929 | lua_pushboolean(l, false); |
930 | return 1; |
931 | } |
932 | |
933 | bool res = false; |
934 | uint32_t pos = (uint32_t)(i - 1); |
935 | uint32_t size = 4; |
936 | |
937 | // ensure we have capacity, if not, then resize |
938 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
939 | // write the bytes |
940 | int32_t val = cf_swap_to_be32((int32_t) v); |
941 | res = as_bytes_set_int32(b, pos, val); |
942 | } |
943 | |
944 | lua_pushboolean(l, res); |
945 | return 1; |
946 | } |
947 | |
948 | /** |
949 | * Set a little endian int32 value at specified index. |
950 | * |
951 | * ----------{.c} |
952 | * bool bytes.set_int32_le(bytes b, uint32 i, int32 v) |
953 | * ---------- |
954 | * |
955 | * @param b The bytes to set a value in. |
956 | * @param i The index in b to set the value of. |
957 | * @param v The int32_t value to set at i. |
958 | * |
959 | * @return On success, true. Otherwise, false on error. |
960 | */ |
961 | static int mod_lua_bytes_set_int32_le(lua_State * l) |
962 | { |
963 | // we expect 3 args |
964 | if ( lua_gettop(l) != 3 ) { |
965 | lua_pushboolean(l, false); |
966 | return 1; |
967 | } |
968 | |
969 | as_bytes * b = mod_lua_checkbytes(l, 1); |
970 | lua_Integer i = luaL_optinteger(l, 2, 0); |
971 | lua_Integer v = luaL_optinteger(l, 3, 0); |
972 | |
973 | // check preconditions: |
974 | // - b != NULL |
975 | // - 1 <= i <= UINT32_MAX |
976 | // - INT32_MIN <= v <= INT32_MAX |
977 | if ( !b || |
978 | i < 1 || i > UINT32_MAX || |
979 | v < INT32_MIN || v > INT32_MAX ) { |
980 | lua_pushboolean(l, false); |
981 | return 1; |
982 | } |
983 | |
984 | bool res = false; |
985 | uint32_t pos = (uint32_t)(i - 1); |
986 | uint32_t size = 4; |
987 | |
988 | // ensure we have capacity, if not, then resize |
989 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
990 | // write the bytes |
991 | int32_t val = cf_swap_to_le32((int32_t) v); |
992 | res = as_bytes_set_int32(b, pos, val); |
993 | } |
994 | |
995 | lua_pushboolean(l, res); |
996 | return 1; |
997 | } |
998 | |
999 | /** |
1000 | * Set a big endian int64_t value at specified index. |
1001 | * |
1002 | * ----------{.c} |
1003 | * bool bytes.set_int64_be(bytes b, uint32 i, int64 v) |
1004 | * ---------- |
1005 | * |
1006 | * @param b The bytes to set a value in. |
1007 | * @param i The index in b to set the value of. |
1008 | * @param v The int64_t value to set at i. |
1009 | * |
1010 | * @return On success, true. Otherwise, false on error. |
1011 | */ |
1012 | static int mod_lua_bytes_set_int64_be(lua_State * l) |
1013 | { |
1014 | // we expect 3 args |
1015 | if ( lua_gettop(l) != 3 ) { |
1016 | lua_pushboolean(l, false); |
1017 | return 1; |
1018 | } |
1019 | |
1020 | as_bytes * b = mod_lua_checkbytes(l, 1); |
1021 | lua_Integer i = luaL_optinteger(l, 2, 0); |
1022 | lua_Integer v = luaL_optinteger(l, 3, 0); |
1023 | |
1024 | // check preconditions: |
1025 | // - b != NULL |
1026 | // - 1 <= i <= UINT32_MAX |
1027 | if ( !b || |
1028 | i < 1 || i > UINT32_MAX ) { |
1029 | lua_pushboolean(l, false); |
1030 | return 1; |
1031 | } |
1032 | |
1033 | bool res = false; |
1034 | uint32_t pos = (uint32_t)(i - 1); |
1035 | uint32_t size = 8; |
1036 | |
1037 | // ensure we have capacity, if not, then resize |
1038 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
1039 | // write the bytes |
1040 | int64_t val = cf_swap_to_be64((int64_t) v); |
1041 | res = as_bytes_set_int64(b, pos, val); |
1042 | } |
1043 | |
1044 | lua_pushboolean(l, res); |
1045 | return 1; |
1046 | } |
1047 | |
1048 | /** |
1049 | * Set a little endian int64_t value at specified index. |
1050 | * |
1051 | * ----------{.c} |
1052 | * bool bytes.set_int64_le(bytes b, uint32 i, int64 v) |
1053 | * ---------- |
1054 | * |
1055 | * @param b The bytes to set a value in. |
1056 | * @param i The index in b to set the value of. |
1057 | * @param v The int64_t value to set at i. |
1058 | * |
1059 | * @return On success, true. Otherwise, false on error. |
1060 | */ |
1061 | static int mod_lua_bytes_set_int64_le(lua_State * l) |
1062 | { |
1063 | // we expect 3 args |
1064 | if ( lua_gettop(l) != 3 ) { |
1065 | lua_pushboolean(l, false); |
1066 | return 1; |
1067 | } |
1068 | |
1069 | as_bytes * b = mod_lua_checkbytes(l, 1); |
1070 | lua_Integer i = luaL_optinteger(l, 2, 0); |
1071 | lua_Integer v = luaL_optinteger(l, 3, 0); |
1072 | |
1073 | // check preconditions: |
1074 | // - b != NULL |
1075 | // - 1 <= i <= UINT32_MAX |
1076 | if ( !b || |
1077 | i < 1 || i > UINT32_MAX ) { |
1078 | lua_pushboolean(l, false); |
1079 | return 1; |
1080 | } |
1081 | |
1082 | bool res = false; |
1083 | uint32_t pos = (uint32_t)(i - 1); |
1084 | uint32_t size = 8; |
1085 | |
1086 | // ensure we have capacity, if not, then resize |
1087 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
1088 | // write the bytes |
1089 | int64_t val = cf_swap_to_le64((int64_t) v); |
1090 | res = as_bytes_set_int64(b, pos, val); |
1091 | } |
1092 | |
1093 | lua_pushboolean(l, res); |
1094 | return 1; |
1095 | } |
1096 | |
1097 | /** |
1098 | * Encode an integer in variable 7-bit format at specified index. |
1099 | * The high bit indicates if more bytes are used. |
1100 | * |
1101 | * ----------{.c} |
1102 | * bool bytes.set_var_int(bytes b, uint32 i, int32 v) |
1103 | * ---------- |
1104 | * |
1105 | * @param b The bytes to set a value in. |
1106 | * @param i The index in b to set the value of. |
1107 | * @param v The integer value to set at i. |
1108 | * |
1109 | * @return number of bytes used to store integer |
1110 | */ |
1111 | static int mod_lua_bytes_set_var_int(lua_State * l) |
1112 | { |
1113 | // we expect 3 args |
1114 | if ( lua_gettop(l) != 3 ) { |
1115 | lua_pushinteger(l, 0); |
1116 | return 1; |
1117 | } |
1118 | |
1119 | as_bytes * b = mod_lua_checkbytes(l, 1); |
1120 | lua_Integer i = luaL_optinteger(l, 2, 0); |
1121 | lua_Integer v = luaL_optinteger(l, 3, 0); |
1122 | |
1123 | // check preconditions: |
1124 | // - b != NULL |
1125 | // - 1 <= i <= UINT32_MAX |
1126 | // - INT32_MIN <= v <= INT32_MAX |
1127 | if ( !b || |
1128 | i < 1 || i > UINT32_MAX || |
1129 | v < INT32_MIN || v > INT32_MAX ) { |
1130 | lua_pushinteger(l, 0); |
1131 | return 1; |
1132 | } |
1133 | |
1134 | uint32_t size = 0; |
1135 | uint32_t pos = (uint32_t)(i - 1); |
1136 | |
1137 | // ensure we have capacity, if not, then resize |
1138 | if ( as_bytes_ensure(b, pos + 5, true) == true ) { |
1139 | size = as_bytes_set_var_int(b, pos, (uint32_t)v); |
1140 | } |
1141 | |
1142 | lua_pushinteger(l, size); |
1143 | return 1; |
1144 | } |
1145 | |
1146 | /** |
1147 | * Set an NULL-terminated string value at specified index. |
1148 | * |
1149 | * ----------{.c} |
1150 | * bool bytes.set_string(bytes b, uint32 i, string v) |
1151 | * ---------- |
1152 | * |
1153 | * @param b The bytes to set a value in. |
1154 | * @param i The index in b to set the value of. |
1155 | * @param v The NULL-terminated string value to set at i. |
1156 | * |
1157 | * @return On success, true. Otherwise, false on error. |
1158 | */ |
1159 | static int mod_lua_bytes_set_string(lua_State * l) |
1160 | { |
1161 | // we expect 3 args |
1162 | if ( lua_gettop(l) != 3 ) { |
1163 | lua_pushboolean(l, false); |
1164 | return 1; |
1165 | } |
1166 | |
1167 | as_bytes * b = mod_lua_checkbytes(l, 1); |
1168 | lua_Integer i = luaL_optinteger(l, 2, 0); |
1169 | size_t n = 0; |
1170 | const char * v = luaL_optlstring(l, 3, NULL, &n); |
1171 | |
1172 | // check preconditions: |
1173 | // - b != NULL |
1174 | // - 1 <= i <= UINT32_MAX |
1175 | // - v != NULL |
1176 | if ( !b || |
1177 | i < 1 || i > UINT32_MAX || |
1178 | !v ) { |
1179 | lua_pushboolean(l, false); |
1180 | return 1; |
1181 | } |
1182 | |
1183 | bool res = false; |
1184 | uint32_t pos = (uint32_t)(i - 1); |
1185 | uint32_t size = (uint32_t)n; |
1186 | |
1187 | // ensure we have capacity, if not, then resize |
1188 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
1189 | // write the bytes |
1190 | res = as_bytes_set(b, pos, (uint8_t *) v, size); |
1191 | } |
1192 | |
1193 | lua_pushboolean(l, res); |
1194 | return 1; |
1195 | } |
1196 | |
1197 | /** |
1198 | * Copy `n` data from bytes `v` to bytes `b` value at specified index. |
1199 | * |
1200 | * ----------{.c} |
1201 | * bool bytes.set_bytes(bytes b, uint32 i, bytes v, uint32 n) |
1202 | * ---------- |
1203 | * |
1204 | * @param b The bytes to set a value in. |
1205 | * @param i The index in b to set the value of. |
1206 | * @param v The NULL-terminated string value to set at i. |
1207 | * @param n The number of bytes to copy from v in to b. |
1208 | * |
1209 | * @return On success, true. Otherwise, false on error. |
1210 | */ |
1211 | static int mod_lua_bytes_set_bytes(lua_State * l) |
1212 | { |
1213 | // we expect 3 args |
1214 | if ( lua_gettop(l) != 4 ) { |
1215 | lua_pushboolean(l, false); |
1216 | return 1; |
1217 | } |
1218 | |
1219 | as_bytes * b = mod_lua_checkbytes(l, 1); |
1220 | lua_Integer i = luaL_optinteger(l, 2, 0); |
1221 | as_bytes * v = mod_lua_checkbytes(l, 3); |
1222 | lua_Integer n = luaL_optinteger(l, 4, 0); |
1223 | |
1224 | // check preconditions: |
1225 | // - b != NULL |
1226 | // - 1 <= i <= UINT32_MAX |
1227 | // - v != NULL |
1228 | // - 0 <= n <= UINT32_MAX |
1229 | if ( !b || |
1230 | i < 1 || i > UINT32_MAX || |
1231 | !v || |
1232 | n < 0 || n > UINT32_MAX ) { |
1233 | lua_pushboolean(l, false); |
1234 | return 1; |
1235 | } |
1236 | |
1237 | bool res = false; |
1238 | uint32_t pos = (uint32_t)(i - 1); |
1239 | uint32_t size = n > v->size ? v->size : (uint32_t)n; |
1240 | |
1241 | // ensure we have capacity, if not, then resize |
1242 | if ( as_bytes_ensure(b, pos + size, true) == true ) { |
1243 | // write the bytes |
1244 | res = as_bytes_set(b, pos, (uint8_t *) v->value, (uint32_t) n); |
1245 | } |
1246 | |
1247 | lua_pushboolean(l, res); |
1248 | return 1; |
1249 | } |
1250 | |
1251 | /****************************************************************************** |
1252 | * GET FUNCTIONS |
1253 | *****************************************************************************/ |
1254 | |
1255 | /** |
1256 | * Get an uint8_t value from the specified index. |
1257 | * |
1258 | * ----------{.c} |
1259 | * uint8 bytes.get_byte(bytes b, uint32 i) |
1260 | * ---------- |
1261 | * |
1262 | * @param b The bytes to get a value from. |
1263 | * @param i The index in b to get the value of. |
1264 | * |
1265 | * @return On success, the value. Otherwise nil on failure. |
1266 | */ |
1267 | static int mod_lua_bytes_get_byte(lua_State * l) |
1268 | { |
1269 | // we expect exactly 2 args |
1270 | if ( lua_gettop(l) != 2) { |
1271 | return 0; |
1272 | } |
1273 | |
1274 | as_bytes * b = mod_lua_checkbytes(l, 1); |
1275 | lua_Integer i = luaL_optinteger(l, 2, 0); |
1276 | |
1277 | // check preconditions: |
1278 | // - b != NULL |
1279 | // - 1 <= i <= UINT32_MAX |
1280 | if ( !b || |
1281 | i < 1 || i > UINT32_MAX ) { |
1282 | return 0; |
1283 | } |
1284 | |
1285 | uint32_t pos = (uint32_t)(i - 1); |
1286 | uint8_t val = 0; |
1287 | |
1288 | // get returns 0 on failure |
1289 | if ( as_bytes_get_byte(b, pos, &val) == 0 ) { |
1290 | return 0; |
1291 | } |
1292 | |
1293 | lua_pushinteger(l, val); |
1294 | return 1; |
1295 | } |
1296 | |
1297 | /** |
1298 | * Get a big endian int16 value from the specified index. |
1299 | * |
1300 | * ----------{.c} |
1301 | * int16 bytes.get_int16_be(bytes b, uint32 i) |
1302 | * ---------- |
1303 | * |
1304 | * @param b The bytes to get a value from. |
1305 | * @param i The index in b to get the value of. |
1306 | * |
1307 | * @return On success, the value. Otherwise nil on failure. |
1308 | */ |
1309 | static int mod_lua_bytes_get_int16_be(lua_State * l) |
1310 | { |
1311 | // we expect exactly 2 args |
1312 | if ( lua_gettop(l) != 2) { |
1313 | return 0; |
1314 | } |
1315 | |
1316 | as_bytes * b = mod_lua_checkbytes(l, 1); |
1317 | lua_Integer i = luaL_optinteger(l, 2, 0); |
1318 | |
1319 | // check preconditions: |
1320 | // - b != NULL |
1321 | // - 1 <= i <= UINT32_MAX |
1322 | if ( !b || |
1323 | i < 1 || i > UINT32_MAX ) { |
1324 | return 0; |
1325 | } |
1326 | |
1327 | uint32_t pos = (uint32_t)(i - 1); |
1328 | int16_t val = 0; |
1329 | |
1330 | // get returns 0 on failure |
1331 | if ( as_bytes_get_int16(b, pos, &val) == 0 ) { |
1332 | return 0; |
1333 | } |
1334 | |
1335 | int16_t res = cf_swap_from_be16(val); |
1336 | lua_pushinteger(l, res); |
1337 | return 1; |
1338 | } |
1339 | |
1340 | /** |
1341 | * Get a little endian int16 value from the specified index. |
1342 | * |
1343 | * ----------{.c} |
1344 | * int16 bytes.get_int16_le(bytes b, uint32 i) |
1345 | * ---------- |
1346 | * |
1347 | * @param b The bytes to get a value from. |
1348 | * @param i The index in b to get the value of. |
1349 | * |
1350 | * @return On success, the value. Otherwise nil on failure. |
1351 | */ |
1352 | static int mod_lua_bytes_get_int16_le(lua_State * l) |
1353 | { |
1354 | // we expect exactly 2 args |
1355 | if ( lua_gettop(l) != 2) { |
1356 | return 0; |
1357 | } |
1358 | |
1359 | as_bytes * b = mod_lua_checkbytes(l, 1); |
1360 | lua_Integer i = luaL_optinteger(l, 2, 0); |
1361 | |
1362 | // check preconditions: |
1363 | // - b != NULL |
1364 | // - 1 <= i <= UINT32_MAX |
1365 | if ( !b || |
1366 | i < 1 || i > UINT32_MAX ) { |
1367 | return 0; |
1368 | } |
1369 | |
1370 | uint32_t pos = (uint32_t)(i - 1); |
1371 | int16_t val = 0; |
1372 | |
1373 | // get returns 0 on failure |
1374 | if ( as_bytes_get_int16(b, pos, &val) == 0 ) { |
1375 | return 0; |
1376 | } |
1377 | |
1378 | int16_t res = cf_swap_from_le16(val); |
1379 | lua_pushinteger(l, res); |
1380 | return 1; |
1381 | } |
1382 | |
1383 | /** |
1384 | * Get a big endian int32 value from the specified index. |
1385 | * |
1386 | * ----------{.c} |
1387 | * int32 bytes.get_int32_be(bytes b, uint32 i) |
1388 | * ---------- |
1389 | * |
1390 | * @param b The bytes to get a value from. |
1391 | * @param i The index in b to get the value of. |
1392 | * |
1393 | * @return On success, the value. Otherwise nil on failure. |
1394 | */ |
1395 | static int mod_lua_bytes_get_int32_be(lua_State * l) |
1396 | { |
1397 | // we expect exactly 2 args |
1398 | if ( lua_gettop(l) != 2) { |
1399 | return 0; |
1400 | } |
1401 | |
1402 | as_bytes * b = mod_lua_checkbytes(l, 1); |
1403 | lua_Integer i = luaL_optinteger(l, 2, 0); |
1404 | |
1405 | // check preconditions: |
1406 | // - b != NULL |
1407 | // - 1 <= i <= UINT32_MAX |
1408 | if ( !b || |
1409 | i < 1 || i > UINT32_MAX ) { |
1410 | return 0; |
1411 | } |
1412 | |
1413 | uint32_t pos = (uint32_t)(i - 1); |
1414 | int32_t val = 0; |
1415 | |
1416 | // get returns 0 on failure |
1417 | if ( as_bytes_get_int32(b, pos, &val) == 0 ) { |
1418 | return 0; |
1419 | } |
1420 | |
1421 | int32_t res = cf_swap_from_be32(val); |
1422 | lua_pushinteger(l, res); |
1423 | return 1; |
1424 | } |
1425 | |
1426 | /** |
1427 | * Get a little endian int32 value from the specified index. |
1428 | * |
1429 | * ----------{.c} |
1430 | * int32 bytes.get_int32_le(bytes b, uint32 i) |
1431 | * ---------- |
1432 | * |
1433 | * @param b The bytes to get a value from. |
1434 | * @param i The index in b to get the value of. |
1435 | * |
1436 | * @return On success, the value. Otherwise nil on failure. |
1437 | */ |
1438 | static int mod_lua_bytes_get_int32_le(lua_State * l) |
1439 | { |
1440 | // we expect exactly 2 args |
1441 | if ( lua_gettop(l) != 2) { |
1442 | return 0; |
1443 | } |
1444 | |
1445 | as_bytes * b = mod_lua_checkbytes(l, 1); |
1446 | lua_Integer i = luaL_optinteger(l, 2, 0); |
1447 | |
1448 | // check preconditions: |
1449 | // - b != NULL |
1450 | // - 1 <= i <= UINT32_MAX |
1451 | if ( !b || |
1452 | i < 1 || i > UINT32_MAX ) { |
1453 | return 0; |
1454 | } |
1455 | |
1456 | uint32_t pos = (uint32_t)(i - 1); |
1457 | int32_t val = 0; |
1458 | |
1459 | // get returns 0 on failure |
1460 | if ( as_bytes_get_int32(b, pos, &val) == 0 ) { |
1461 | return 0; |
1462 | } |
1463 | |
1464 | int32_t res = cf_swap_from_le32(val); |
1465 | lua_pushinteger(l, res); |
1466 | return 1; |
1467 | } |
1468 | |
1469 | /** |
1470 | * Get a big endian int64 value from the specified index. |
1471 | * |
1472 | * ----------{.c} |
1473 | * int64 bytes.get_int64_be(bytes b, uint32 i) |
1474 | * ---------- |
1475 | * |
1476 | * @param b The bytes to get a value from. |
1477 | * @param i The index in b to get the value of. |
1478 | * |
1479 | * @return On success, the value. Otherwise nil on failure. |
1480 | */ |
1481 | static int mod_lua_bytes_get_int64_be(lua_State * l) |
1482 | { |
1483 | // we expect exactly 2 args |
1484 | if ( lua_gettop(l) != 2) { |
1485 | return 0; |
1486 | } |
1487 | |
1488 | as_bytes * b = mod_lua_checkbytes(l, 1); |
1489 | lua_Integer i = luaL_optinteger(l, 2, 0); |
1490 | |
1491 | // check preconditions: |
1492 | // - b != NULL |
1493 | // - 1 <= i <= UINT32_MAX |
1494 | if ( !b || |
1495 | i < 1 || i > UINT32_MAX ) { |
1496 | return 0; |
1497 | } |
1498 | |
1499 | uint32_t pos = (uint32_t)(i - 1); |
1500 | int64_t val = 0; |
1501 | |
1502 | // get returns 0 on failure |
1503 | if ( as_bytes_get_int64(b, pos, &val) == 0 ) { |
1504 | return 0; |
1505 | } |
1506 | |
1507 | int64_t res = cf_swap_from_be64(val); |
1508 | lua_pushinteger(l, res); |
1509 | return 1; |
1510 | } |
1511 | |
1512 | /** |
1513 | * Get a little endian int64 value from the specified index. |
1514 | * |
1515 | * ----------{.c} |
1516 | * int64 bytes.get_int64_le(bytes b, uint32 i) |
1517 | * ---------- |
1518 | * |
1519 | * @param b The bytes to get a value from. |
1520 | * @param i The index in b to get the value of. |
1521 | * |
1522 | * @return On success, the value. Otherwise nil on failure. |
1523 | */ |
1524 | static int mod_lua_bytes_get_int64_le(lua_State * l) |
1525 | { |
1526 | // we expect exactly 2 args |
1527 | if ( lua_gettop(l) != 2) { |
1528 | return 0; |
1529 | } |
1530 | |
1531 | as_bytes * b = mod_lua_checkbytes(l, 1); |
1532 | lua_Integer i = luaL_optinteger(l, 2, 0); |
1533 | |
1534 | // check preconditions: |
1535 | // - b != NULL |
1536 | // - 1 <= i <= UINT32_MAX |
1537 | if ( !b || |
1538 | i < 1 || i > UINT32_MAX ) { |
1539 | return 0; |
1540 | } |
1541 | |
1542 | uint32_t pos = (uint32_t)(i - 1); |
1543 | int64_t val = 0; |
1544 | |
1545 | // get returns 0 on failure |
1546 | if ( as_bytes_get_int64(b, pos, &val) == 0 ) { |
1547 | return 0; |
1548 | } |
1549 | |
1550 | int64_t res = cf_swap_from_le64(val); |
1551 | lua_pushinteger(l, res); |
1552 | return 1; |
1553 | } |
1554 | |
1555 | /** |
1556 | * Decode an integer in variable 7-bit format. |
1557 | * The high bit indicates if more bytes are used. |
1558 | * |
1559 | * ----------{.c} |
1560 | * int bytes.get_var_int(bytes b, uint32 i) |
1561 | * ---------- |
1562 | * |
1563 | * @param b The bytes to get a value from. |
1564 | * @param i The index in b to get the value of. |
1565 | * |
1566 | * @return On success, the value. Otherwise nil on failure. |
1567 | */ |
1568 | static int mod_lua_bytes_get_var_int(lua_State * l) |
1569 | { |
1570 | // we expect exactly 2 args |
1571 | if ( lua_gettop(l) != 2) { |
1572 | return 0; |
1573 | } |
1574 | |
1575 | as_bytes * b = mod_lua_checkbytes(l, 1); |
1576 | lua_Integer i = luaL_optinteger(l, 2, 0); |
1577 | |
1578 | // check preconditions: |
1579 | // - b != NULL |
1580 | // - 1 <= i <= UINT32_MAX |
1581 | if ( !b || |
1582 | i < 1 || i > UINT32_MAX ) { |
1583 | return 0; |
1584 | } |
1585 | |
1586 | uint32_t pos = (uint32_t)(i - 1); |
1587 | uint32_t val = 0; |
1588 | uint32_t size = as_bytes_get_var_int(b, pos, &val); |
1589 | |
1590 | lua_pushinteger(l, val); |
1591 | lua_pushinteger(l, size); |
1592 | return 2; |
1593 | } |
1594 | |
1595 | /** |
1596 | * Get an bytes value from the specified index. |
1597 | * |
1598 | * ----------{.c} |
1599 | * bytes bytes.get_bytes(bytes b, uint32 i, uint32 n) |
1600 | * ---------- |
1601 | * |
1602 | * @param b The bytes to get a value from. |
1603 | * @param i The index in b to get the value from. |
1604 | * @param n The the length of the bytes to copy. |
1605 | * |
1606 | * @return On success, the value. Otherwise nil on failure. |
1607 | */ |
1608 | |
1609 | static int mod_lua_bytes_get_string(lua_State * l) |
1610 | { |
1611 | // we expect exactly 3 args |
1612 | if ( lua_gettop(l) != 3 ) { |
1613 | return 0; |
1614 | } |
1615 | |
1616 | as_bytes * b = mod_lua_checkbytes(l, 1); |
1617 | lua_Integer i = luaL_optinteger(l, 2, 0); |
1618 | lua_Integer n = luaL_optinteger(l, 3, 0); |
1619 | |
1620 | // check preconditions: |
1621 | // - b != NULL |
1622 | // - 1 <= i <= UINT32_MAX |
1623 | // - 0 <= n <= UINT32_MAX |
1624 | if ( !b || |
1625 | i < 1 || i > UINT32_MAX || |
1626 | n < 0 || n > UINT32_MAX ) { |
1627 | return 0; |
1628 | } |
1629 | |
1630 | uint32_t pos = (uint32_t)(i - 1); |
1631 | uint32_t len = (uint32_t) n; |
1632 | char * val = (char *) cf_calloc(len + 1, sizeof(char)); |
1633 | |
1634 | if ( !val ) { |
1635 | return 0; |
1636 | } |
1637 | |
1638 | // copy into the the string |
1639 | memcpy(val, b->value + pos, len); |
1640 | val[len] = '\0'; |
1641 | |
1642 | lua_pushlstring(l, val, len); |
1643 | cf_free(val); |
1644 | return 1; |
1645 | } |
1646 | |
1647 | |
1648 | /** |
1649 | * Get an bytes value from the specified index. |
1650 | * |
1651 | * ----------{.c} |
1652 | * bytes bytes.get_bytes(bytes b, uint32 i, uint32 n) |
1653 | * ---------- |
1654 | * |
1655 | * @param b The bytes to get a value from. |
1656 | * @param i The index in b to get the value from. |
1657 | * @param n The the length of the bytes to copy. |
1658 | * |
1659 | * @return On success, the value. Otherwise nil on failure. |
1660 | */ |
1661 | static int mod_lua_bytes_get_bytes(lua_State * l) |
1662 | { |
1663 | // we expect exactly 3 args |
1664 | if ( lua_gettop(l) != 3 ) { |
1665 | return 0; |
1666 | } |
1667 | |
1668 | as_bytes * b = mod_lua_checkbytes(l, 1); |
1669 | lua_Integer i = luaL_optinteger(l, 2, 0); |
1670 | lua_Integer n = luaL_optinteger(l, 3, 0); |
1671 | |
1672 | // check preconditions: |
1673 | // - b != NULL |
1674 | // - 1 <= i <= UINT32_MAX |
1675 | // - 0 <= n <= UINT32_MAX |
1676 | if ( !b || |
1677 | i < 1 || i > UINT32_MAX || |
1678 | n < 0 || n > UINT32_MAX ) { |
1679 | return 0; |
1680 | } |
1681 | |
1682 | uint32_t pos = (uint32_t)(i - 1); |
1683 | uint32_t len = (uint32_t) n; |
1684 | uint8_t * raw = (uint8_t *) cf_calloc(len, sizeof(uint8_t)); |
1685 | |
1686 | if ( !raw ) { |
1687 | return 0; |
1688 | } |
1689 | |
1690 | // copy into the the buffer |
1691 | memcpy(raw, b->value + pos, len); |
1692 | |
1693 | // create a new bytes |
1694 | as_bytes * val = as_bytes_new_wrap(raw, len, true); |
1695 | |
1696 | if ( !val ) { |
1697 | return 0; |
1698 | } |
1699 | |
1700 | mod_lua_pushbytes(l, val); |
1701 | return 1; |
1702 | } |
1703 | |
1704 | /****************************************************************************** |
1705 | * OBJECT TABLE |
1706 | *****************************************************************************/ |
1707 | |
1708 | static const luaL_reg bytes_object_table[] = { |
1709 | |
1710 | {"size" , mod_lua_bytes_size}, |
1711 | {"set_size" , mod_lua_bytes_ensure}, |
1712 | |
1713 | {"get_type" , mod_lua_bytes_get_type}, |
1714 | {"set_type" , mod_lua_bytes_set_type}, |
1715 | |
1716 | {"get_string" , mod_lua_bytes_get_string}, |
1717 | {"get_bytes" , mod_lua_bytes_get_bytes}, |
1718 | {"get_byte" , mod_lua_bytes_get_byte}, |
1719 | {"get_int16" , mod_lua_bytes_get_int16_be}, |
1720 | {"get_int16_be" , mod_lua_bytes_get_int16_be}, |
1721 | {"get_int16_le" , mod_lua_bytes_get_int16_le}, |
1722 | {"get_int32" , mod_lua_bytes_get_int32_be}, |
1723 | {"get_int32_be" , mod_lua_bytes_get_int32_be}, |
1724 | {"get_int32_le" , mod_lua_bytes_get_int32_le}, |
1725 | {"get_int64" , mod_lua_bytes_get_int64_be}, |
1726 | {"get_int64_be" , mod_lua_bytes_get_int64_be}, |
1727 | {"get_int64_le" , mod_lua_bytes_get_int64_le}, |
1728 | {"get_var_int" , mod_lua_bytes_get_var_int}, |
1729 | |
1730 | {"set_string" , mod_lua_bytes_set_string}, |
1731 | {"set_bytes" , mod_lua_bytes_set_bytes}, |
1732 | {"set_byte" , mod_lua_bytes_set_byte}, |
1733 | {"set_int16" , mod_lua_bytes_set_int16_be}, |
1734 | {"set_int16_be" , mod_lua_bytes_set_int16_be}, |
1735 | {"set_int16_le" , mod_lua_bytes_set_int16_le}, |
1736 | {"set_int32" , mod_lua_bytes_set_int32_be}, |
1737 | {"set_int32_be" , mod_lua_bytes_set_int32_be}, |
1738 | {"set_int32_le" , mod_lua_bytes_set_int32_le}, |
1739 | {"set_int64" , mod_lua_bytes_set_int64_be}, |
1740 | {"set_int64_be" , mod_lua_bytes_set_int64_be}, |
1741 | {"set_int64_le" , mod_lua_bytes_set_int64_le}, |
1742 | {"set_var_int" , mod_lua_bytes_set_var_int}, |
1743 | |
1744 | {"append_string" , mod_lua_bytes_append_string}, |
1745 | {"append_bytes" , mod_lua_bytes_append_bytes}, |
1746 | {"append_byte" , mod_lua_bytes_append_byte}, |
1747 | {"append_int16" , mod_lua_bytes_append_int16_be}, |
1748 | {"append_int16_be" , mod_lua_bytes_append_int16_be}, |
1749 | {"append_int16_le" , mod_lua_bytes_append_int16_le}, |
1750 | {"append_int32" , mod_lua_bytes_append_int32_be}, |
1751 | {"append_int32_be" , mod_lua_bytes_append_int32_be}, |
1752 | {"append_int32_le" , mod_lua_bytes_append_int32_le}, |
1753 | {"append_int64" , mod_lua_bytes_append_int64_be}, |
1754 | {"append_int64_be" , mod_lua_bytes_append_int64_be}, |
1755 | {"append_int64_le" , mod_lua_bytes_append_int64_le}, |
1756 | {"append_var_int" , mod_lua_bytes_append_var_int}, |
1757 | |
1758 | {0, 0} |
1759 | }; |
1760 | |
1761 | static const luaL_reg bytes_object_metatable[] = { |
1762 | {"__call" , mod_lua_bytes_new}, |
1763 | {0, 0} |
1764 | }; |
1765 | |
1766 | /****************************************************************************** |
1767 | * CLASS TABLE |
1768 | *****************************************************************************/ |
1769 | |
1770 | /* |
1771 | static const luaL_reg bytes_class_table[] = { |
1772 | {"putX", mod_lua_bytes_tostring}, |
1773 | {0, 0} |
1774 | }; |
1775 | */ |
1776 | |
1777 | static const luaL_reg bytes_class_metatable[] = { |
1778 | {"__index" , mod_lua_bytes_get_byte}, |
1779 | {"__newindex" , mod_lua_bytes_set_byte}, |
1780 | {"__len" , mod_lua_bytes_size}, |
1781 | {"__tostring" , mod_lua_bytes_tostring}, |
1782 | {"__gc" , mod_lua_bytes_gc}, |
1783 | {0, 0} |
1784 | }; |
1785 | |
1786 | /****************************************************************************** |
1787 | * REGISTER |
1788 | *****************************************************************************/ |
1789 | |
1790 | int mod_lua_bytes_register(lua_State * l) { |
1791 | mod_lua_reg_object(l, OBJECT_NAME, bytes_object_table, bytes_object_metatable); |
1792 | mod_lua_reg_class(l, CLASS_NAME, NULL, bytes_class_metatable); |
1793 | return 1; |
1794 | } |
1795 | |