Add new bin_record() functions Implement them.
authorSoren Sandmann <sandmann@daimi.au.dk>
Sat, 26 Aug 2006 16:44:17 +0000 (16:44 +0000)
committerSøren Sandmann Pedersen <ssp@src.gnome.org>
Sat, 26 Aug 2006 16:44:17 +0000 (16:44 +0000)
2006-08-26  Soren Sandmann <sandmann@daimi.au.dk>

* binparser.h: Add new bin_record() functions
* binparser.c: Implement them.

ChangeLog
binparser.c
binparser.h

index 7293f0c..bcd7971 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2006-08-26  Soren Sandmann <sandmann@daimi.au.dk>
+
+       * binparser.h: Add new bin_record() functions
+       * binparser.c: Implement them.
+
 2006-08-22  Soren Sandmann <sandmann@daimi.au.dk>
 
        * collector.c (unique_dup): Demangle instead of strdup.
index a37a302..4542191 100644 (file)
@@ -15,6 +15,14 @@ struct ParserFrame
     ParserFrame *      next;
 };
 
+struct BinRecord
+{
+    BinFormat *                format;
+    int                        index;
+    gsize              offset;
+    BinParser *                parser;
+};
+
 struct BinField
 {
     guint64    offset;
@@ -166,49 +174,25 @@ get_field (BinFormat *format,
 }
 
 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);
@@ -216,9 +200,9 @@ bin_parser_get_uint (BinParser *parser,
        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);
@@ -226,19 +210,49 @@ bin_parser_get_uint (BinParser *parser,
        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;
@@ -345,6 +359,59 @@ bin_parser_get_length (BinParser *parser)
     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)
index f458398..a7bcd7f 100644 (file)
@@ -3,6 +3,7 @@
 typedef struct BinField BinField;
 typedef struct BinFormat BinFormat;
 typedef struct BinParser BinParser;
+typedef struct BinRecord BinRecord;
 
 /* BinParser */
 BinParser *bin_parser_new (const guchar        *data,
@@ -19,6 +20,16 @@ const char *bin_parser_get_string (BinParser *parser);
 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,