1 /*
2 * A Lua userdata object for 64-bit signed/unsigned integers.
3 *
4 * I, Hadriel Kaplan, the author of wslua_int6464.c, wish to put it in
5 * the Public Domain. That is not universally accepted, however,
6 * so you may license it under the FreeBSD License instead, which is an open
7 * source license approved for GPL use as well as commercial etc.
8 * It's even less restrictive than the MIT license, because it requires
9 * no attribution anywhere - I don't *want* attribution.
10
11 Copyright (C) 2013 Hadriel Kaplan <hadrielk@yahoo.com>
12 All rights reserved.
13
14 SPDX-License-Identifier: BSD-2-Clause
15
16 The views and conclusions contained in the software and documentation are those
17 of the authors and should not be interpreted as representing official policies,
18 either expressed or implied, of the FreeBSD Project.
19 */
20
21 #include "config.h"
22
23 #include "wslua.h"
24
25 /*
26 WSLUA_MODULE Int64 Handling 64-bit Integers
27
28 Lua uses one single number representation which can be chosen at compile time and since it is often set to IEEE 754 double precision floating point, one cannot store 64 bit integers with full precision.
29
30 Lua numbers are stored as floating point (doubles) internally, not integers; thus while they can represent incredibly large numbers, above 2^53 they lose integral precision -- they can't represent every whole integer value.
31 For example if you set a lua variable to the number 9007199254740992 and tried to increment it by 1, you'd get the same number because it can't represent 9007199254740993 (only the even number 9007199254740994).
32
33 Therefore, in order to count higher than 2^53 in integers, we need a true integer type.
34 The way this is done is with an explicit 'Int64' or 'UInt64' object (i.e., Lua userdata).
35 This object has metamethods for all of the math and comparison operators, so you can handle it like any number variable.
36 For the math operators, it can even be mixed with plain Lua numbers.
37
38 For example 'my64num = my64num + 1' will work even if 'my64num' is a <<lua_class_Int64,`Int64`>> or <<lua_class_UInt64,`UInt64`>> object.
39 Note that comparison operators ('==','$$<=$$','>', etc.) will not work with plain numbers -- only other Int64/UInt64 objects.
40 This is a limitation of Lua itself, in terms of how it handles operator overloading.
41
42 // Previous to Wireshark release 1.11, Int64 and UInt64 could only be created by tvbrange:int64() or tvbrange:le_int64(), or tvbrange:uint64() or tvbrange:le_uint64() or tvbrange:bitfield(), and had only a couple functions (the metamethods tostring() and concat()).
43 // All of the functions on this page are only available starting in Wireshark 1.11 and higher.
44
45 [WARNING]
46 ====
47 Many of the UInt64/Int64 functions accept a Lua number as an argument.
48 You should be very careful to never use Lua numbers bigger than 32 bits (i.e., the number value 4,294,967,295 or the literal 0xFFFFFFFF) for such arguments, because Lua itself does not handle bigger numbers consistently across platforms (32-bit vs. 64-bit systems), and because a Lua number is a C-code double which cannot have more than 53 bits of precision.
49 Instead, use a Int64 or UInt64 for the argument.
50 ====
51
52 For example, do this...
53
54 [source,lua]
55 ----
56 local mynum = UInt64(0x2b89dd1e, 0x3f91df0b)
57 ----
58
59 ...instead of this:
60
61 [source,lua]
62 ----
63 -- Bad. Leads to inconsistent results across platforms
64 local mynum = UInt64(0x3f91df0b2b89dd1e)
65 ----
66
67 And do this...
68
69 [source,lua]
70 ----
71 local masked = mynum:band(UInt64(0, 0xFFFFFFFF))
72 ----
73
74 ...instead of this:
75
76 [source,lua]
77 ----
78 -- Bad. Leads to inconsistent results across platforms
79 local masked = mynum:band(0xFFFFFFFF00000000)
80 ----
81 */
82
83 #define LUATYPE64_STRING_SIZE 21 /* string to hold 18446744073709551615 */
84
85 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
86 #define IS_LITTLE_ENDIAN TRUE
87 #else
88 #define IS_LITTLE_ENDIAN FALSE
89 #endif
90
91 WSLUA_CLASS_DEFINE_BASE(Int64,NOP,0);
92 /*
93 <<lua_class_Int64,`Int64`>> represents a 64 bit signed integer.
94
95 Note the caveats <<lua_module_Int64,listed above>>.
96 */
97
98 /* A checkInt64 but that also auto-converts numbers, strings, and UINT64 to a gint64 */
getInt64(lua_State * L,int i)99 static gint64 getInt64(lua_State *L, int i)
100 {
101 gchar *end = NULL;
102 (void) end;
103 switch (lua_type(L,i))
104 {
105 case LUA_TNUMBER:
106 return wslua_checkgint64(L,i);
107 case LUA_TSTRING:
108 return g_ascii_strtoll(luaL_checkstring(L,i),&end,10);
109 case LUA_TUSERDATA:
110 if (isUInt64(L, i)) {
111 return (Int64) toUInt64(L, i);
112 }
113 /* fall through */
114 default:
115 return checkInt64(L,i);
116 }
117 }
118
119
120 /* Encodes Int64 userdata into Lua string struct with given endianness */
Int64_pack(lua_State * L,luaL_Buffer * b,gint idx,gboolean asLittleEndian)121 void Int64_pack(lua_State* L, luaL_Buffer *b, gint idx, gboolean asLittleEndian) {
122 gint64 value = checkInt64(L,idx);
123 gint8 buff[sizeof(gint64)];
124
125 if (asLittleEndian) {
126 guint i;
127 for (i = 0; i < sizeof(gint64); i++) {
128 buff[i] = (value & 0xff);
129 value >>= 8;
130 }
131 }
132 else {
133 gint i;
134 for (i = sizeof(gint64) - 1; i >= 0; i--) {
135 buff[i] = (value & 0xff);
136 value >>= 8;
137 }
138 }
139 luaL_addlstring(b, (char*)buff, sizeof(gint64));
140 }
141
Int64_encode(lua_State * L)142 WSLUA_METHOD Int64_encode(lua_State* L) {
143 /* Encodes the <<lua_class_Int64,`Int64`>> number into an 8-byte Lua string using the given endianness.
144 @since 1.11.3
145 */
146 #define WSLUA_OPTARG_Int64_encode_ENDIAN 2 /* If set to true then little-endian is used,
147 if false then big-endian; if missing or `nil`,
148 native host endian. */
149 luaL_Buffer b;
150 gboolean asLittleEndian = IS_LITTLE_ENDIAN;
151
152 if (lua_gettop(L) >= WSLUA_OPTARG_Int64_encode_ENDIAN) {
153 if (lua_type(L,WSLUA_OPTARG_Int64_encode_ENDIAN) == LUA_TBOOLEAN)
154 asLittleEndian = lua_toboolean(L,WSLUA_OPTARG_Int64_encode_ENDIAN);
155 }
156
157 luaL_buffinit(L, &b);
158
159 Int64_pack(L, &b, 1, asLittleEndian);
160
161 luaL_pushresult(&b);
162 WSLUA_RETURN(1); /* The Lua string. */
163 }
164
165 /* Decodes from string buffer struct into Int64 userdata, with given endianness */
Int64_unpack(lua_State * L,const gchar * buff,gboolean asLittleEndian)166 int Int64_unpack(lua_State* L, const gchar *buff, gboolean asLittleEndian) {
167 gint64 value = 0;
168 gint i;
169
170 if (asLittleEndian) {
171 for (i = sizeof(gint64) - 1; i >= 0; i--) {
172 value <<= 8;
173 value |= (gint64)(guchar)buff[i];
174 }
175 }
176 else {
177 for (i = 0; i < (gint) sizeof(gint64); i++) {
178 value <<= 8;
179 value |= (gint64)(guchar)buff[i];
180 }
181 }
182
183 pushInt64(L,value);
184 return 1;
185 }
186
Int64_decode(lua_State * L)187 WSLUA_CONSTRUCTOR Int64_decode(lua_State* L) {
188 /* Decodes an 8-byte Lua string, using the given endianness, into a new <<lua_class_Int64,`Int64`>> object.
189 @since 1.11.3
190 */
191 #define WSLUA_ARG_Int64_decode_STRING 1 /* The Lua string containing a binary 64-bit integer. */
192 #define WSLUA_OPTARG_Int64_decode_ENDIAN 2 /* If set to true then little-endian is used,
193 if false then big-endian; if missing or `nil`, native
194 host endian. */
195 gboolean asLittleEndian = IS_LITTLE_ENDIAN;
196 size_t len = 0;
197 const gchar *s = luaL_checklstring(L, WSLUA_ARG_Int64_decode_STRING, &len);
198
199 if (lua_gettop(L) >= WSLUA_OPTARG_Int64_decode_ENDIAN) {
200 if (lua_type(L,WSLUA_OPTARG_Int64_decode_ENDIAN) == LUA_TBOOLEAN)
201 asLittleEndian = lua_toboolean(L,WSLUA_OPTARG_Int64_decode_ENDIAN);
202 }
203
204 if (len == sizeof(gint64)) {
205 Int64_unpack(L, s, asLittleEndian);
206 } else {
207 lua_pushnil(L);
208 }
209
210 WSLUA_RETURN(1); /* The <<lua_class_Int64,`Int64`>> object created, or nil on failure. */
211 }
212
Int64_new(lua_State * L)213 WSLUA_CONSTRUCTOR Int64_new(lua_State* L) {
214 /* Creates a <<lua_class_Int64,`Int64`>> Object.
215 @since 1.11.3
216 */
217 #define WSLUA_OPTARG_Int64_new_VALUE 1 /* A number, <<lua_class_UInt64,`UInt64`>>, <<lua_class_Int64,`Int64`>>, or string of ASCII digits
218 to assign the value of the new <<lua_class_Int64,`Int64`>>. Default is 0. */
219 #define WSLUA_OPTARG_Int64_new_HIGHVALUE 2 /* If this is a number and the first argument was
220 a number, then the first will be treated as a
221 lower 32 bits, and this is the high-order 32
222 bit number. */
223 gint64 value = 0;
224
225 if (lua_gettop(L) >= 1) {
226 switch(lua_type(L, WSLUA_OPTARG_Int64_new_VALUE)) {
227 case LUA_TNUMBER:
228 value = wslua_togint64(L, WSLUA_OPTARG_Int64_new_VALUE);
229 if (lua_gettop(L) == 2 &&
230 lua_type(L, WSLUA_OPTARG_Int64_new_HIGHVALUE) == LUA_TNUMBER) {
231 gint64 h = wslua_togint64(L, WSLUA_OPTARG_Int64_new_HIGHVALUE);
232 value &= G_GUINT64_CONSTANT(0x00000000FFFFFFFF);
233 h <<= 32; h &= G_GUINT64_CONSTANT(0xFFFFFFFF00000000);
234 value += h;
235 }
236 break;
237 case LUA_TSTRING:
238 case LUA_TUSERDATA:
239 value = getInt64(L,WSLUA_OPTARG_Int64_new_VALUE);
240 break;
241 default:
242 WSLUA_OPTARG_ERROR(Int64_new,VALUE,"must be a number, UInt64, Int64, or string");
243 break;
244 }
245 }
246
247 pushInt64(L,value);
248
249 WSLUA_RETURN(1); /* The new <<lua_class_Int64,`Int64`>> object. */
250 }
251
Int64__call(lua_State * L)252 WSLUA_METAMETHOD Int64__call(lua_State* L) {
253 /* Creates a <<lua_class_Int64,`Int64`>> object.
254 @since 1.11.3
255 */
256 lua_remove(L,1); /* remove the table */
257 WSLUA_RETURN(Int64_new(L)); /* The new <<lua_class_Int64,`Int64`>> object. */
258 }
259
Int64_max(lua_State * L)260 WSLUA_CONSTRUCTOR Int64_max(lua_State* L) {
261 /* Creates an <<lua_class_Int64,`Int64`>> of the maximum possible positive value. In other words, this should return an Int64 object of the number 9,223,372,036,854,775,807.
262 @since 1.11.3
263 */
264 pushInt64(L, G_MAXINT64);
265 WSLUA_RETURN(1); /* The new <<lua_class_Int64,`Int64`>> object of the maximum value. */
266 }
267
Int64_min(lua_State * L)268 WSLUA_CONSTRUCTOR Int64_min(lua_State* L) {
269 /* Creates an <<lua_class_Int64,`Int64`>> of the minimum possible negative value. In other words, this should return an Int64 object of the number -9,223,372,036,854,775,808.
270 @since 1.11.3
271 */
272 pushInt64(L, G_MININT64);
273 WSLUA_RETURN(1); /* The new <<lua_class_Int64,`Int64`>> object of the minimum value. */
274 }
275
276
Int64_tonumber(lua_State * L)277 WSLUA_METHOD Int64_tonumber(lua_State* L) {
278 /* Returns a Lua number of the <<lua_class_Int64,`Int64`>> value. Note that this may lose precision.
279 @since 1.11.3
280 */
281 lua_pushnumber(L, (lua_Number)(checkInt64(L,1)));
282 WSLUA_RETURN(1); /* The Lua number. */
283 }
284
Int64_fromhex(lua_State * L)285 WSLUA_CONSTRUCTOR Int64_fromhex(lua_State* L) {
286 /* Creates an <<lua_class_Int64,`Int64`>> object from the given hexadecimal string.
287 @since 1.11.3
288 */
289 #define WSLUA_ARG_Int64_fromhex_HEX 1 /* The hex-ASCII Lua string. */
290 guint64 result = 0;
291 size_t len = 0;
292 const gchar *s = luaL_checklstring(L,WSLUA_ARG_Int64_fromhex_HEX,&len);
293
294 if (len > 0) {
295 if (sscanf(s, "%" G_GINT64_MODIFIER "x", &result) != 1) {
296 return luaL_error(L, "Error decoding the passed-in hex string");
297 }
298 }
299 pushInt64(L,(gint64)result);
300 WSLUA_RETURN(1); /* The new <<lua_class_Int64,`Int64`>> object. */
301 }
302
Int64_tohex(lua_State * L)303 WSLUA_METHOD Int64_tohex(lua_State* L) {
304 /* Returns a hexadecimal string of the <<lua_class_Int64,`Int64`>> value.
305 @since 1.11.3
306 */
307 #define WSLUA_OPTARG_Int64_new_NUMBYTES 2 /* The number of hex chars/nibbles to generate.
308 A negative value generates uppercase. Default is 16. */
309 gint64 b = getInt64(L,1);
310 lua_Integer n = luaL_optinteger(L, WSLUA_OPTARG_Int64_new_NUMBYTES, 16);
311 const gchar *hexdigits = "0123456789abcdef";
312 gchar buf[16];
313 lua_Integer i;
314 if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
315 if (n > 16) n = 16;
316 for (i = n-1; i >= 0; --i) { buf[i] = hexdigits[b & 15]; b >>= 4; }
317 lua_pushlstring(L, buf, (size_t)n);
318 WSLUA_RETURN(1); /* The string hex. */
319 }
320
Int64_higher(lua_State * L)321 WSLUA_METHOD Int64_higher(lua_State* L) {
322 /* Returns a Lua number of the higher 32 bits of the <<lua_class_Int64,`Int64`>> value. A negative <<lua_class_Int64,`Int64`>>
323 will return a negative Lua number.
324 @since 1.11.3
325 */
326 gint64 num = getInt64(L,1);
327 gint64 b = num;
328 lua_Number n = 0;
329 if (b < 0) b = -b; /* masking/shifting negative int64 isn't working on some platforms */
330 b &= G_GUINT64_CONSTANT(0x7FFFFFFF00000000);
331 b >>= 32;
332 n = (lua_Number)(guint32)(b & G_GUINT64_CONSTANT(0x00000000FFFFFFFFF));
333 if (num < 0) n = -n;
334 lua_pushnumber(L,n);
335 WSLUA_RETURN(1); /* The Lua number. */
336 }
337
Int64_lower(lua_State * L)338 WSLUA_METHOD Int64_lower(lua_State* L) {
339 /* Returns a Lua number of the lower 32 bits of the <<lua_class_Int64,`Int64`>> value. This will always be positive.
340 @since 1.11.3
341 */
342 gint64 b = getInt64(L,1);
343 if (b < 0) b = -b; /* masking/shifting negative int64 isn't working on some platforms */
344 lua_pushnumber(L,(guint32)(b & G_GUINT64_CONSTANT(0x00000000FFFFFFFFF)));
345 WSLUA_RETURN(1); /* The Lua number. */
346 }
347
Int64__tostring(lua_State * L)348 WSLUA_METAMETHOD Int64__tostring(lua_State* L) {
349 /* Converts the <<lua_class_Int64,`Int64`>> into a string of decimal digits. */
350 gint64 num = getInt64(L,1);
351 gchar s[LUATYPE64_STRING_SIZE];
352 if (g_snprintf(s, LUATYPE64_STRING_SIZE, "%" G_GINT64_MODIFIER "d", num) < 0) {
353 return luaL_error(L, "Error writing Int64 to a string");
354 }
355 lua_pushstring(L,s);
356 WSLUA_RETURN(1); /* The Lua string. */
357 }
358
Int64__unm(lua_State * L)359 WSLUA_METAMETHOD Int64__unm(lua_State* L) {
360 /* Returns the negative of the <<lua_class_Int64,`Int64`>> as a new <<lua_class_Int64,`Int64`>>.
361 @since 1.11.3
362 */
363 pushInt64(L,-(getInt64(L,1)));
364 WSLUA_RETURN(1); /* The new <<lua_class_Int64,`Int64`>>. */
365 }
366
367 #define WSLUA_MATH_OP_FUNC(obj,op) \
368 /* use the 'get' form so we can accept numbers as well */ \
369 obj num1 = get##obj(L,1); \
370 obj num2 = get##obj(L,2); \
371 push##obj(L,(num1) op (num2)); \
372 return 1
373
Int64__add(lua_State * L)374 WSLUA_METAMETHOD Int64__add(lua_State* L) {
375 /* Adds two <<lua_class_Int64,`Int64`>> together and returns a new one. The value may wrapped.
376 @since 1.11.3
377 */
378 WSLUA_MATH_OP_FUNC(Int64,+);
379 }
380
Int64__sub(lua_State * L)381 WSLUA_METAMETHOD Int64__sub(lua_State* L) {
382 /* Subtracts two <<lua_class_Int64,`Int64`>> and returns a new one. The value may wrapped.
383 @since 1.11.3
384 */
385 WSLUA_MATH_OP_FUNC(Int64,-);
386 }
387
Int64__mul(lua_State * L)388 WSLUA_METAMETHOD Int64__mul(lua_State* L) {
389 /* Multiplies two <<lua_class_Int64,`Int64`>> and returns a new one. The value may truncated.
390 @since 1.11.3
391 */
392 WSLUA_MATH_OP_FUNC(Int64,*);
393 }
394
Int64__div(lua_State * L)395 WSLUA_METAMETHOD Int64__div(lua_State* L) {
396 /* Divides two <<lua_class_Int64,`Int64`>> and returns a new one. Integer divide, no remainder.
397 Trying to divide by zero results in a Lua error.
398 @since 1.11.3
399 */
400 Int64 num1 = getInt64(L,1);
401 Int64 num2 = getInt64(L,2);
402 if (num2 == 0) {
403 return luaL_error(L, "Trying to divide Int64 by zero");
404 }
405 pushInt64(L, num1 / num2);
406 WSLUA_RETURN(1); /* The <<lua_class_Int64,`Int64`>> object. */
407 }
408
Int64__mod(lua_State * L)409 WSLUA_METAMETHOD Int64__mod(lua_State* L) {
410 /* Divides two <<lua_class_Int64,`Int64`>> and returns a new one of the remainder.
411 Trying to modulo by zero results in a Lua error.
412 @since 1.11.3
413 */
414 Int64 num1 = getInt64(L,1);
415 Int64 num2 = getInt64(L,2);
416 if (num2 == 0) {
417 return luaL_error(L, "Trying to modulo Int64 by zero");
418 }
419 pushInt64(L, num1 % num2);
420 WSLUA_RETURN(1); /* The <<lua_class_Int64,`Int64`>> object. */
421 }
422
Int64__pow(lua_State * L)423 WSLUA_METAMETHOD Int64__pow(lua_State* L) {
424 /* The first <<lua_class_Int64,`Int64`>> is taken to the power of the second <<lua_class_Int64,`Int64`>>, returning a new
425 one. This may truncate the value.
426 @since 1.11.3
427 */
428 gint64 num1 = getInt64(L,1);
429 gint64 num2 = getInt64(L,2);
430 gint64 result;
431 if (num1 == 2) {
432 result = (num2 >= 8 * (gint64) sizeof(gint64)) ? 0 : ((gint64)1 << num2);
433 }
434 else {
435 for (result = 1; num2 > 0; num2 >>= 1) {
436 if (num2 & 1) result *= num1;
437 num1 *= num1;
438 }
439 }
440 pushInt64(L,result);
441 WSLUA_RETURN(1); /* The <<lua_class_Int64,`Int64`>> object. */
442 }
443
444 #define WSLUA_COMP_OP_FUNC(obj,op) \
445 obj num1 = get##obj(L,1); \
446 obj num2 = get##obj(L,2); \
447 lua_pushboolean(L,(num1) op (num2)); \
448 return 1
449
Int64__eq(lua_State * L)450 WSLUA_METAMETHOD Int64__eq(lua_State* L) {
451 /* Returns `true` if both <<lua_class_Int64,`Int64`>> are equal.
452 @since 1.11.3
453 */
454 WSLUA_COMP_OP_FUNC(Int64,==);
455 }
456
Int64__lt(lua_State * L)457 WSLUA_METAMETHOD Int64__lt(lua_State* L) {
458 /* Returns `true` if first <<lua_class_Int64,`Int64`>> is less than the second.
459 @since 1.11.3
460 */
461 WSLUA_COMP_OP_FUNC(Int64,<);
462 }
463
Int64__le(lua_State * L)464 WSLUA_METAMETHOD Int64__le(lua_State* L) {
465 /* Returns `true` if the first <<lua_class_Int64,`Int64`>> is less than or equal to the second.
466 @since 1.11.3
467 */
468 WSLUA_COMP_OP_FUNC(Int64,<=);
469 }
470
Int64_bnot(lua_State * L)471 WSLUA_METHOD Int64_bnot(lua_State* L) {
472 /* Returns a <<lua_class_Int64,`Int64`>> of the bitwise 'not' operation.
473 @since 1.11.3
474 */
475 pushInt64(L,~(getInt64(L,1)));
476 WSLUA_RETURN(1); /* The <<lua_class_Int64,`Int64`>> object. */
477 }
478
479 #define WSLUA_BIT_OP_FUNC(obj,op) \
480 gint32 i; \
481 obj num = get##obj(L,1); \
482 for (i = lua_gettop(L); i > 1; i--) { \
483 num op get##obj(L,i); \
484 } \
485 push##obj(L,num); \
486 return 1
487
Int64_band(lua_State * L)488 WSLUA_METHOD Int64_band(lua_State* L) {
489 /* Returns a <<lua_class_Int64,`Int64`>> of the bitwise 'and' operation with the given number/`Int64`/`UInt64`.
490 Note that multiple arguments are allowed.
491 @since 1.11.3
492 */
493 WSLUA_BIT_OP_FUNC(Int64,&=);
494 }
495
Int64_bor(lua_State * L)496 WSLUA_METHOD Int64_bor(lua_State* L) {
497 /* Returns a <<lua_class_Int64,`Int64`>> of the bitwise 'or' operation, with the given number/`Int64`/`UInt64`.
498 Note that multiple arguments are allowed.
499 @since 1.11.3
500 */
501 WSLUA_BIT_OP_FUNC(Int64,|=);
502 }
503
Int64_bxor(lua_State * L)504 WSLUA_METHOD Int64_bxor(lua_State* L) {
505 /* Returns a <<lua_class_Int64,`Int64`>> of the bitwise 'xor' operation, with the given number/`Int64`/`UInt64`.
506 Note that multiple arguments are allowed.
507 @since 1.11.3
508 */
509 WSLUA_BIT_OP_FUNC(Int64,^=);
510 }
511
Int64_lshift(lua_State * L)512 WSLUA_METHOD Int64_lshift(lua_State* L) {
513 /* Returns a <<lua_class_Int64,`Int64`>> of the bitwise logical left-shift operation, by the given
514 number of bits.
515 @since 1.11.3
516 */
517 #define WSLUA_ARG_Int64_lshift_NUMBITS 2 /* The number of bits to left-shift by. */
518 guint64 b = (guint64) getInt64(L,1);
519 guint32 n = wslua_checkguint32(L,WSLUA_ARG_Int64_lshift_NUMBITS);
520 pushInt64(L,(gint64)(b << n));
521 WSLUA_RETURN(1); /* The <<lua_class_Int64,`Int64`>> object. */
522 }
523
Int64_rshift(lua_State * L)524 WSLUA_METHOD Int64_rshift(lua_State* L) {
525 /* Returns a <<lua_class_Int64,`Int64`>> of the bitwise logical right-shift operation, by the
526 given number of bits.
527 @since 1.11.3
528 */
529 #define WSLUA_ARG_Int64_rshift_NUMBITS 2 /* The number of bits to right-shift by. */
530 guint64 b = (guint64) getInt64(L,1);
531 guint32 n = wslua_checkguint32(L,WSLUA_ARG_Int64_rshift_NUMBITS);
532 pushInt64(L,(gint64)(b >> n));
533 WSLUA_RETURN(1); /* The <<lua_class_Int64,`Int64`>> object. */
534 }
535
Int64_arshift(lua_State * L)536 WSLUA_METHOD Int64_arshift(lua_State* L) {
537 /* Returns a <<lua_class_Int64,`Int64`>> of the bitwise arithmetic right-shift operation, by the
538 given number of bits.
539 @since 1.11.3
540 */
541 #define WSLUA_ARG_Int64_arshift_NUMBITS 2 /* The number of bits to right-shift by. */
542 gint64 b = getInt64(L,1);
543 gint32 n = wslua_checkgint32(L,WSLUA_ARG_Int64_arshift_NUMBITS);
544 pushInt64(L,(b >> n));
545 WSLUA_RETURN(1); /* The <<lua_class_Int64,`Int64`>> object. */
546 }
547
Int64_rol(lua_State * L)548 WSLUA_METHOD Int64_rol(lua_State* L) {
549 /* Returns a <<lua_class_Int64,`Int64`>> of the bitwise left rotation operation, by the given number of
550 bits (up to 63).
551 @since 1.11.3
552 */
553 #define WSLUA_ARG_Int64_rol_NUMBITS 2 /* The number of bits to roll left by. */
554 guint64 b = (guint64) getInt64(L,1);
555 guint32 n = wslua_checkguint32(L,WSLUA_ARG_Int64_rol_NUMBITS);
556 pushInt64(L,(gint64)((b << n) | (b >> (64-n))));
557 WSLUA_RETURN(1); /* The <<lua_class_Int64,`Int64`>> object. */
558 }
559
Int64_ror(lua_State * L)560 WSLUA_METHOD Int64_ror(lua_State* L) {
561 /* Returns a <<lua_class_Int64,`Int64`>> of the bitwise right rotation operation, by the given number of
562 bits (up to 63).
563 @since 1.11.3
564 */
565 #define WSLUA_ARG_Int64_ror_NUMBITS 2 /* The number of bits to roll right by. */
566 guint64 b = (guint64) getInt64(L,1);
567 guint32 n = wslua_checkguint32(L,WSLUA_ARG_Int64_ror_NUMBITS);
568 pushInt64(L,(gint64)((b << (64-n)) | (b >> n)));
569 WSLUA_RETURN(1); /* The <<lua_class_Int64,`Int64`>> object. */
570 }
571
Int64_bswap(lua_State * L)572 WSLUA_METHOD Int64_bswap(lua_State* L) {
573 /* Returns a <<lua_class_Int64,`Int64`>> of the bytes swapped. This can be used to convert little-endian
574 64-bit numbers to big-endian 64 bit numbers or vice versa.
575 @since 1.11.3
576 */
577 guint64 b = (guint64) getInt64(L,1);
578 guint64 result = 0;
579 size_t i;
580 for (i = 0; i < sizeof(gint64); i++) {
581 result <<= 8;
582 result |= (b & G_GUINT64_CONSTANT(0x00000000000000FF));
583 b >>= 8;
584 }
585 pushInt64(L,(gint64)result);
586 WSLUA_RETURN(1); /* The <<lua_class_Int64,`Int64`>> object. */
587 }
588
589 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META. */
Int64__gc(lua_State * L _U_)590 static int Int64__gc(lua_State* L _U_) {
591 return 0;
592 }
593
594 WSLUA_METHODS Int64_methods[] = {
595 WSLUA_CLASS_FNREG(Int64,new),
596 WSLUA_CLASS_FNREG(Int64,max),
597 WSLUA_CLASS_FNREG(Int64,min),
598 WSLUA_CLASS_FNREG(Int64,tonumber),
599 WSLUA_CLASS_FNREG(Int64,fromhex),
600 WSLUA_CLASS_FNREG(Int64,tohex),
601 WSLUA_CLASS_FNREG(Int64,higher),
602 WSLUA_CLASS_FNREG(Int64,lower),
603 WSLUA_CLASS_FNREG(Int64,encode),
604 WSLUA_CLASS_FNREG(Int64,decode),
605 WSLUA_CLASS_FNREG(Int64,bnot),
606 WSLUA_CLASS_FNREG(Int64,band),
607 WSLUA_CLASS_FNREG(Int64,bor),
608 WSLUA_CLASS_FNREG(Int64,bxor),
609 WSLUA_CLASS_FNREG(Int64,lshift),
610 WSLUA_CLASS_FNREG(Int64,rshift),
611 WSLUA_CLASS_FNREG(Int64,arshift),
612 WSLUA_CLASS_FNREG(Int64,rol),
613 WSLUA_CLASS_FNREG(Int64,ror),
614 WSLUA_CLASS_FNREG(Int64,bswap),
615 { NULL, NULL }
616 };
617
618 WSLUA_META Int64_meta[] = {
619 WSLUA_CLASS_MTREG(Int64,tostring),
620 WSLUA_CLASS_MTREG(Int64,call),
621 WSLUA_CLASS_MTREG(wslua,concat),
622 WSLUA_CLASS_MTREG(Int64,unm),
623 WSLUA_CLASS_MTREG(Int64,add),
624 WSLUA_CLASS_MTREG(Int64,sub),
625 WSLUA_CLASS_MTREG(Int64,mul),
626 WSLUA_CLASS_MTREG(Int64,div),
627 WSLUA_CLASS_MTREG(Int64,mod),
628 WSLUA_CLASS_MTREG(Int64,pow),
629 WSLUA_CLASS_MTREG(Int64,eq),
630 WSLUA_CLASS_MTREG(Int64,lt),
631 WSLUA_CLASS_MTREG(Int64,le),
632 { NULL, NULL }
633 };
634
Int64_register(lua_State * L)635 LUALIB_API int Int64_register(lua_State* L) {
636 WSLUA_REGISTER_CLASS(Int64);
637 return 0;
638 }
639
640
641
642 WSLUA_CLASS_DEFINE_BASE(UInt64,NOP,0);
643 /*
644 <<lua_class_UInt64,`UInt64`>> represents a 64 bit unsigned integer, similar to <<lua_class_Int64,`Int64`>>.
645
646 Note the caveats <<lua_module_Int64,listed above>>.
647 */
648
649 /* A checkUInt64 but that also auto-converts numbers, strings, and <<lua_class_Int64,`Int64`>> to a guint64. */
getUInt64(lua_State * L,int i)650 static guint64 getUInt64(lua_State *L, int i)
651 {
652 gchar *end = NULL;
653 (void) end;
654 switch (lua_type(L,i))
655 {
656 case LUA_TNUMBER:
657 return wslua_checkguint64(L,i);
658 case LUA_TSTRING:
659 return g_ascii_strtoull(luaL_checkstring(L,i), &end, 10);
660 case LUA_TUSERDATA:
661 if (isInt64(L, i)) {
662 return (UInt64) toInt64(L, i);
663 }
664 /* fall through */
665 default:
666 return checkUInt64(L,i);
667 }
668 }
669
670 /* Encodes <<lua_class_UInt64,`UInt64`>> userdata into Lua string struct with given endianness */
UInt64_pack(lua_State * L,luaL_Buffer * b,gint idx,gboolean asLittleEndian)671 void UInt64_pack(lua_State* L, luaL_Buffer *b, gint idx, gboolean asLittleEndian) {
672 guint64 value = checkUInt64(L,idx);
673 gint8 buff[sizeof(guint64)];
674
675 if (asLittleEndian) {
676 guint i;
677 for (i = 0; i < sizeof(guint64); i++) {
678 buff[i] = (value & 0xff);
679 value >>= 8;
680 }
681 }
682 else {
683 gint i;
684 for (i = sizeof(guint64) - 1; i >= 0; i--) {
685 buff[i] = (value & 0xff);
686 value >>= 8;
687 }
688 }
689 luaL_addlstring(b, (char*)buff, sizeof(guint64));
690 }
691
UInt64_encode(lua_State * L)692 WSLUA_METHOD UInt64_encode(lua_State* L) {
693 /* Encodes the <<lua_class_UInt64,`UInt64`>> number into an 8-byte Lua binary string, using given endianness.
694 @since 1.11.3
695 */
696 #define WSLUA_OPTARG_UInt64_encode_ENDIAN 2 /* If set to true then little-endian is used,
697 if false then big-endian; if missing or `nil`,
698 native host endian. */
699 luaL_Buffer b;
700 gboolean asLittleEndian = IS_LITTLE_ENDIAN;
701
702 if (lua_gettop(L) >= 2) {
703 if (lua_type(L,2) == LUA_TBOOLEAN)
704 asLittleEndian = lua_toboolean(L,2);
705 }
706
707 luaL_buffinit(L, &b);
708
709 UInt64_pack(L, &b, 1, asLittleEndian);
710
711 luaL_pushresult(&b);
712 WSLUA_RETURN(1); /* The Lua binary string. */
713 }
714
715 /* Decodes from string buffer struct into <<lua_class_UInt64,`UInt64`>> userdata, with given endianness. */
UInt64_unpack(lua_State * L,const gchar * buff,gboolean asLittleEndian)716 int UInt64_unpack(lua_State* L, const gchar *buff, gboolean asLittleEndian) {
717 guint64 value = 0;
718 gint i;
719
720 if (asLittleEndian) {
721 for (i = sizeof(guint64) - 1; i >= 0; i--) {
722 value <<= 8;
723 value |= (guint64)(guchar)buff[i];
724 }
725 }
726 else {
727 for (i = 0; i < (gint) sizeof(guint64); i++) {
728 value <<= 8;
729 value |= (guint64)(guchar)buff[i];
730 }
731 }
732
733 pushUInt64(L,value);
734 return 1;
735 }
736
UInt64_decode(lua_State * L)737 WSLUA_CONSTRUCTOR UInt64_decode(lua_State* L) {
738 /* Decodes an 8-byte Lua binary string, using given endianness, into a new <<lua_class_UInt64,`UInt64`>> object.
739 @since 1.11.3
740 */
741 #define WSLUA_ARG_UInt64_decode_STRING 1 /* The Lua string containing a binary 64-bit integer. */
742 #define WSLUA_OPTARG_UInt64_decode_ENDIAN 2 /* If set to true then little-endian is used,
743 if false then big-endian; if missing or `nil`,
744 native host endian. */
745 gboolean asLittleEndian = IS_LITTLE_ENDIAN;
746 size_t len = 0;
747 const gchar *s = luaL_checklstring(L, WSLUA_ARG_UInt64_decode_STRING, &len);
748
749 if (lua_gettop(L) >= WSLUA_OPTARG_UInt64_decode_ENDIAN) {
750 if (lua_type(L,WSLUA_OPTARG_UInt64_decode_ENDIAN) == LUA_TBOOLEAN)
751 asLittleEndian = lua_toboolean(L,WSLUA_OPTARG_UInt64_decode_ENDIAN);
752 }
753
754 if (len == sizeof(guint64)) {
755 UInt64_unpack(L, s, asLittleEndian);
756 } else {
757 lua_pushnil(L);
758 }
759
760 WSLUA_RETURN(1); /* The <<lua_class_UInt64,`UInt64`>> object created, or nil on failure. */
761 }
762
UInt64_new(lua_State * L)763 WSLUA_CONSTRUCTOR UInt64_new(lua_State* L) {
764 /* Creates a <<lua_class_UInt64,`UInt64`>> Object.
765 @since 1.11.3
766 */
767 #define WSLUA_OPTARG_UInt64_new_VALUE 1 /* A number, <<lua_class_UInt64,`UInt64`>>, <<lua_class_Int64,`Int64`>>, or string of digits
768 to assign the value of the new <<lua_class_UInt64,`UInt64`>>. Default is 0. */
769 #define WSLUA_OPTARG_UInt64_new_HIGHVALUE 2 /* If this is a number and the first argument was
770 a number, then the first will be treated as a
771 lower 32 bits, and this is the high-order
772 32-bit number. */
773 guint64 value = 0;
774
775 if (lua_gettop(L) >= 1) {
776 switch(lua_type(L, WSLUA_OPTARG_UInt64_new_VALUE)) {
777 case LUA_TNUMBER:
778 value = wslua_toguint64(L, WSLUA_OPTARG_UInt64_new_VALUE);
779 if (lua_gettop(L) == 2 &&
780 lua_type(L, WSLUA_OPTARG_UInt64_new_HIGHVALUE) == LUA_TNUMBER) {
781 guint64 h = wslua_toguint64(L, WSLUA_OPTARG_UInt64_new_HIGHVALUE);
782 value &= G_GUINT64_CONSTANT(0x00000000FFFFFFFF);
783 h <<= 32; h &= G_GUINT64_CONSTANT(0xFFFFFFFF00000000);
784 value += h;
785 }
786 break;
787 case LUA_TSTRING:
788 case LUA_TUSERDATA:
789 value = getUInt64(L, WSLUA_OPTARG_UInt64_new_VALUE);
790 break;
791 default:
792 WSLUA_OPTARG_ERROR(UInt64_new,VALUE,"must be a number, UInt64, Int64, or string");
793 break;
794 }
795 }
796
797 pushUInt64(L,value);
798
799 WSLUA_RETURN(1); /* The new <<lua_class_UInt64,`UInt64`>> object. */
800 }
801
UInt64__call(lua_State * L)802 WSLUA_METAMETHOD UInt64__call(lua_State* L) {
803 /* Creates a <<lua_class_UInt64,`UInt64`>> object.
804 @since 1.11.3
805 */
806 lua_remove(L,1); /* remove the table */
807 WSLUA_RETURN(UInt64_new(L)); /* The new <<lua_class_UInt64,`UInt64`>> object. */
808 }
809
UInt64_max(lua_State * L)810 WSLUA_CONSTRUCTOR UInt64_max(lua_State* L) {
811 /* Creates a <<lua_class_UInt64,`UInt64`>> of the maximum possible value. In other words, this should return an UInt64 object of the number 18,446,744,073,709,551,615.
812 @since 1.11.3
813 */
814 pushUInt64(L,G_MAXUINT64);
815 WSLUA_RETURN(1); /* The maximum value. */
816 }
817
UInt64_min(lua_State * L)818 WSLUA_CONSTRUCTOR UInt64_min(lua_State* L) {
819 /* Creates a <<lua_class_UInt64,`UInt64`>> of the minimum possible value. In other words, this should return an UInt64 object of the number 0.
820 @since 1.11.3
821 */
822 pushUInt64(L,0);
823 WSLUA_RETURN(1); /* The minimum value. */
824 }
825
UInt64_tonumber(lua_State * L)826 WSLUA_METHOD UInt64_tonumber(lua_State* L) {
827 /* Returns a Lua number of the <<lua_class_UInt64,`UInt64`>> value. This may lose precision.
828 @since 1.11.3
829 */
830 lua_pushnumber(L,(lua_Number)(checkUInt64(L,1)));
831 WSLUA_RETURN(1); /* The Lua number. */
832 }
833
UInt64__tostring(lua_State * L)834 WSLUA_METAMETHOD UInt64__tostring(lua_State* L) {
835 /* Converts the <<lua_class_UInt64,`UInt64`>> into a string. */
836 guint64 num = getUInt64(L,1);
837 gchar s[LUATYPE64_STRING_SIZE];
838 if (g_snprintf(s, LUATYPE64_STRING_SIZE, "%" G_GINT64_MODIFIER "u",(guint64)num) < 0) {
839 return luaL_error(L, "Error writing UInt64 to a string");
840 }
841 lua_pushstring(L,s);
842 WSLUA_RETURN(1); /* The Lua string. */
843 }
844
UInt64_fromhex(lua_State * L)845 WSLUA_CONSTRUCTOR UInt64_fromhex(lua_State* L) {
846 /* Creates a <<lua_class_UInt64,`UInt64`>> object from the given hex string.
847 @since 1.11.3
848 */
849 #define WSLUA_ARG_UInt64_fromhex_HEX 1 /* The hex-ASCII Lua string. */
850 guint64 result = 0;
851 size_t len = 0;
852 const gchar *s = luaL_checklstring(L,WSLUA_ARG_UInt64_fromhex_HEX,&len);
853
854 if (len > 0) {
855 if (sscanf(s, "%" G_GINT64_MODIFIER "x", &result) != 1) {
856 return luaL_error(L, "Error decoding the passed-in hex string");
857 }
858 }
859 pushUInt64(L,result);
860 WSLUA_RETURN(1); /* The new <<lua_class_UInt64,`UInt64`>> object. */
861 }
862
UInt64_tohex(lua_State * L)863 WSLUA_METHOD UInt64_tohex(lua_State* L) {
864 /* Returns a hex string of the <<lua_class_UInt64,`UInt64`>> value.
865 @since 1.11.3
866 */
867 #define WSLUA_OPTARG_UInt64_new_NUMBYTES 2 /* The number of hex-chars/nibbles to generate.
868 Negative means uppercase Default is 16. */
869 guint64 b = getUInt64(L,1);
870 lua_Integer n = luaL_optinteger(L, WSLUA_OPTARG_UInt64_new_NUMBYTES, 16);
871 const gchar *hexdigits = "0123456789abcdef";
872 gchar buf[16];
873 lua_Integer i;
874 if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
875 if (n > 16) n = 16;
876 for (i = n-1; i >= 0; --i) { buf[i] = hexdigits[b & 15]; b >>= 4; }
877 lua_pushlstring(L, buf, (size_t)n);
878 WSLUA_RETURN(1); /* The string hex. */
879 }
880
UInt64_higher(lua_State * L)881 WSLUA_METHOD UInt64_higher(lua_State* L) {
882 /* Returns a Lua number of the higher 32 bits of the <<lua_class_UInt64,`UInt64`>> value. */
883 guint64 num = getUInt64(L,1);
884 guint64 b = num;
885 lua_Number n = 0;
886 b &= G_GUINT64_CONSTANT(0xFFFFFFFF00000000);
887 b >>= 32;
888 n = (lua_Number)(guint32)(b & G_GUINT64_CONSTANT(0x00000000FFFFFFFFF));
889 lua_pushnumber(L,n);
890 WSLUA_RETURN(1); /* The Lua number. */
891 }
892
UInt64_lower(lua_State * L)893 WSLUA_METHOD UInt64_lower(lua_State* L) {
894 /* Returns a Lua number of the lower 32 bits of the <<lua_class_UInt64,`UInt64`>> value. */
895 guint64 b = getUInt64(L,1);
896 lua_pushnumber(L,(guint32)(b & G_GUINT64_CONSTANT(0x00000000FFFFFFFFF)));
897 WSLUA_RETURN(1); /* The Lua number. */
898 }
899
UInt64__unm(lua_State * L)900 WSLUA_METAMETHOD UInt64__unm(lua_State* L) {
901 /* Returns the <<lua_class_UInt64,`UInt64`>> in a new <<lua_class_UInt64,`UInt64`>>, since unsigned integers can't be negated.
902 @since 1.11.3
903 */
904 pushUInt64(L,getUInt64(L,1));
905 WSLUA_RETURN(1); /* The <<lua_class_UInt64,`UInt64`>> object. */
906 }
907
UInt64__add(lua_State * L)908 WSLUA_METAMETHOD UInt64__add(lua_State* L) {
909 /* Adds two <<lua_class_UInt64,`UInt64`>> together and returns a new one. This may wrap the value.
910 @since 1.11.3
911 */
912 WSLUA_MATH_OP_FUNC(UInt64,+);
913 }
914
UInt64__sub(lua_State * L)915 WSLUA_METAMETHOD UInt64__sub(lua_State* L) {
916 /* Subtracts two <<lua_class_UInt64,`UInt64`>> and returns a new one. This may wrap the value.
917 @since 1.11.3
918 */
919 WSLUA_MATH_OP_FUNC(UInt64,-);
920 }
921
UInt64__mul(lua_State * L)922 WSLUA_METAMETHOD UInt64__mul(lua_State* L) {
923 /* Multiplies two <<lua_class_UInt64,`UInt64`>> and returns a new one. This may truncate the value.
924 @since 1.11.3
925 */
926 WSLUA_MATH_OP_FUNC(UInt64,*);
927 }
928
UInt64__div(lua_State * L)929 WSLUA_METAMETHOD UInt64__div(lua_State* L) {
930 /* Divides two <<lua_class_UInt64,`UInt64`>> and returns a new one. Integer divide, no remainder.
931 Trying to divide by zero results in a Lua error.
932 @since 1.11.3
933 */
934 UInt64 num1 = getUInt64(L,1);
935 UInt64 num2 = getUInt64(L,2);
936 if (num2 == 0) {
937 return luaL_error(L, "Trying to divide UInt64 by zero");
938 }
939 pushUInt64(L, num1 / num2);
940 WSLUA_RETURN(1); /* The <<lua_class_UInt64,`UInt64`>> result. */
941 }
942
UInt64__mod(lua_State * L)943 WSLUA_METAMETHOD UInt64__mod(lua_State* L) {
944 /* Divides two <<lua_class_UInt64,`UInt64`>> and returns a new one of the remainder.
945 Trying to modulo by zero results in a Lua error.
946 @since 1.11.3
947 */
948 UInt64 num1 = getUInt64(L,1);
949 UInt64 num2 = getUInt64(L,2);
950 if (num2 == 0) {
951 return luaL_error(L, "Trying to modulo UInt64 by zero");
952 }
953 pushUInt64(L, num1 % num2);
954 WSLUA_RETURN(1); /* The <<lua_class_UInt64,`UInt64`>> result. */
955 }
956
UInt64__pow(lua_State * L)957 WSLUA_METAMETHOD UInt64__pow(lua_State* L) {
958 /* The first <<lua_class_UInt64,`UInt64`>> is taken to the power of the second <<lua_class_UInt64,`UInt64`>>/number,
959 returning a new one. This may truncate the value.
960 @since 1.11.3
961 */
962 guint64 num1 = getUInt64(L,1);
963 guint64 num2 = getUInt64(L,2);
964 guint64 result;
965 if (num1 == 2) {
966 result = (num2 >= 8 * (guint64) sizeof(guint64)) ? 0 : ((guint64)1 << num2);
967 }
968 else {
969 for (result = 1; num2 > 0; num2 >>= 1) {
970 if (num2 & 1) result *= num1;
971 num1 *= num1;
972 }
973 }
974 pushUInt64(L,result);
975 WSLUA_RETURN(1); /* The <<lua_class_UInt64,`UInt64`>> object. */
976 }
977
UInt64__eq(lua_State * L)978 WSLUA_METAMETHOD UInt64__eq(lua_State* L) {
979 /* Returns true if both <<lua_class_UInt64,`UInt64`>> are equal.
980 @since 1.11.3
981 */
982 WSLUA_COMP_OP_FUNC(UInt64,==);
983 }
984
UInt64__lt(lua_State * L)985 WSLUA_METAMETHOD UInt64__lt(lua_State* L) {
986 /* Returns true if first <<lua_class_UInt64,`UInt64`>> is less than the second.
987 @since 1.11.3
988 */
989 WSLUA_COMP_OP_FUNC(UInt64,<);
990 }
991
UInt64__le(lua_State * L)992 WSLUA_METAMETHOD UInt64__le(lua_State* L) {
993 /* Returns true if first <<lua_class_UInt64,`UInt64`>> is less than or equal to the second.
994 @since 1.11.3
995 */
996 WSLUA_COMP_OP_FUNC(UInt64,<=);
997 }
998
UInt64_bnot(lua_State * L)999 WSLUA_METHOD UInt64_bnot(lua_State* L) {
1000 /* Returns a <<lua_class_UInt64,`UInt64`>> of the bitwise 'not' operation.
1001 @since 1.11.3
1002 */
1003 pushUInt64(L,~(getUInt64(L,1)));
1004 WSLUA_RETURN(1); /* The <<lua_class_UInt64,`UInt64`>> object. */
1005 }
1006
UInt64_band(lua_State * L)1007 WSLUA_METHOD UInt64_band(lua_State* L) {
1008 /* Returns a <<lua_class_UInt64,`UInt64`>> of the bitwise 'and' operation, with the given number/`Int64`/`UInt64`.
1009 Note that multiple arguments are allowed.
1010 @since 1.11.3
1011 */
1012 WSLUA_BIT_OP_FUNC(UInt64,&=);
1013 }
1014
UInt64_bor(lua_State * L)1015 WSLUA_METHOD UInt64_bor(lua_State* L) {
1016 /* Returns a <<lua_class_UInt64,`UInt64`>> of the bitwise 'or' operation, with the given number/`Int64`/`UInt64`.
1017 Note that multiple arguments are allowed.
1018 @since 1.11.3
1019 */
1020 WSLUA_BIT_OP_FUNC(UInt64,|=);
1021 }
1022
UInt64_bxor(lua_State * L)1023 WSLUA_METHOD UInt64_bxor(lua_State* L) {
1024 /* Returns a <<lua_class_UInt64,`UInt64`>> of the bitwise 'xor' operation, with the given number/`Int64`/`UInt64`.
1025 Note that multiple arguments are allowed.
1026 @since 1.11.3
1027 */
1028 WSLUA_BIT_OP_FUNC(UInt64,^=);
1029 }
1030
UInt64_lshift(lua_State * L)1031 WSLUA_METHOD UInt64_lshift(lua_State* L) {
1032 /* Returns a <<lua_class_UInt64,`UInt64`>> of the bitwise logical left-shift operation, by the
1033 given number of bits.
1034 @since 1.11.3
1035 */
1036 #define WSLUA_ARG_UInt64_lshift_NUMBITS 2 /* The number of bits to left-shift by. */
1037 guint64 b = getUInt64(L,1);
1038 guint32 n = wslua_checkguint32(L,WSLUA_ARG_UInt64_lshift_NUMBITS);
1039 pushUInt64(L,(b << n));
1040 WSLUA_RETURN(1); /* The <<lua_class_UInt64,`UInt64`>> object. */
1041 }
1042
UInt64_rshift(lua_State * L)1043 WSLUA_METHOD UInt64_rshift(lua_State* L) {
1044 /* Returns a <<lua_class_UInt64,`UInt64`>> of the bitwise logical right-shift operation, by the
1045 given number of bits.
1046 @since 1.11.3
1047 */
1048 #define WSLUA_ARG_UInt64_rshift_NUMBITS 2 /* The number of bits to right-shift by. */
1049 guint64 b = getUInt64(L,1);
1050 guint32 n = wslua_checkguint32(L,WSLUA_ARG_UInt64_rshift_NUMBITS);
1051 pushUInt64(L,(b >> n));
1052 WSLUA_RETURN(1); /* The <<lua_class_UInt64,`UInt64`>> object. */
1053 }
1054
UInt64_arshift(lua_State * L)1055 WSLUA_METHOD UInt64_arshift(lua_State* L) {
1056 /* Returns a <<lua_class_UInt64,`UInt64`>> of the bitwise arithmetic right-shift operation, by the
1057 given number of bits.
1058 @since 1.11.3
1059 */
1060 #define WSLUA_ARG_UInt64_arshift_NUMBITS 2 /* The number of bits to right-shift by. */
1061 guint64 b = getUInt64(L,1);
1062 guint32 n = wslua_checkguint32(L,WSLUA_ARG_UInt64_arshift_NUMBITS);
1063 pushUInt64(L,(b >> n));
1064 WSLUA_RETURN(1); /* The <<lua_class_UInt64,`UInt64`>> object. */
1065 }
1066
UInt64_rol(lua_State * L)1067 WSLUA_METHOD UInt64_rol(lua_State* L) {
1068 /* Returns a <<lua_class_UInt64,`UInt64`>> of the bitwise left rotation operation, by the
1069 given number of bits (up to 63).
1070 @since 1.11.3
1071 */
1072 #define WSLUA_ARG_UInt64_rol_NUMBITS 2 /* The number of bits to roll left by. */
1073 guint64 b = getUInt64(L,1);
1074 guint32 n = wslua_checkguint32(L,WSLUA_ARG_UInt64_rol_NUMBITS);
1075 pushUInt64(L,((b << n) | (b >> (64-n))));
1076 WSLUA_RETURN(1); /* The <<lua_class_UInt64,`UInt64`>> object. */
1077 }
1078
UInt64_ror(lua_State * L)1079 WSLUA_METHOD UInt64_ror(lua_State* L) {
1080 /* Returns a <<lua_class_UInt64,`UInt64`>> of the bitwise right rotation operation, by the
1081 given number of bits (up to 63).
1082 @since 1.11.3
1083 */
1084 #define WSLUA_ARG_UInt64_ror_NUMBITS 2 /* The number of bits to roll right by. */
1085 guint64 b = getUInt64(L,1);
1086 guint32 n = wslua_checkguint32(L,WSLUA_ARG_UInt64_ror_NUMBITS);
1087 pushUInt64(L,((b << (64-n)) | (b >> n)));
1088 WSLUA_RETURN(1); /* The <<lua_class_UInt64,`UInt64`>> object. */
1089 }
1090
UInt64_bswap(lua_State * L)1091 WSLUA_METHOD UInt64_bswap(lua_State* L) {
1092 /* Returns a <<lua_class_UInt64,`UInt64`>> of the bytes swapped. This can be used to convert little-endian
1093 64-bit numbers to big-endian 64 bit numbers or vice versa.
1094 @since 1.11.3
1095 */
1096 guint64 b = getUInt64(L,1);
1097 guint64 result = 0;
1098 size_t i;
1099 for (i = 0; i < sizeof(guint64); i++) {
1100 result <<= 8;
1101 result |= (b & G_GUINT64_CONSTANT(0x00000000000000FF));
1102 b >>= 8;
1103 }
1104 pushUInt64(L,result);
1105 WSLUA_RETURN(1); /* The <<lua_class_UInt64,`UInt64`>> object. */
1106 }
1107
1108 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
UInt64__gc(lua_State * L _U_)1109 static int UInt64__gc(lua_State* L _U_) {
1110 return 0;
1111 }
1112
1113 WSLUA_METHODS UInt64_methods[] = {
1114 WSLUA_CLASS_FNREG(UInt64,new),
1115 WSLUA_CLASS_FNREG(UInt64,max),
1116 WSLUA_CLASS_FNREG(UInt64,min),
1117 WSLUA_CLASS_FNREG(UInt64,tonumber),
1118 WSLUA_CLASS_FNREG(UInt64,fromhex),
1119 WSLUA_CLASS_FNREG(UInt64,tohex),
1120 WSLUA_CLASS_FNREG(UInt64,higher),
1121 WSLUA_CLASS_FNREG(UInt64,lower),
1122 WSLUA_CLASS_FNREG(UInt64,encode),
1123 WSLUA_CLASS_FNREG(UInt64,decode),
1124 WSLUA_CLASS_FNREG(UInt64,bnot),
1125 WSLUA_CLASS_FNREG(UInt64,band),
1126 WSLUA_CLASS_FNREG(UInt64,bor),
1127 WSLUA_CLASS_FNREG(UInt64,bxor),
1128 WSLUA_CLASS_FNREG(UInt64,lshift),
1129 WSLUA_CLASS_FNREG(UInt64,rshift),
1130 WSLUA_CLASS_FNREG(UInt64,arshift),
1131 WSLUA_CLASS_FNREG(UInt64,rol),
1132 WSLUA_CLASS_FNREG(UInt64,ror),
1133 WSLUA_CLASS_FNREG(UInt64,bswap),
1134 { NULL, NULL }
1135 };
1136
1137 WSLUA_META UInt64_meta[] = {
1138 WSLUA_CLASS_MTREG(UInt64,tostring),
1139 WSLUA_CLASS_MTREG(UInt64,call),
1140 WSLUA_CLASS_MTREG(wslua,concat),
1141 WSLUA_CLASS_MTREG(UInt64,unm),
1142 WSLUA_CLASS_MTREG(UInt64,add),
1143 WSLUA_CLASS_MTREG(UInt64,sub),
1144 WSLUA_CLASS_MTREG(UInt64,mul),
1145 WSLUA_CLASS_MTREG(UInt64,div),
1146 WSLUA_CLASS_MTREG(UInt64,mod),
1147 WSLUA_CLASS_MTREG(UInt64,pow),
1148 WSLUA_CLASS_MTREG(UInt64,eq),
1149 WSLUA_CLASS_MTREG(UInt64,lt),
1150 WSLUA_CLASS_MTREG(UInt64,le),
1151 { NULL, NULL }
1152 };
1153
UInt64_register(lua_State * L)1154 LUALIB_API int UInt64_register(lua_State* L) {
1155 WSLUA_REGISTER_CLASS(UInt64);
1156 return 0;
1157 }
1158
1159 /*
1160 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1161 *
1162 * Local variables:
1163 * c-basic-offset: 4
1164 * tab-width: 8
1165 * indent-tabs-mode: nil
1166 * End:
1167 *
1168 * vi: set shiftwidth=4 tabstop=8 expandtab:
1169 * :indentSize=4:tabSize=8:noTabs=true:
1170 */
1171