Adds 64 bit integer handling to Lua interface.
authorrbalint <rbalint@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 16 Sep 2008 14:37:00 +0000 (14:37 +0000)
committerrbalint <rbalint@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 16 Sep 2008 14:37:00 +0000 (14:37 +0000)
Fixes bug 2750.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@26216 f5534014-38df-0310-8fa8-9805f1628bb7

epan/wslua/make-reg.pl
epan/wslua/wslua.h
epan/wslua/wslua_field.c
epan/wslua/wslua_tree.c
epan/wslua/wslua_tvb.c

index 3dc2453154ce906f87d4ebe252feab8af4ab1318..ba555900c299d6f51efe45033794a0097dba2bdd 100755 (executable)
@@ -31,8 +31,8 @@ my @classes = ();
 my @functions = ();
 
 while (<>) {
-       push @classes, $1 if /WSLUA_CLASS_DEFINE\050\s*([A-Za-z]+)/;
-       push @functions, $1 if  /WSLUA_FUNCTION\s+wslua_([a-z_]+)/;
+       push @classes, $1 if /WSLUA_CLASS_DEFINE\050\s*([A-Za-z0-9]+)/;
+       push @functions, $1 if  /WSLUA_FUNCTION\s+wslua_([a-z_0-9]+)/;
 }
 
 open C, ">register_wslua.c";
index a5fcd8739822716a4f3044ce52e906765edc3a15..726b98ac37e2cc234ced768aa1dfef1d8ebd03c4 100644 (file)
@@ -214,6 +214,8 @@ typedef struct _wslua_cols* Columns;
 typedef struct _wslua_pinfo* Pinfo;
 typedef struct _wslua_treeitem* TreeItem;
 typedef address* Address;
+typedef gint64* Int64;
+typedef guint64* UInt64;
 typedef header_field_info** Field;
 typedef field_info* FieldInfo;
 typedef struct _wslua_tap* Listener;
