ParserFrame * next;
};
+struct BinRecord
+{
+ BinFormat * format;
+ int index;
+ gsize offset;
+ BinParser * parser;
+};
+
struct BinField
{
guint64 offset;
}
guint64
-bin_parser_get_uint (BinParser *parser,
- const gchar *name)
+convert_uint (const guchar *data,
+ gboolean big_endian,
+ int width)
{
- const BinField *field;
- const guint8 *pos;
guint8 r8;
guint16 r16;
guint32 r32;
guint64 r64;
- BinFormat *format;
- const guchar *data;
-
- g_return_val_if_fail (parser->frame != NULL, 0);
-
- format = parser->frame->format;
- data = parser->data + parser->frame->offset;
-
- field = get_field (format, name);
-
- g_return_val_if_fail (field != NULL, (guint64)-1);
-
- pos = data + field->offset;
- if (field->offset + field->width > parser->length)
- {
- /* FIXME: generate error */
- return 0;
- }
-
-#if 0
- g_print ("getting %s from offset: %llu\n", name, field->offset);
-#endif
-
- switch (field->width)
+ switch (width)
{
case 1:
- r8 = *(guint8 *)pos;
+ r8 = *(guint8 *)data;
return r8;
case 2:
- r16 = *(guint16 *)pos;
+ r16 = *(guint16 *)data;
- if (format->big_endian)
+ if (big_endian)
r16 = GUINT16_FROM_BE (r16);
else
r16 = GUINT16_FROM_LE (r16);
return r16;
case 4:
- r32 = *(guint32 *)pos;
+ r32 = *(guint32 *)data;
- if (format->big_endian)
+ if (big_endian)
r32 = GUINT32_FROM_BE (r32);
else
r32 = GUINT32_FROM_LE (r32);
return r32;
case 8:
- r64 = *(guint64 *)pos;
+ r64 = *(guint64 *)data;
- if (format->big_endian)
+ if (big_endian)
r64 = GUINT64_FROM_BE (r64);
else
r64 = GUINT64_FROM_LE (r64);
return r64;
+
+ default:
+ g_assert_not_reached();
+ return 0;
}
+}
+
+
+guint64
+bin_parser_get_uint (BinParser *parser,
+ const gchar *name)
+{
+ const BinField *field;
+ const guint8 *pos;
+ BinFormat *format;
+ const guchar *data;
+
+ g_return_val_if_fail (parser->frame != NULL, 0);
+
+ format = parser->frame->format;
+ data = parser->data + parser->frame->offset;
-#if 0
- g_print ("width: %d\n", field->width);
-#endif
+ field = get_field (format, name);
+
+ g_return_val_if_fail (field != NULL, (guint64)-1);
+
+ pos = data + field->offset;
+
+ if (field->offset + field->width > parser->length)
+ {
+ /* FIXME: generate error */
+ return 0;
+ }
+
+ return convert_uint (pos, format->big_endian, field->width);
g_assert_not_reached();
return 0;
return parser->length;
}
+
+/* Record */
+BinRecord *
+bin_parser_get_record (BinParser *parser,
+ BinFormat *format,
+ gsize offset)
+{
+ BinRecord *record = g_new0 (BinRecord, 1);
+ record->parser = parser;
+ record->index = 0;
+ record->offset = offset;
+ record->format = format;
+ return record;
+}
+
+void
+bin_record_free (BinRecord *record)
+{
+ g_free (record);
+}
+
+guint64
+bin_record_get_uint (BinRecord *record,
+ const char *name)
+{
+ const guint8 *pos;
+ const BinField *field;
+
+ field = get_field (record->format, name);
+ pos = record->parser->data + record->offset + field->offset;
+
+ if (record->offset + field->offset + field->width > record->parser->length)
+ {
+ /* FIXME: generate error */
+ return 0;
+ }
+
+ return convert_uint (pos, record->format->big_endian, field->width);
+}
+
+void
+bin_record_index (BinRecord *record,
+ int index)
+{
+ gsize format_size = bin_format_get_size (record->format);
+
+ record->offset -= record->index * format_size;
+ record->offset += index * format_size;
+ record->index = index;
+}
+
+/* Fields */
+
BinField *
bin_field_new_fixed_array (int n_elements,
int element_size)
typedef struct BinField BinField;
typedef struct BinFormat BinFormat;
typedef struct BinParser BinParser;
+typedef struct BinRecord BinRecord;
/* BinParser */
BinParser *bin_parser_new (const guchar *data,
guint64 bin_parser_get_uint (BinParser *parser,
const gchar *name);
+/* Record */
+BinRecord *bin_parser_get_record (BinParser *parser,
+ BinFormat *format,
+ gsize offset);
+void bin_record_free (BinRecord *record);
+guint64 bin_record_get_uint (BinRecord *record,
+ const char *name);
+void bin_record_index (BinRecord *record,
+ int index);
+
/* BinFormat */
BinFormat *bin_format_new (gboolean big_endian,
const char *name, BinField *field,