diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2007-12-06 13:35:50 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2007-12-06 13:35:50 +0000 |
commit | 6934720f91c82666e6437792ffb34eaa08ea65da (patch) | |
tree | 1619cc17bb6c457685fdbebfe3ac360a0085c424 /src/minibfd | |
parent | c473b2dd5425b32b2649eadb2b61f32881e29bca (diff) |
Use a binary search to speed field lookup.
Diffstat (limited to 'src/minibfd')
-rw-r--r-- | src/minibfd/binparser.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/src/minibfd/binparser.c b/src/minibfd/binparser.c index ddd27e7..352a0b6 100644 --- a/src/minibfd/binparser.c +++ b/src/minibfd/binparser.c @@ -19,6 +19,7 @@ #include "config.h" #endif +#include <stdlib.h> #include <string.h> #include "binparser.h" @@ -33,6 +34,7 @@ struct _field { struct _bin_record { BinRecord *next; + guint size; guint n_fields; Field fields[0]; }; @@ -95,6 +97,13 @@ get_align (const BinField *field) return field->n_bytes; } +static int +field_strcmp (const void *A, const void *B) +{ + const Field *a = A, *b = B; + return strcmp (a->name, b->name); +} + BinRecord * bin_parser_create_record (BinParser *parser, const BinField *fields) { @@ -124,6 +133,12 @@ bin_parser_create_record (BinParser *parser, const BinField *fields) offset += record->fields[i].width; } + record->size = align (record->fields[n_fields-1].offset + + record->fields[n_fields-1].width, + record->fields[0].width); + + qsort (record->fields, n_fields, sizeof (Field), field_strcmp); + record->next = parser->records; parser->records = record; @@ -176,14 +191,7 @@ bin_parser_align (BinParser *parser, gsize byte_width) gsize bin_record_get_size (BinRecord *record) { - Field *last_field = &(record->fields[record->n_fields - 1]); - Field *first_field = &(record->fields[0]); - - /* align to first field, since that's the alignment of the record - * following this one - */ - - return align (last_field->offset + last_field->width, first_field->width); + return record->size; } void @@ -290,16 +298,20 @@ bin_parser_get_string (BinParser *parser) static const Field * get_field (BinRecord *format, const gchar *name) { - guint i; + guint first = 0, last = format->n_fields; + while (last - first > 1) { + gint cmp; + guint mid = (first + last) / 2; + cmp = strcmp (name, format->fields[mid].name); + if (cmp < 0) + last = mid; + else if (cmp > 0) + first = mid; + else + return &format->fields[mid]; - for (i = 0; i < format->n_fields; ++i) { - Field *field = &format->fields[i]; - - if (strcmp (field->name, name) == 0) - return field; } - - return NULL; + return &format->fields[first]; } guint64 |