index ebc041ea1f575396309a4139d6349ec21625dd4d..3b8a46d8ca186fd329669a10dbd8e69f0d4434c9 100644 (file)
@@ -80,13 +80,18 @@ WSLUA_METAMETHOD FieldInfo__call(lua_State* L) {
                case FT_DOUBLE:
                        lua_pushnumber(L,(lua_Number)fvalue_get_floating(&(fi->value)));
                        return 1;
-               case FT_INT64:
-               case FT_UINT64:
-                       /*
-                        * XXX: double has 53 bits integer precision, n > 2^22 will cause a loss in precision
-                        */
-                       lua_pushnumber(L,(lua_Number)(gint64)fvalue_get_integer64(&(fi->value)));
+               case FT_INT64: {
+                       Int64 num = g_malloc(sizeof(Int64));
+                       *num = fvalue_get_integer64(&(fi->value));
+                       pushInt64(L,num);
                        return 1;
+               }
+               case FT_UINT64: {
+                       UInt64 num = g_malloc(sizeof(UInt64));
+                       *num = fvalue_get_integer64(&(fi->value));
+                       pushUInt64(L,num);
+                       return 1;
+               }
                case FT_ETHER: {
                        Address eth = g_malloc(sizeof(address));
                        eth->type = AT_ETHER;
index d67b4f722a100830b389862b21f4487e040f72f9..362327fb907ac183def435291c5de26d02371ace 100644 (file)
@@ -124,10 +124,10 @@ static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) {
                     item = proto_tree_add_bytes(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len, (const guint8*) luaL_checkstring(L,1));
                     break;
                 case FT_UINT64:
-                    item = proto_tree_add_uint64(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(guint64)luaL_checknumber(L,1));
+                    item = proto_tree_add_uint64(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,*(UInt64)checkUInt64(L,1));
                     break;
                 case FT_INT64:
-                    item = proto_tree_add_int64(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(gint64)luaL_checknumber(L,1));
+                    item = proto_tree_add_int64(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,*(Int64)checkInt64(L,1));
                     break;
                 case FT_IPv4:
                     item = proto_tree_add_ipv4(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,*((guint32*)(checkAddress(L,1)->data)));
index 5835bd9a67a582999aa4c25684764af17d3b36bf..37f9b2d9e7aecb85bd970917dc1313782f714446 100644 (file)
@@ -652,8 +652,7 @@ static int TvbRange_newindex(lua_State* L) {
  *  get a Blefuscuoan unsigned integer from a tvb
  */
 WSLUA_METHOD TvbRange_uint(lua_State* L) {
-       /* get a Big Endian (network order) unsigned integer from a TvbRange. The range must be 1, 2, 3 or 4 octets long.
-       There's no support yet for 64 bit integers*/
+       /* get a Big Endian (network order) unsigned integer from a TvbRange. The range must be 1, 2, 3 or 4 octets long. */
     TvbRange tvbr = checkTvbRange(L,1);
     if (!(tvbr && tvbr->tvb)) return 0;
     if (tvbr->tvb->expired) {
@@ -691,8 +690,7 @@ WSLUA_METHOD TvbRange_uint(lua_State* L) {
  *  get a Lilliputian unsigned integer from a tvb
  */
 WSLUA_METHOD TvbRange_le_uint(lua_State* L) {
-       /* get a Little Endian unsigned integer from a TvbRange. The range must be 1, 2, 3 or 4 octets long.
-       There's no support yet for 64 bit integers*/
+       /* get a Little Endian unsigned integer from a TvbRange. The range must be 1, 2, 3 or 4 octets long. */
     TvbRange tvbr = checkTvbRange(L,1);
     if (!(tvbr && tvbr->tvb)) return 0;
     if (tvbr->tvb->expired) {
@@ -720,6 +718,70 @@ WSLUA_METHOD TvbRange_le_uint(lua_State* L) {
     }
 }
 
+/*
+ *  get a Blefuscuoan unsigned 64 bit integer from a tvb
+ */
+WSLUA_METHOD TvbRange_uint64(lua_State* L) {
+       /* get a Big Endian (network order) unsigned 64 bit integer from a TvbRange. The range must be 1-8 octets long. */
+    TvbRange tvbr = checkTvbRange(L,1);
+    if (!(tvbr && tvbr->tvb)) return 0;
+    if (tvbr->tvb->expired) {
+        luaL_error(L,"expired tvb");
+        return 0;
+    }
+
+    switch (tvbr->len) {
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
+        case 8: {
+           UInt64 num = g_malloc(sizeof(guint64));
+           *num = tvb_get_ntoh64(tvbr->tvb->ws_tvb,tvbr->offset);
+           pushUInt64(L,num);
+            WSLUA_RETURN(1);
+        }
+        default:
+            luaL_error(L,"TvbRange:get_uint64() does not handle %d byte integers",tvbr->len);
+            return 0;
+    }
+}
+
+/*
+ *  get a Lilliputian unsigned 64 bit integer from a tvb
+ */
+WSLUA_METHOD TvbRange_le_uint64(lua_State* L) {
+       /* get a Little Endian unsigned 64 bit integer from a TvbRange. The range must be 1-8 octets long. */
+    TvbRange tvbr = checkTvbRange(L,1);
+    if (!(tvbr && tvbr->tvb)) return 0;
+    if (tvbr->tvb->expired) {
+        luaL_error(L,"expired tvb");
+        return 0;
+    }
+
+    switch (tvbr->len) {
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
+        case 8: {
+           UInt64 num = g_malloc(sizeof(guint64));
+           *num = tvb_get_ntoh64(tvbr->tvb->ws_tvb,tvbr->offset);
+           pushUInt64(L,num);
+            WSLUA_RETURN(1);
+        }
+        default:
+            luaL_error(L,"TvbRange:get_le_uint64() does not handle %d byte integers",tvbr->len);
+            return 0;
+    }
+}
+
 /*
  *  get a Blefuscuoan float
  */
@@ -900,6 +962,8 @@ WSLUA_METAMETHOD TvbRange__tostring(lua_State* L) {
 static const luaL_reg TvbRange_methods[] = {
     {"uint", TvbRange_uint},
     {"le_uint", TvbRange_le_uint},
+    {"uint64", TvbRange_uint64},
+    {"le_uint64", TvbRange_le_uint64},
     {"float", TvbRange_float},
     {"le_float", TvbRange_le_float},
     {"ether", TvbRange_ether},
@@ -924,3 +988,60 @@ int TvbRange_register(lua_State* L) {
     WSLUA_REGISTER_CLASS(TvbRange);
     return 1;
 }
+
+WSLUA_CLASS_DEFINE(Int64,NOP,NOP);
+/*
+ * Int64 represents a 64 bit integer.
+ * 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, we cannot store a 64 bit integer
+ * with full precision.
+ * For details, see: http://lua-users.org/wiki/FloatingPoint
+ */
+
+WSLUA_METAMETHOD Int64__tostring(lua_State* L) {
+       /* converts the Int64 into a string */
+    Int64 num = checkInt64(L,1);
+    lua_pushstring(L,g_strdup_printf("%ld",(long int)*(num)));
+    return 1;
+}
+
+static const luaL_reg Int64_methods[] = {
+    { NULL, NULL }
+};
+
+static const luaL_reg Int64_meta[] = {
+   {"__tostring", Int64__tostring},
+    { NULL, NULL }
+};
+
+int Int64_register(lua_State* L) {
+    WSLUA_REGISTER_CLASS(Int64);
+    return 1;
+}
+
+WSLUA_CLASS_DEFINE(UInt64,NOP,NOP);
+/*
+ * Int64 represents a 64 bit integer.
+ */
+
+WSLUA_METAMETHOD UInt64__tostring(lua_State* L) {
+       /* converts the UInt64 into a string */
+    UInt64 num = checkUInt64(L,1);
+    lua_pushstring(L,g_strdup_printf("%ld",(unsigned long int)*(num)));
+    return 1;
+}
+
+static const luaL_reg UInt64_methods[] = {
+    { NULL, NULL }
+};
+
+static const luaL_reg UInt64_meta[] = {
+    {"__tostring", UInt64__tostring},
+    { NULL, NULL }
+};
+
+int UInt64_register(lua_State* L) {
+    WSLUA_REGISTER_CLASS(UInt64);
+    return 1;
+}
+