Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / wslua / wslua_byte_array.c
blob041555062faff590c1bb670eb843c6399447d796
1 /*
2 * wslua_byte_array.c
4 * Wireshark's interface to the Lua Programming Language
6 * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
7 * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
8 * (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
9 * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include "config.h"
20 #include "wslua.h"
22 /* WSLUA_CONTINUE_MODULE Tvb */
25 WSLUA_CLASS_DEFINE(ByteArray,FAIL_ON_NULL("ByteArray"));
27 WSLUA_CONSTRUCTOR ByteArray_new(lua_State* L) {
29 Creates a new <<lua_class_ByteArray,`ByteArray`>> object.
31 Starting in version 1.11.3, if the second argument is a boolean `true`,
32 then the first argument is treated as a raw Lua string of bytes to use,
33 instead of a hexadecimal string.
35 ===== Example
37 [source,lua]
38 ----
39 local empty = ByteArray.new()
40 local b1 = ByteArray.new("a1 b2 c3 d4")
41 local b2 = ByteArray.new("112233")
42 ----
44 #define WSLUA_OPTARG_ByteArray_new_HEXBYTES 1 /* A string consisting of hexadecimal bytes like "00 B1 A2" or "1a2b3c4d". */
45 #define WSLUA_OPTARG_ByteArray_new_SEPARATOR 2 /* A string separator between hex bytes/words (default=" "),
46 or if the boolean value `true` is used, then the first argument
47 is treated as raw binary data */
48 GByteArray* ba = g_byte_array_new();
49 const char* s;
50 size_t len = 0;
51 const char* sep = " ";
52 bool ishex = true;
54 if (lua_gettop(L) >= 1) {
55 s = luaL_checklstring(L,WSLUA_OPTARG_ByteArray_new_HEXBYTES,&len);
57 if (lua_gettop(L) >= 2) {
58 if (lua_type(L,2) == LUA_TBOOLEAN && lua_toboolean(L,2)) {
59 ishex = false;
60 } else {
61 sep = luaL_optstring(L,WSLUA_OPTARG_ByteArray_new_SEPARATOR," ");
65 if (ishex) {
66 wslua_hex2bin(L, s, (unsigned)len, sep); /* this pushes a new string on top of stack */
67 s = luaL_checklstring(L, -1, &len); /* get the new binary string */
68 g_byte_array_append(ba,s,(unsigned)len); /* copy it into ByteArray */
69 lua_pop(L,1); /* pop the newly created string */
70 } else {
71 g_byte_array_append(ba,s,(unsigned)len);
75 pushByteArray(L,ba);
77 WSLUA_RETURN(1); /* The new ByteArray object. */
80 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
81 static int ByteArray__gc(lua_State* L) {
82 ByteArray ba = toByteArray(L,1);
84 if (!ba) return 0;
86 g_byte_array_free(ba,true);
87 return 0;
90 WSLUA_METAMETHOD ByteArray__concat(lua_State* L) {
91 /* Concatenate two <<lua_class_ByteArray,`ByteArray`>>s. */
92 #define WSLUA_ARG_ByteArray__concat_FIRST 1 /* First array. */
93 #define WSLUA_ARG_ByteArray__concat_SECOND 2 /* Second array. */
95 ByteArray ba1 = checkByteArray(L,WSLUA_ARG_ByteArray__concat_FIRST);
96 ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray__concat_SECOND);
97 ByteArray ba;
99 ba = g_byte_array_new();
100 g_byte_array_append(ba,ba1->data,ba1->len);
101 g_byte_array_append(ba,ba2->data,ba2->len);
103 pushByteArray(L,ba);
104 WSLUA_RETURN(1); /* The new composite <<lua_class_ByteArray,`ByteArray`>>. */
107 WSLUA_METAMETHOD ByteArray__eq(lua_State* L) {
108 /* Compares two ByteArray values. */
109 #define WSLUA_ARG_ByteArray__eq_FIRST 1 /* First array. */
110 #define WSLUA_ARG_ByteArray__eq_SECOND 2 /* Second array. */
111 ByteArray ba1 = checkByteArray(L,WSLUA_ARG_ByteArray__eq_FIRST);
112 ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray__eq_SECOND);
113 bool result = false;
115 if (ba1->len == ba2->len) {
116 if (memcmp(ba1->data, ba2->data, ba1->len) == 0)
117 result = true;
120 lua_pushboolean(L,result);
122 return 1;
125 WSLUA_METHOD ByteArray_prepend(lua_State* L) {
126 /* Prepend a <<lua_class_ByteArray,`ByteArray`>> to this <<lua_class_ByteArray,`ByteArray`>>. */
127 #define WSLUA_ARG_ByteArray_prepend_PREPENDED 2 /* <<lua_class_ByteArray,`ByteArray`>> to be prepended. */
128 ByteArray ba = checkByteArray(L,1);
129 ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray_prepend_PREPENDED);
131 g_byte_array_prepend(ba,ba2->data,ba2->len);
133 return 0;
136 WSLUA_METHOD ByteArray_append(lua_State* L) {
137 /* Append a <<lua_class_ByteArray,`ByteArray`>> to this <<lua_class_ByteArray,`ByteArray`>>. */
138 #define WSLUA_ARG_ByteArray_append_APPENDED 2 /* <<lua_class_ByteArray,`ByteArray`>> to be appended. */
139 ByteArray ba = checkByteArray(L,1);
140 ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray_append_APPENDED);
142 g_byte_array_append(ba,ba2->data,ba2->len);
144 return 0;
147 WSLUA_METHOD ByteArray_set_size(lua_State* L) {
148 /* Sets the size of a <<lua_class_ByteArray,`ByteArray`>>, either truncating it or filling it with zeros. */
149 #define WSLUA_ARG_ByteArray_set_size_SIZE 2 /* New size of the array. */
151 ByteArray ba = checkByteArray(L,1);
152 int siz = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_set_size_SIZE);
153 uint8_t* padding;
155 if (siz < 0) {
156 WSLUA_ERROR(ByteArray_set_size,"ByteArray size must be non-negative");
157 return 0;
160 if (ba->len >= (unsigned)siz) { /* truncate */
161 g_byte_array_set_size(ba,siz);
162 } else { /* fill */
163 padding = (uint8_t *)g_malloc0(sizeof(uint8_t)*(siz - ba->len));
164 g_byte_array_append(ba,padding,siz - ba->len);
165 g_free(padding);
167 return 0;
170 WSLUA_METHOD ByteArray_set_index(lua_State* L) {
171 /* Sets the value of an index of a <<lua_class_ByteArray,`ByteArray`>>. */
172 #define WSLUA_ARG_ByteArray_set_index_INDEX 2 /* The position of the byte to be set. */
173 #define WSLUA_ARG_ByteArray_set_index_VALUE 3 /* The char value to set [0-255]. */
174 ByteArray ba = checkByteArray(L,1);
175 int idx = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_set_index_INDEX);
176 int v = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_set_index_VALUE);
178 if (idx == 0 && ! g_str_equal(luaL_optstring(L,2,""),"0") ) {
179 luaL_argerror(L,2,"bad index");
180 return 0;
183 if (idx < 0 || (unsigned)idx >= ba->len) {
184 luaL_argerror(L,2,"index out of range");
185 return 0;
188 if (v < 0 || v > 255) {
189 luaL_argerror(L,3,"Byte out of range");
190 return 0;
193 ba->data[idx] = (uint8_t)v;
195 return 0;
199 WSLUA_METHOD ByteArray_get_index(lua_State* L) {
200 /* Get the value of a byte in a <<lua_class_ByteArray,`ByteArray`>>. */
201 #define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the byte to get. */
202 ByteArray ba = checkByteArray(L,1);
203 int idx = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_get_index_INDEX);
205 if (idx == 0 && ! g_str_equal(luaL_optstring(L,2,""),"0") ) {
206 luaL_argerror(L,2,"bad index");
207 return 0;
210 if (idx < 0 || (unsigned)idx >= ba->len) {
211 luaL_argerror(L,2,"index out of range");
212 return 0;
214 lua_pushinteger(L,ba->data[idx]);
216 WSLUA_RETURN(1); /* The value [0-255] of the byte. */
219 WSLUA_METHOD ByteArray_le_int(lua_State* L) {
220 /* Read a little endian encoded signed integer in a <<lua_class_ByteArray,`ByteArray`>> beginning at given offset with given length.
222 @since 4.2.0
224 #define WSLUA_OPTARG_ByteArray_le_int_OFFSET 2 /* The position of the first byte. Default is 0, or the first byte. */
225 #define WSLUA_OPTARG_ByteArray_le_int_LENGTH 3 /* The length of the integer. Default is -1, or the remaining bytes in the <<lua_class_ByteArray,`ByteArray`>>. */
226 ByteArray ba = checkByteArray(L, 1);
227 int offset = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_le_int_OFFSET, 0);
228 int len = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_le_int_LENGTH, -1);
230 if (offset < 0 || (unsigned)offset >= ba->len) {
231 luaL_argerror(L, WSLUA_OPTARG_ByteArray_le_int_OFFSET, "offset out of bounds");
232 return 0;
235 if (len == -1) {
236 len = ba->len - offset; /* Use remaining bytes. */
239 if (len < 1 || len > 4) {
240 luaL_argerror(L, WSLUA_OPTARG_ByteArray_le_int_LENGTH, "bad length");
241 return 0;
244 if ((unsigned)(offset + len) > ba->len) {
245 luaL_error(L, "range out of bounds");
246 return 0;
249 int32_t value = (int8_t)ba->data[offset + len - 1];
250 for (int i = len - 2; i >= 0; i--) {
251 value <<= 8;
252 value |= (uint8_t)ba->data[offset + i];
255 lua_pushinteger(L, value);
257 WSLUA_RETURN(1); /* The value of the little endian encoded signed integer beginning at given offset with given length. */
260 WSLUA_METHOD ByteArray_le_int64(lua_State* L) {
261 /* Read a little endian encoded 64 bit signed integer in a <<lua_class_ByteArray,`ByteArray`>> beginning at given offset with given length.
263 @since 4.2.0
265 #define WSLUA_OPTARG_ByteArray_le_int64_OFFSET 2 /* The position of the first byte. Default is 0, or the first byte. */
266 #define WSLUA_OPTARG_ByteArray_le_int64_LENGTH 3 /* The length of the integer. Default is -1, or the remaining bytes in the <<lua_class_ByteArray,`ByteArray`>>. */
267 ByteArray ba = checkByteArray(L, 1);
268 int offset = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_le_int64_OFFSET, 0);
269 int len = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_le_int64_LENGTH, -1);
271 if (offset < 0 || (unsigned)offset >= ba->len) {
272 luaL_argerror(L, WSLUA_OPTARG_ByteArray_le_int64_OFFSET, "offset out of bounds");
273 return 0;
276 if (len == -1) {
277 len = ba->len - offset; /* Use remaining bytes. */
280 if (len < 1 || len > 8) {
281 luaL_argerror(L, WSLUA_OPTARG_ByteArray_le_int64_LENGTH, "bad length");
282 return 0;
285 if ((unsigned)(offset + len) > ba->len) {
286 luaL_error(L, "range out of bounds");
287 return 0;
290 int64_t value = (int8_t)ba->data[offset + len - 1];
291 for (int i = len - 2; i >= 0; i--) {
292 value <<= 8;
293 value |= (uint8_t)ba->data[offset + i];
296 pushInt64(L, value);
298 WSLUA_RETURN(1); /* The value of the little endian encoded 64 bit signed integer as a <<lua_class_Int64,`Int64`>> object beginning at given offset with given length. */
301 WSLUA_METHOD ByteArray_le_uint(lua_State* L) {
302 /* Read a little endian encoded unsigned integer in a <<lua_class_ByteArray,`ByteArray`>> beginning at given offset with given length.
304 @since 4.2.0
306 #define WSLUA_OPTARG_ByteArray_le_uint_OFFSET 2 /* The position of the first byte. Default is 0, or the first byte. */
307 #define WSLUA_OPTARG_ByteArray_le_uint_LENGTH 3 /* The length of the integer. Default is -1, or the remaining bytes in the <<lua_class_ByteArray,`ByteArray`>>. */
308 ByteArray ba = checkByteArray(L, 1);
309 int offset = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_le_uint_OFFSET, 0);
310 int len = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_le_uint_LENGTH, -1);
312 if (offset < 0 || (unsigned)offset >= ba->len) {
313 luaL_argerror(L, WSLUA_OPTARG_ByteArray_le_uint_OFFSET, "offset out of bounds");
314 return 0;
317 if (len == -1) {
318 len = ba->len - offset; /* Use remaining bytes. */
321 if (len < 1 || len > 4) {
322 luaL_argerror(L, WSLUA_OPTARG_ByteArray_le_uint_LENGTH, "bad length");
323 return 0;
326 if ((unsigned)(offset + len) > ba->len) {
327 luaL_error(L, "range out of bounds");
328 return 0;
331 uint32_t value = (uint8_t)ba->data[offset + len - 1];
332 for (int i = len - 2; i >= 0; i--) {
333 value <<= 8;
334 value |= (uint8_t)ba->data[offset + i];
337 lua_pushinteger(L, value);
339 WSLUA_RETURN(1); /* The value of the little endian encoded unsigned integer beginning at given offset with given length. */
342 WSLUA_METHOD ByteArray_le_uint64(lua_State* L) {
343 /* Read a little endian encoded 64 bit unsigned integer in a <<lua_class_ByteArray,`ByteArray`>> beginning at given offset with given length.
345 @since 4.2.0
347 #define WSLUA_OPTARG_ByteArray_le_uint64_OFFSET 2 /* The position of the first byte. Default is 0, or the first byte. */
348 #define WSLUA_OPTARG_ByteArray_le_uint64_LENGTH 3 /* The length of the integer. Default is -1, or the remaining bytes in the <<lua_class_ByteArray,`ByteArray`>>. */
349 ByteArray ba = checkByteArray(L, 1);
350 int offset = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_le_uint64_OFFSET, 0);
351 int len = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_le_uint64_LENGTH, -1);
353 if (offset < 0 || (unsigned)offset >= ba->len) {
354 luaL_argerror(L, WSLUA_OPTARG_ByteArray_le_uint64_OFFSET, "offset out of bounds");
355 return 0;
358 if (len == -1) {
359 len = ba->len - offset; /* Use remaining bytes. */
362 if (len < 1 || len > 8) {
363 luaL_argerror(L, WSLUA_OPTARG_ByteArray_le_uint64_LENGTH, "bad length");
364 return 0;
367 if ((unsigned)(offset + len) > ba->len) {
368 luaL_error(L, "range out of bounds");
369 return 0;
372 uint64_t value = (uint8_t)ba->data[offset + len - 1];
373 for (int i = len - 2; i >= 0; i--) {
374 value <<= 8;
375 value |= (uint8_t)ba->data[offset + i];
378 pushUInt64(L, value);
380 WSLUA_RETURN(1); /* The value of the little endian encoded 64 bit unsigned integer as a <<lua_class_UInt64,`UInt64`>> object beginning at given offset with given length. */
383 WSLUA_METHOD ByteArray_int(lua_State* L) {
384 /* Read a big endian encoded signed integer in a <<lua_class_ByteArray,`ByteArray`>> beginning at given offset with given length.
386 @since 4.2.0
388 #define WSLUA_OPTARG_ByteArray_int_OFFSET 2 /* The position of the first byte. Default is 0, or the first byte. */
389 #define WSLUA_OPTARG_ByteArray_int_LENGTH 3 /* The length of the integer. Default is -1, or the remaining bytes in the <<lua_class_ByteArray,`ByteArray`>>. */
390 ByteArray ba = checkByteArray(L, 1);
391 int offset = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_int_OFFSET, 0);
392 int len = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_int_LENGTH, -1);
394 if (offset < 0 || (unsigned)offset >= ba->len) {
395 luaL_argerror(L, WSLUA_OPTARG_ByteArray_int_OFFSET, "offset out of bounds");
396 return 0;
399 if (len == -1) {
400 len = ba->len - offset; /* Use remaining bytes. */
403 if (len < 1 || len > 4) {
404 luaL_argerror(L, WSLUA_OPTARG_ByteArray_int_LENGTH, "bad length");
405 return 0;
408 if ((unsigned)(offset + len) > ba->len) {
409 luaL_error(L, "range out of bounds");
410 return 0;
413 int32_t value = (int8_t)ba->data[offset];
414 for (int i = 1; i < len; i++) {
415 value <<= 8;
416 value |= (uint8_t)ba->data[offset + i];
419 lua_pushinteger(L, value);
421 WSLUA_RETURN(1); /* The value of the big endian encoded 32 bit signed integer beginning at given offset with given length. */
424 WSLUA_METHOD ByteArray_int64(lua_State* L) {
425 /* Read a big endian encoded 64 bit signed integer in a <<lua_class_ByteArray,`ByteArray`>> beginning at given offset with given length.
427 @since 4.2.0
429 #define WSLUA_OPTARG_ByteArray_int64_OFFSET 2 /* The position of the first byte. Default is 0, or the first byte. */
430 #define WSLUA_OPTARG_ByteArray_int64_LENGTH 3 /* The length of the integer. Default is -1, or the remaining bytes in the <<lua_class_ByteArray,`ByteArray`>>. */
431 ByteArray ba = checkByteArray(L, 1);
432 int offset = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_int64_OFFSET, 0);
433 int len = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_int64_LENGTH, -1);
435 if (offset < 0 || (unsigned)offset >= ba->len) {
436 luaL_argerror(L, WSLUA_OPTARG_ByteArray_int64_OFFSET, "offset out of bounds");
437 return 0;
440 if (len == -1) {
441 len = ba->len - offset; /* Use remaining bytes. */
444 if (len < 1 || len > 8) {
445 luaL_argerror(L, WSLUA_OPTARG_ByteArray_int64_LENGTH, "bad length");
446 return 0;
449 if ((unsigned)(offset + len) > ba->len) {
450 luaL_error(L, "range out of bounds");
451 return 0;
454 int64_t value = (int8_t)ba->data[offset];
455 for (int i = 1; i < len; i++) {
456 value <<= 8;
457 value |= (uint8_t)ba->data[offset + i];
460 pushInt64(L, value);
462 WSLUA_RETURN(1); /* The value of the big endian encoded 64 bit signed integer as a <<lua_class_Int64,`Int64`>> object beginning at given offset and given length. */
465 WSLUA_METHOD ByteArray_uint(lua_State* L) {
466 /* Read a big endian encoded unsigned integer in a <<lua_class_ByteArray,`ByteArray`>> beginning at given offset with given length.
468 @since 4.2.0
470 #define WSLUA_OPTARG_ByteArray_uint_OFFSET 2 /* The position of the first byte. Default is 0, or the first byte. */
471 #define WSLUA_OPTARG_ByteArray_uint_LENGTH 3 /* The length of the integer. Default is -1, or the remaining bytes in the <<lua_class_ByteArray,`ByteArray`>>. */
472 ByteArray ba = checkByteArray(L, 1);
473 int offset = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_uint_OFFSET, 0);
474 int len = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_uint_LENGTH, -1);
476 if (offset < 0 || (unsigned)offset >= ba->len) {
477 luaL_argerror(L, WSLUA_OPTARG_ByteArray_uint_OFFSET, "offset out of bounds");
478 return 0;
481 if (len == -1) {
482 len = ba->len - offset; /* Use remaining bytes. */
485 if (len < 1 || len > 4) {
486 luaL_argerror(L, WSLUA_OPTARG_ByteArray_uint_LENGTH, "bad length");
487 return 0;
490 if ((unsigned)(offset + len) > ba->len) {
491 luaL_error(L, "range out of bounds");
492 return 0;
495 uint32_t value = (uint8_t)ba->data[offset];
496 for (int i = 1; i < len; i++) {
497 value <<= 8;
498 value |= (uint8_t)ba->data[offset + i];
501 lua_pushinteger(L, value);
503 WSLUA_RETURN(1); /* The value of the big endian encoded 32 bit unsigned integer beginning at given offset with given length. */
506 WSLUA_METHOD ByteArray_uint64(lua_State* L) {
507 /* Read a big endian encoded 64 bit unsigned integer in a <<lua_class_ByteArray,`ByteArray`>> beginning at given offset with given length.
509 @since 4.2.0
511 #define WSLUA_OPTARG_ByteArray_uint64_OFFSET 2 /* The position of the first byte. Default is 0, or the first byte. */
512 #define WSLUA_OPTARG_ByteArray_uint64_LENGTH 3 /* The length of the integer. Default is -1, or the remaining bytes in the <<lua_class_ByteArray,`ByteArray`>>. */
513 ByteArray ba = checkByteArray(L, 1);
514 int offset = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_uint64_OFFSET, 0);
515 int len = (int)luaL_optinteger(L, WSLUA_OPTARG_ByteArray_uint64_LENGTH, -1);
517 if (offset < 0 || (unsigned)offset >= ba->len) {
518 luaL_argerror(L, WSLUA_OPTARG_ByteArray_uint64_OFFSET, "offset out of bounds");
519 return 0;
522 if (len == -1) {
523 len = ba->len - offset; /* Use remaining bytes. */
526 if (len < 1 || len > 8) {
527 luaL_argerror(L, WSLUA_OPTARG_ByteArray_uint64_LENGTH, "bad length");
528 return 0;
531 if ((unsigned)(offset + len) > ba->len) {
532 luaL_error(L, "range out of bounds");
533 return 0;
536 uint64_t value = (uint8_t)ba->data[offset];
537 for (int i = 1; i < len; i++) {
538 value <<= 8;
539 value |= (uint8_t)ba->data[offset + i];
542 pushUInt64(L, value);
544 WSLUA_RETURN(1); /* The value of the big endian encoded 64 bit unsigned integer as a <<lua_class_UInt64,`UInt64`>> object beginning at given offset with given length. */
547 WSLUA_METHOD ByteArray_len(lua_State* L) {
548 /* Obtain the length of a <<lua_class_ByteArray,`ByteArray`>>. */
549 ByteArray ba = checkByteArray(L,1);
551 lua_pushinteger(L,(lua_Integer)ba->len);
553 WSLUA_RETURN(1); /* The length of the <<lua_class_ByteArray,`ByteArray`>>. */
556 WSLUA_METHOD ByteArray_subset(lua_State* L) {
557 /* Obtain a segment of a <<lua_class_ByteArray,`ByteArray`>>, as a new <<lua_class_ByteArray,`ByteArray`>>. */
558 #define WSLUA_ARG_ByteArray_subset_OFFSET 2 /* The position of the first byte (0=first). */
559 #define WSLUA_ARG_ByteArray_subset_LENGTH 3 /* The length of the segment. */
560 ByteArray ba = checkByteArray(L,1);
561 int offset = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_subset_OFFSET);
562 int len = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_subset_LENGTH);
563 ByteArray sub;
565 if ((offset + len) > (int)ba->len || offset < 0 || len < 1) {
566 luaL_error(L,"Out Of Bounds");
567 return 0;
570 sub = g_byte_array_new();
571 g_byte_array_append(sub,ba->data + offset,len);
573 pushByteArray(L,sub);
575 WSLUA_RETURN(1); /* A <<lua_class_ByteArray,`ByteArray`>> containing the requested segment. */
578 WSLUA_METHOD ByteArray_base64_decode(lua_State* L) {
579 /* Obtain a Base64 decoded <<lua_class_ByteArray,`ByteArray`>>. */
580 ByteArray ba = checkByteArray(L,1);
581 ByteArray ba2;
582 char *data;
583 size_t len = ba->len;
585 if ((len % 4) != 0) {
586 len += 4 - (len % 4);
589 ba2 = g_byte_array_new();
590 if (ba->len > 1) {
591 data = (char*)g_malloc(len + 1);
592 memcpy(data, ba->data, ba->len);
593 if (len > ba->len) {
594 memcpy(data + ba->len, "====", len - ba->len);
596 data[len] = '\0';
598 g_base64_decode_inplace(data, &len);
599 g_byte_array_append(ba2, data, (int)len);
600 g_free(data);
603 pushByteArray(L,ba2);
604 WSLUA_RETURN(1); /* The created <<lua_class_ByteArray,`ByteArray`>>. */
607 WSLUA_METHOD ByteArray_raw(lua_State* L) {
608 /* Obtain a Lua string of the binary bytes in a <<lua_class_ByteArray,`ByteArray`>>. */
609 #define WSLUA_OPTARG_ByteArray_raw_OFFSET 2 /* The position of the first byte (default=0/first). */
610 #define WSLUA_OPTARG_ByteArray_raw_LENGTH 3 /* The length of the segment to get (default=all). */
611 ByteArray ba = checkByteArray(L,1);
612 unsigned offset = (unsigned) luaL_optinteger(L,WSLUA_OPTARG_ByteArray_raw_OFFSET,0);
613 int len;
615 if (!ba) return 0;
616 if (offset > ba->len) {
617 WSLUA_OPTARG_ERROR(ByteArray_raw,OFFSET,"offset beyond end of byte array");
618 return 0;
621 len = (int) luaL_optinteger(L,WSLUA_OPTARG_ByteArray_raw_LENGTH, ba->len - offset);
622 if ((len < 0) || ((unsigned)len > (ba->len - offset)))
623 len = ba->len - offset;
625 lua_pushlstring(L, &(ba->data[offset]), len);
627 WSLUA_RETURN(1); /* A Lua string of the binary bytes in the ByteArray. */
630 WSLUA_METHOD ByteArray_tohex(lua_State* L) {
631 /* Obtain a Lua string of the bytes in a <<lua_class_ByteArray,`ByteArray`>> as hex-ascii, with given separator. */
632 #define WSLUA_OPTARG_ByteArray_tohex_LOWERCASE 2 /* True to use lower-case hex characters (default=false). */
633 #define WSLUA_OPTARG_ByteArray_tohex_SEPARATOR 3 /* A string separator to insert between hex bytes (default=nil). */
634 ByteArray ba = checkByteArray(L,1);
635 bool lowercase = false;
636 const char* sep = NULL;
638 if (!ba) return 0;
640 lowercase = wslua_optbool(L,WSLUA_OPTARG_ByteArray_tohex_LOWERCASE,false);
641 sep = luaL_optstring(L,WSLUA_OPTARG_ByteArray_tohex_SEPARATOR,NULL);
643 wslua_bin2hex(L, ba->data, ba->len, lowercase, sep);
645 WSLUA_RETURN(1); /* A hex-ascii string representation of the <<lua_class_ByteArray,`ByteArray`>>. */
648 WSLUA_METAMETHOD ByteArray__tostring(lua_State* L) {
649 /* Obtain a Lua string containing the bytes in a <<lua_class_ByteArray,`ByteArray`>> so that it can be used in
650 display filters (e.g. "01FE456789AB"). */
651 ByteArray ba = checkByteArray(L,1);
653 if (!ba) return 0;
655 wslua_bin2hex(L, ba->data, ba->len, false, NULL);
657 WSLUA_RETURN(1); /* A hex-ascii string representation of the <<lua_class_ByteArray,`ByteArray`>>. */
660 WSLUA_METHOD ByteArray_tvb (lua_State *L) {
662 Creates a new <<lua_class_Tvb,`Tvb`>> from a <<lua_class_ByteArray,`ByteArray`>>.
663 The <<lua_class_Tvb,`Tvb`>> will be added to the current frame.
665 ===== Example
667 [source,lua]
668 ----
669 function proto_foo.dissector(buf, pinfo, tree)
670 -- Create a new tab named "My Tvb" and add some data to it
671 local b = ByteArray.new("11223344")
672 local tvb = ByteArray.tvb(b, "My Tvb")
674 -- Create a tree item that, when clicked, automatically shows the tab we just created
675 tree:add( tvb(1,2), "Foo" )
677 ----
679 #define WSLUA_ARG_ByteArray_tvb_NAME 2 /* The name to be given to the new data source. */
680 ByteArray ba = checkByteArray(L,1);
681 const char* name = luaL_optstring(L,WSLUA_ARG_ByteArray_tvb_NAME,"Unnamed") ;
682 uint8_t* data;
683 Tvb tvb;
685 if (!lua_tvb) {
686 luaL_error(L,"Tvbs can only be created and used in dissectors");
687 return 0;
690 data = (uint8_t *)g_memdup2(ba->data, ba->len);
692 tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
693 tvb->ws_tvb = tvb_new_child_real_data(lua_tvb, data, ba->len,ba->len);
694 tvb->expired = false;
695 tvb->need_free = false;
696 tvb_set_free_cb(tvb->ws_tvb, g_free);
698 add_new_data_source(lua_pinfo, tvb->ws_tvb, name);
699 push_wsluaTvb(L,tvb);
700 WSLUA_RETURN(1); /* The created <<lua_class_Tvb,`Tvb`>>. */
704 WSLUA_METHODS ByteArray_methods[] = {
705 WSLUA_CLASS_FNREG(ByteArray,new),
706 WSLUA_CLASS_FNREG(ByteArray,le_int),
707 WSLUA_CLASS_FNREG(ByteArray,le_int64),
708 WSLUA_CLASS_FNREG(ByteArray,le_uint),
709 WSLUA_CLASS_FNREG(ByteArray,le_uint64),
710 WSLUA_CLASS_FNREG(ByteArray,int),
711 WSLUA_CLASS_FNREG(ByteArray,int64),
712 WSLUA_CLASS_FNREG(ByteArray,uint),
713 WSLUA_CLASS_FNREG(ByteArray,uint64),
714 WSLUA_CLASS_FNREG(ByteArray,len),
715 WSLUA_CLASS_FNREG(ByteArray,prepend),
716 WSLUA_CLASS_FNREG(ByteArray,append),
717 WSLUA_CLASS_FNREG(ByteArray,subset),
718 WSLUA_CLASS_FNREG(ByteArray,set_size),
719 WSLUA_CLASS_FNREG(ByteArray,tvb),
720 WSLUA_CLASS_FNREG(ByteArray,base64_decode),
721 WSLUA_CLASS_FNREG(ByteArray,get_index),
722 WSLUA_CLASS_FNREG(ByteArray,set_index),
723 WSLUA_CLASS_FNREG(ByteArray,tohex),
724 WSLUA_CLASS_FNREG(ByteArray,raw),
725 { NULL, NULL }
728 WSLUA_META ByteArray_meta[] = {
729 WSLUA_CLASS_MTREG(ByteArray,tostring),
730 WSLUA_CLASS_MTREG(ByteArray,concat),
731 WSLUA_CLASS_MTREG(ByteArray,eq),
732 {"__call",ByteArray_subset},
733 { NULL, NULL }
736 int ByteArray_register(lua_State* L) {
737 WSLUA_REGISTER_CLASS(ByteArray);
738 return 0;
743 * Editor modelines - https://www.wireshark.org/tools/modelines.html
745 * Local variables:
746 * c-basic-offset: 4
747 * tab-width: 8
748 * indent-tabs-mode: nil
749 * End:
751 * vi: set shiftwidth=4 tabstop=8 expandtab:
752 * :indentSize=4:tabSize=8:noTabs=true: