summaryrefslogtreecommitdiff
path: root/src/minibfd
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2007-12-06 13:35:50 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2007-12-06 13:35:50 +0000
commit6934720f91c82666e6437792ffb34eaa08ea65da (patch)
tree1619cc17bb6c457685fdbebfe3ac360a0085c424 /src/minibfd
parentc473b2dd5425b32b2649eadb2b61f32881e29bca (diff)
Use a binary search to speed field lookup.
Diffstat (limited to 'src/minibfd')
-rw-r--r--src/minibfd/binparser.c44
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