summaryrefslogtreecommitdiff
path: root/libedsio/generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'libedsio/generic.c')
-rwxr-xr-xlibedsio/generic.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/libedsio/generic.c b/libedsio/generic.c
new file mode 100755
index 0000000..d63dfb0
--- /dev/null
+++ b/libedsio/generic.c
@@ -0,0 +1,252 @@
+/* -*-Mode: C;-*-
+ * $Id: generic.c 1.2 Sun, 28 Jan 2007 12:21:11 -0800 jmacd $
+ *
+ * Copyright (C) 1998, 1999, Josh MacDonald.
+ * All Rights Reserved.
+ *
+ * Author: Josh MacDonald <jmacd@CS.Berkeley.EDU>
+ */
+
+#include "edsio.h"
+
+/* Type-based selectors for unknown types
+ */
+
+typedef struct {
+ const char* name;
+ gboolean (*unserialize_func) ();
+ gboolean (*serialize_func) ();
+ guint (*count_func) ();
+ void (*print_func) ();
+ guint32 val;
+} SerEntry;
+
+static GArray *ser_array;
+static gboolean ser_array_sorted;
+
+void
+serializeio_initialize_type (const char* name,
+ guint32 val,
+ gboolean (*unserialize_func) (),
+ gboolean (*serialize_func) (),
+ guint (*count_func) (),
+ void (*print_func) ())
+{
+ SerEntry it;
+
+ it.name = name;
+ it.val = val;
+ it.unserialize_func = unserialize_func;
+ it.serialize_func = serialize_func;
+ it.count_func = count_func;
+ it.print_func = print_func;
+
+ if (ser_array == NULL)
+ ser_array = g_array_new (FALSE, TRUE, sizeof (SerEntry));
+
+ g_array_append_val (ser_array, it);
+
+ ser_array_sorted = FALSE;
+}
+
+static int
+ser_entry_compare (const void* va, const void* vb)
+{
+ SerEntry* a = (SerEntry*) va;
+ SerEntry* b = (SerEntry*) vb;
+
+ return a->val - b->val;
+}
+
+static SerEntry*
+serializeio_find_entry (SerialType type)
+{
+ if (! edsio_library_check (type & EDSIO_LIBRARY_OFFSET_MASK))
+ return NULL;
+
+ if (ser_array)
+ {
+ gint high_index = ser_array->len;
+ gint low_index = 0;
+ gint index;
+ gint this_val;
+
+ if (! ser_array_sorted)
+ {
+ ser_array_sorted = TRUE;
+ qsort (ser_array->data, ser_array->len, sizeof (SerEntry), ser_entry_compare);
+ }
+
+ again:
+
+ index = (low_index + high_index) / 2;
+
+ this_val = g_array_index (ser_array, SerEntry, index).val;
+
+ if (this_val < type)
+ {
+ low_index = index + 1;
+ goto again;
+ }
+ else if (this_val > type)
+ {
+ high_index = index - 1;
+ goto again;
+ }
+ else
+ {
+ return & g_array_index (ser_array, SerEntry, index);
+ }
+ }
+
+ edsio_generate_intint_event (EC_EdsioUnregisteredType,
+ type & EDSIO_LIBRARY_OFFSET_MASK,
+ type >> EDSIO_LIBRARY_OFFSET_BITS);
+ return NULL;
+}
+
+gboolean
+serializeio_unserialize_generic_internal (SerialSource *source,
+ SerialType *object_type,
+ void **object,
+ gboolean set_allocation)
+{
+ SerialType type = (* source->source_type) (source, set_allocation);
+ SerEntry* ent;
+ gboolean res = FALSE;
+
+ if (type < 0)
+ return FALSE;
+
+ ent = serializeio_find_entry (type);
+
+ (*object_type) = type;
+
+ if (ent)
+ {
+ res = ent->unserialize_func (source, object);
+ }
+
+ return res;
+}
+
+gboolean
+serializeio_unserialize_generic (SerialSource *source,
+ SerialType *object_type,
+ void **object)
+{
+ return serializeio_unserialize_generic_internal (source, object_type, object, TRUE);
+}
+
+gboolean
+serializeio_serialize_generic (SerialSink *sink,
+ SerialType object_type,
+ void *object)
+{
+ return serializeio_serialize_generic_internal (sink, object_type, object, TRUE);
+}
+
+gboolean
+serializeio_serialize_generic_internal (SerialSink *sink,
+ SerialType object_type,
+ void *object,
+ gboolean set_allocation)
+{
+ SerEntry* ent;
+ gboolean res = FALSE;
+
+ if (! (* sink->sink_type) (sink, object_type, set_allocation ? serializeio_generic_count (object_type, object) : 0, set_allocation))
+ return FALSE;
+
+ ent = serializeio_find_entry (object_type);
+
+ if (ent)
+ res = ent->serialize_func (sink, object);
+
+ return res;
+}
+
+const char*
+serializeio_generic_type_to_string (SerialType type)
+{
+ SerEntry* ent;
+ const char* res = "*Unknown*";
+
+ ent = serializeio_find_entry (type);
+
+ if (ent)
+ res = ent->name;
+
+ return res;
+}
+
+guint
+serializeio_generic_count (SerialType object_type,
+ void *object)
+{
+ SerEntry* ent;
+ gboolean res = FALSE;
+
+ ent = serializeio_find_entry (object_type);
+
+ if (ent)
+ res = ent->count_func (object);
+
+ return res;
+}
+
+void
+serializeio_generic_print (SerialType type, void* object, guint indent_spaces)
+{
+ SerEntry* ent;
+
+ ent = serializeio_find_entry (type);
+
+ if (ent)
+ ent->print_func (object, indent_spaces);
+ else
+ {
+ int i = 0;
+
+ for (; i < indent_spaces; i += 1)
+ g_print (" ");
+
+ g_print ("*Type Not Registered*\n");
+ }
+}
+
+gboolean
+serializeio_unserialize_generic_acceptable (SerialSource *source,
+ guint32 accept,
+ SerialType *object_type,
+ void **object)
+{
+ gboolean s;
+
+ s = serializeio_unserialize_generic (source, object_type, object);
+
+ if (s)
+ {
+ if (accept != -1)
+ {
+ if ((*object_type & EDSIO_LIBRARY_OFFSET_MASK) != (accept & EDSIO_LIBRARY_OFFSET_MASK))
+ {
+ edsio_generate_intint_event (EC_EdsioUnexpectedLibraryType,
+ accept & EDSIO_LIBRARY_OFFSET_MASK,
+ *object_type & EDSIO_LIBRARY_OFFSET_MASK);
+
+ return FALSE;
+ }
+
+ if (! ((*object_type & ~EDSIO_LIBRARY_OFFSET_MASK) |
+ (accept & ~EDSIO_LIBRARY_OFFSET_MASK)))
+ {
+ edsio_generate_void_event (EC_EdsioUnexpectedType);
+
+ return FALSE;
+ }
+ }
+ }
+
+ return s;
+}