Get rid of remaining Booleans-as-encoding-arguments in

proto_tree_add_item() calls.

Add new "add_packet_field" method to the TreeItem class, taking a
protocol field (*not* a protocol), TvbRange, and encoding value as
arguments.

Add the ENC_ values to init.lua.  Make them all hex #defines so
make-init-lua.pl can easily extract them.

Export tvb_unicode_strsize() for use by Lua (and elsewhere as desired). 
Note that it handles UTF-16 and UTF-8, and fix the comment to note that
its count of hexadectets *does* include the null terminator (that's what
the code does).

svn path=/trunk/; revision=42621
This commit is contained in:
Guy Harris 2012-05-14 00:49:05 +00:00
parent 723b213c89
commit 14b616c35d
7 changed files with 135 additions and 28 deletions

View File

@ -1183,6 +1183,7 @@ tvb_strncaseeql
tvb_strneql
tvb_strnlen
tvb_strsize
tvb_unicode_strsize
tvb_uncompress
tvbparse_casestring
tvbparse_char

View File

@ -237,8 +237,8 @@ typedef struct _protocol protocol_t;
* For backwards compatibility, we interpret an encoding of 1 as meaning
* "little-endian timespec", so that passing TRUE is interpreted as that.
*/
#define ENC_TIME_TIMESPEC 0
#define ENC_TIME_NTP 2
#define ENC_TIME_TIMESPEC 0x00000000
#define ENC_TIME_NTP 0x00000002
/*
* Historically, the only place the representation mattered for strings
@ -249,7 +249,9 @@ typedef struct _protocol protocol_t;
* values are encoded in all but the top bit (which is the byte-order
* bit, required for FT_UINT_STRING and for UCS-2 and UTF-16 strings)
* and the bottom bit (which we ignore for now so that programs that
* pass TRUE for the encoding just do ASCII).
* pass TRUE for the encoding just do ASCII). (The encodings are given
* directly as even numbers in hex, so that make-init-lua.pl can just
* turn them into numbers for use in init.lua.)
*
* We don't yet process ASCII and UTF-8 differently. Ultimately, for
* ASCII, all bytes with the 8th bit set should be mapped to some "this
@ -270,11 +272,11 @@ typedef struct _protocol protocol_t;
* caps, diagonally. (Unfortunately, those only exist for C0, not C1.)
*/
#define ENC_CHARENCODING_MASK 0x7FFFFFFE /* mask out byte-order bits */
#define ENC_ASCII (0 << 1) /* shift up to avoid low-order bit */
#define ENC_UTF_8 (1 << 1)
#define ENC_UTF_16 (2 << 1)
#define ENC_UCS_2 (3 << 1)
#define ENC_EBCDIC (4 << 1)
#define ENC_ASCII 0x00000000
#define ENC_UTF_8 0x00000002
#define ENC_UTF_16 0x00000004
#define ENC_UCS_2 0x00000006
#define ENC_EBCDIC 0x00000008
/*
* TODO:

View File

@ -2019,8 +2019,8 @@ tvb_strsize(tvbuff_t *tvb, const gint offset)
return (nul_offset - abs_offset) + 1;
}
/* Unicode (UTF-16) version of tvb_strsize */
/* Returns number of *UTF-16 characters* (not bytes) excluding the null terminator */
/* UTF-16/UCS-2 version of tvb_strsize */
/* Returns number of *16-bit units* (not bytes) including the null terminator */
guint
tvb_unicode_strsize(tvbuff_t *tvb, const gint offset)
{
@ -2035,7 +2035,7 @@ tvb_unicode_strsize(tvbuff_t *tvb, const gint offset)
i += 2;
} while(uchar != 0);
return i; /* Number of *UTF-16* characters */
return i; /* Number of *16-bit units* */
}
/* Find length of string by looking for end of string ('\0'), up to

View File

@ -393,6 +393,14 @@ extern gint tvb_pbrk_guint8(tvbuff_t *, const gint offset, const gint maxlength,
*/
extern guint tvb_strsize(tvbuff_t *tvb, const gint offset);
/** Find size of UCS-2 or UTF-16 stringz (NUL-terminated string) by
* looking for terminating 16-bit NUL. The size of the string includes
* the terminating NUL.
*
* If the NUL isn't found, it throws the appropriate exception.
*/
extern guint tvb_unicode_strsize(tvbuff_t *tvb, const gint offset);
/** Find length of string by looking for end of zero terminated string, up to
* 'maxlength' characters'; if 'maxlength' is -1, searches to end
* of tvbuff.

View File

@ -35,6 +35,7 @@ die "'$WSROOT' is not a directory" unless -d $WSROOT;
my $wtap_encaps_table = '';
my $ft_types_table = '';
my $bases_table = '';
my $encodings = '';
my $expert_pi = '';
my $menu_groups = '';
@ -42,6 +43,7 @@ my %replacements = %{{
WTAP_ENCAPS => \$wtap_encaps_table,
FT_TYPES => \$ft_types_table,
BASES => \$bases_table,
ENCODINGS => \$encodings,
EXPERT => \$expert_pi,
MENU_GROUPS => \$menu_groups,
}};
@ -58,7 +60,9 @@ $template .= $_ while(<TEMPLATE>);
close TEMPLATE;
#
# make wiretap encapusulation table
# Extract values from wiretap/wtap.h:
#
# WTAP_ENCAP_ values
#
$wtap_encaps_table = "-- Wiretap encapsulations\nwtap = {\n";
@ -74,7 +78,9 @@ while(<WTAP_H>) {
$wtap_encaps_table =~ s/,\n$/\n}\n/msi;
#
# enum fttype
# Extract values from epan/ftypes/ftypes.h:
#
# values from enum fttype
#
$ft_types_table = " -- Field Types\nftypes = {\n";
@ -92,13 +98,15 @@ close FTYPES_H;
$ft_types_table =~ s/,\n$/\n}\n/msi;
#
# enum base
# Extract values from epan/proto.h:
#
# values from enum base
# #defines for encodings and expert group and severity levels
#
$bases_table = "-- Display Bases\n base = {\n";
$encodings = "-- Encodings\n";
$expert_pi = "-- Expert flags and facilities\n";
my $base_num = 0;
@ -114,11 +122,19 @@ while(<PROTO_H>) {
my ($name, $value) = ($1, hex($2));
$expert_pi .= "$name = $value\n";
}
if ( /^.define\s+(ENC_[A-Z0-9_]+)\s+((0x)?[0-9A-Fa-f]+)/ ) {
my ($name, $value) = ($1, hex($2));
$encodings .= "$name = $value\n";
}
}
close PROTO_H;
# register_stat_group_t
#
# Extract values from stat_menu.h:
#
# MENU_X_X values for register_stat_group_t
#
$menu_groups .= "-- menu groups for register_menu\n";
my $menu_i = 0;
@ -135,6 +151,7 @@ close STAT_MENU;
$bases_table .= "}\n\n";
$encodings .= "\n\n";
$expert_pi .= "\n\n";
for my $key (keys %replacements) {

View File

@ -64,6 +64,8 @@ end
-- %BASES%
-- %ENCODINGS%
-- %EXPERT%
-- %MENU_GROUPS%

View File

@ -53,6 +53,82 @@ WSLUA_CLASS_DEFINE(TreeItem,NOP,NOP);
/* TreeItems represent information in the packet-details pane.
A root TreeItem is passed to dissectors as first argument. */
WSLUA_METHOD TreeItem_add_packet_field(lua_State *L) {
/*
Adds an child item to a given item, returning the child.
tree_item:add_packet_field([proto_field], [tvbrange], [encoding], ...)
*/
TvbRange tvbr;
ProtoField field;
int hfid;
int ett;
ftenum_t type;
TreeItem tree_item = shiftTreeItem(L,1);
guint encoding;
proto_item* item = NULL;
if (!tree_item) {
return luaL_error(L,"not a TreeItem!");
}
if (tree_item->expired) {
luaL_error(L,"expired TreeItem");
return 0;
}
if (! ( field = shiftProtoField(L,1) ) ) {
luaL_error(L,"TreeField:add_packet_field not passed a ProtoField");
return 0;
}
hfid = field->hfid;
type = field->type;
ett = field->ett;
tvbr = shiftTvbRange(L,1);
if (!tvbr) {
/* No TvbRange specified */
tvbr = ep_alloc(sizeof(struct _wslua_tvbrange));
tvbr->tvb = ep_alloc(sizeof(struct _wslua_tvb));
tvbr->tvb->ws_tvb = lua_tvb;
tvbr->offset = 0;
tvbr->len = 0;
}
encoding = (guint)luaL_checknumber(L,1);
lua_remove(L,1);
if (type == FT_STRINGZ) {
switch (encoding & ENC_CHARENCODING_MASK) {
case ENC_UTF_16:
case ENC_UCS_2:
/* tvb_unicode_strsize() returns a count of 16-bit
values; we need a count of bytes */
tvbr->len = (tvb_unicode_strsize (tvbr->tvb->ws_tvb, tvbr->offset)) * 2;
break;
default:
tvbr->len = tvb_strsize (tvbr->tvb->ws_tvb, tvbr->offset);
break;
}
}
item = proto_tree_add_item(tree_item->tree, hfid, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, encoding);
while(lua_gettop(L)) {
const gchar* s;
s = lua_tostring(L,1);
if (s) proto_item_append_text(item, " %s", s);
lua_remove(L,1);
}
tree_item = g_malloc(sizeof(struct _wslua_treeitem));
tree_item->item = item;
tree_item->tree = proto_item_add_subtree(item,ett > 0 ? ett : wslua_ett);
tree_item->expired = FALSE;
PUSH_TREEITEM(L,tree_item);
return 1;
}
static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) {
TvbRange tvbr;
Proto proto;
@ -97,7 +173,7 @@ static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) {
if (lua_gettop(L)) {
switch(type) {
case FT_PROTOCOL:
item = proto_tree_add_item(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,FALSE);
item = proto_tree_add_item(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,ENC_NA);
lua_pushnumber(L,0);
lua_insert(L,1);
break;
@ -160,7 +236,7 @@ static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) {
} else {
if (type == FT_STRINGZ) tvbr->len = tvb_strsize (tvbr->tvb->ws_tvb, tvbr->offset);
item = proto_tree_add_item(tree_item->tree, hfid, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, little_endian);
item = proto_tree_add_item(tree_item->tree, hfid, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN);
}
if ( lua_gettop(L) ) {
@ -352,15 +428,16 @@ static int TreeItem_gc(lua_State* L) {
}
static const luaL_reg TreeItem_methods[] = {
{"add", TreeItem_add},
{"add_le", TreeItem_add_le},
{"set_text", TreeItem_set_text},
{"append_text", TreeItem_append_text},
{"set_expert_flags", TreeItem_set_expert_flags},
{"add_expert_info", TreeItem_add_expert_info},
{"set_generated", TreeItem_set_generated},
{"add_packet_field", TreeItem_add_packet_field},
{"add", TreeItem_add},
{"add_le", TreeItem_add_le},
{"set_text", TreeItem_set_text},
{"append_text", TreeItem_append_text},
{"set_expert_flags", TreeItem_set_expert_flags},
{"add_expert_info", TreeItem_add_expert_info},
{"set_generated", TreeItem_set_generated},
{"set_hidden", TreeItem_set_hidden},
{"set_len", TreeItem_set_len},
{"set_len", TreeItem_set_len},
{ NULL, NULL }
};