#include "trace.h" static void trace_entry_free(trace_entry_t *te) { g_slice_free1(te->count*12 + 8, te); } static void _trace_entry_free(gpointer p, gpointer x) { UNUSED(x); trace_entry_free(p); } static trace_entry_t *trace_entry_new(guint32 timestamp, guint32 count) { trace_entry_t *te = g_slice_alloc(count*12 + 8); te->timestamp = timestamp; te->count = count; return te; } trace_t *trace_load(const gchar *filename) { GError *err = NULL; guint32 *buf = NULL; gsize len = 0, i; trace_t *trace = g_slice_new0(trace_t); trace->data = g_ptr_array_new(); if (!g_file_get_contents(filename, (gchar**) &buf, &len, &err)) { fprintf (stderr, "Unable to read file %s: %s\n", filename, err->message); g_error_free (err); exit(1); } if (len % 4 > 0) { fprintf (stderr, "Solution: length not aligned\n"); exit(10); } len /= 4; if (len < 10) { fprintf (stderr, "Solution too short\n"); exit(10); } if (buf[0] != 0xCAFEBABE) { fprintf (stderr, "Wrong magic in solution: 0x%X\n", (guint) buf[0]); exit(10); } trace->magic = buf[0]; trace->team = buf[1]; trace->scenario = buf[2]; for (i = 3; i < len; ) { guint32 timestamp, count; trace_entry_t *te; if (i+1 >= len) { fprintf(stderr, "Solution: unexpected end of file (%i+1 >= %i)\n", (guint) i, (guint) len); exit(10); } timestamp = buf[i++]; count = buf[i++]; if (i+count*3 > len) { fprintf(stderr, "Solution: unexpected end of file (%i+%i*3 >= %i\n", (guint) i, (guint) count, (guint) len); exit(10); } te = trace_entry_new(timestamp, count); if (count > 0) memcpy(te->data, &buf[i], count * 12); i += 3*count; g_ptr_array_add(trace->data, te); if (count == 0 && i < len) { fprintf (stderr, "Solution: expected end of file (count = 0)\n"); } } return trace; } void trace_free(trace_t *trace) { g_ptr_array_foreach(trace->data, _trace_entry_free, NULL); }