2 * $Id: edsio.c 1.1 Sun, 28 Jan 2007 10:02:26 -0800 jmacd $
4 * Copyright (C) 1998, 1999, Josh MacDonald.
7 * Author: Josh MacDonald <jmacd@CS.Berkeley.EDU>
13 #if TIME_WITH_SYS_TIME
14 # include <sys/time.h>
18 # include <sys/time.h>
26 /*#define DEBUG_PROPS*/
31 static GHashTable* all_event_defs = NULL;
33 static GPtrArray* all_event_watchers = NULL;
35 typedef struct _ErrorDeliveryWatcher ErrorDeliveryWatcher;
36 typedef struct _DelayedEvent DelayedEvent;
38 struct _ErrorDeliveryWatcher {
39 ErrorDeliveryFunc deliver;
42 struct _DelayedEvent {
49 eventdelivery_initialize_event_def (gint code,
54 const char * (* field_to_string) (GenericEvent* ev, gint field))
56 GenericEventDef* def = g_new0 (GenericEventDef, 1);
59 all_event_defs = g_hash_table_new (g_int_hash, g_int_equal);
65 def->oneline = oneline;
66 def->field_to_string = field_to_string;
68 g_hash_table_insert (all_event_defs, & def->code, def);
72 eventdelivery_event_watch_all (ErrorDeliveryFunc func)
74 ErrorDeliveryWatcher* w = g_new0 (ErrorDeliveryWatcher, 1);
78 if (! all_event_watchers)
79 all_event_watchers = g_ptr_array_new ();
81 g_ptr_array_add (all_event_watchers, w);
85 eventdelivery_event_lookup (gint code)
87 return g_hash_table_lookup (all_event_defs, & code);
91 eventdelivery_event_deliver (GenericEvent* e)
93 static gint in_call = FALSE;
94 static GQueue* queued = NULL;
95 static GPtrArray* free_strings = NULL;
99 queued = g_queue_new ();
100 free_strings = g_ptr_array_new ();
111 GenericEventDef* def = g_hash_table_lookup (all_event_defs, & e->code);
116 const char* oneline = def->oneline;
119 out = g_string_new (NULL);
121 while ((c = *oneline++))
131 if ((*oneline++) != '{')
134 f = strtol (oneline, &end, 10);
136 if (f < 0 || !end || end[0] != '}')
141 g_assert (def->field_to_string);
143 field = def->field_to_string (e, f);
147 g_string_append (out, field);
149 g_free ((void*) field);
156 g_string_append_c (out, c);
160 if (! all_event_watchers)
162 fprintf (stderr, "%s:%d: %s\n", e->srcfile, e->srcline, out->str);
164 g_string_free (out, TRUE);
166 else if (in_call == 1)
170 for (i = 0; i < all_event_watchers->len; i += 1)
172 ErrorDeliveryWatcher* w = all_event_watchers->pdata[i];
174 if (! w->deliver (e, def, out->str))
176 g_warning ("%s:%d: An error delivery routine failed: %s\n", e->srcfile, e->srcline, out->str);
182 while (g_queue_get_size (queued) > 0)
184 DelayedEvent* de = g_queue_pop (queued);
186 for (i = 0; i < all_event_watchers->len; i += 1)
188 ErrorDeliveryWatcher* w = all_event_watchers->pdata[i];
190 if (! w->deliver (& de->ev, de->def, de->msg))
192 g_warning ("%s:%d: An error delivery routine failed: %s\n", e->srcfile, e->srcline, out->str);
199 for (i = 0; i < free_strings->len; i += 1)
200 g_string_free (free_strings->pdata[i], TRUE);
202 g_ptr_array_set_size (free_strings, 0);
204 g_string_free (out, TRUE);
208 DelayedEvent* de = g_new (DelayedEvent, 1);
214 g_queue_push (queued, de);
216 g_ptr_array_add (free_strings, out);
225 g_warning ("%s:%d: Unrecognized event delivered (code=%d)\n", e->srcfile, e->srcline, e->code);
233 g_warning ("%s:%d: An malformed error could not print here (code=%d)\n", e->srcfile, e->srcline, e->code);
241 eventdelivery_int_to_string (int x)
243 return g_strdup_printf ("%d", x);
247 eventdelivery_string_to_string (const char* x)
253 eventdelivery_source_to_string (SerialSource* x)
255 return g_strdup ("@@@SerialSource");
259 eventdelivery_sink_to_string (SerialSink* x)
261 return g_strdup ("@@@SerialSink");
265 eventdelivery_handle_to_string (FileHandle* x)
267 g_return_val_if_fail (x, g_strdup ("*error*"));
269 return x->table->table_handle_name (x);
276 edsio_time_of_day (SerialGenericTime* setme)
278 #if HAVE_GETTIMEOFDAY
282 if (gettimeofday (& tv, NULL))
284 edsio_generate_errno_event (EC_EdsioGetTimeOfDayFailure);
290 setme->nanos = tv.tv_usec * 1000;
291 setme->seconds = tv.tv_sec;
297 time_t t = time (NULL);
301 edsio_generate_errno_event (EC_EdsioTimeFailure);
308 setme->seconds = tv.tv_sec;
324 edsio_time_to_iso8601 (SerialGenericTime *tp)
326 return edsio_time_t_to_iso8601 (tp->seconds);
330 edsio_time_t_to_iso8601 (GTime t0)
332 static char timebuf[64];
335 struct tm lt = *localtime(&t);
336 int utc_offset = difftm(<, gmtime(&t));
337 char sign = utc_offset < 0 ? '-' : '+';
338 int minutes = abs (utc_offset) / 60;
339 int hours = minutes / 60;
342 "%d-%02d-%02d %02d:%02d:%02d%c%02d%02d",
357 strtosl_checked (const char* str, long* l, const char* errmsg)
361 (*l) = strtol (str, &end, 10);
366 edsio_generate_stringstring_event (EC_EdsioInvalidIntegerString, errmsg, str);
376 strtosi_checked (const char* str, gint32* i, const char* errmsg)
380 if (! strtosl_checked (str, &l, errmsg))
386 if (l > G_MAXINT || l < G_MININT)
389 edsio_generate_stringstring_event (EC_EdsioIntegerOutOfRange, errmsg, str);
401 strtoss_checked (const char* str, gint16* i, const char* errmsg)
405 if (! strtosl_checked (str, &l, errmsg))
411 if (l > G_MAXSHORT || l < G_MINSHORT)
414 edsio_generate_stringstring_event (EC_EdsioIntegerOutOfRange, errmsg, str);
426 strtoui_checked (const char* str, guint32* i, const char* errmsg)
430 if (! strtosl_checked (str, &l, errmsg))
439 edsio_generate_stringstring_event (EC_EdsioInvalidIntegerSign, errmsg, str);
450 edsio_generate_stringstring_event (EC_EdsioIntegerOutOfRange, errmsg, str);
460 strtous_checked (const char* str, guint16* i, const char* errmsg)
464 if (! strtosl_checked (str, &l, errmsg))
473 edsio_generate_stringstring_event (EC_EdsioInvalidIntegerSign, errmsg, str);
484 edsio_generate_stringstring_event (EC_EdsioIntegerOutOfRange, errmsg, str);
494 edsio_md5_equal (gconstpointer v,
497 return memcmp (v, v2, 16) == 0;
501 edsio_md5_hash (gconstpointer v)
503 guint8* md5 = (guint8*) v;
507 for (i = 0, j = 0; i < 16; i += 1, j += 1, j %= sizeof (guint32))
508 x ^= md5[i] << (8*j);
514 serializeio_print_bytes (const guint8* bytes, guint len0)
520 len = MIN (len0, 32);
522 for (i = 0; i < len; i += 1)
523 sprintf (buf + 2*i, "%02x", bytes[i]);
528 g_print ("%s\n", buf);
532 edsio_md5_to_string (const guint8* md5, char buf[33])
536 for (i = 0; i < 16; i += 1)
537 sprintf (buf + 2*i, "%02x", md5[i]);
541 from_hex (char c, int* x, const char* ctx)
545 if (c >= '0' && c <= '9')
550 else if (c >= 'A' && c <= 'F')
555 else if (c >= 'a' && c <= 'f')
564 edsio_generate_stringstring_event (EC_EdsioInvalidHexDigit, buf, ctx);
569 edsio_md5_from_string (guint8* md5, const char buf[33])
572 gint l = strlen (buf);
576 edsio_generate_string_event (EC_EdsioMD5StringShort, buf);
581 edsio_generate_string_event (EC_EdsioMD5StringLong, buf);
585 for (i = 0; i < 16; i += 1)
587 char c1 = buf[(2*i)];
588 char c2 = buf[(2*i)+1];
591 if (! from_hex (c1, &x1, buf))
594 if (! from_hex (c2, &x2, buf))
597 md5[i] = (x1 << 4) | x2;
606 const char* edsio_intern_string (const char* str)
608 static GStringChunk* chunk = NULL;
611 chunk = g_string_chunk_new (256);
613 return g_string_chunk_insert_const (chunk, str);
619 typedef struct _EdsioHostType EdsioHostType;
620 typedef struct _EdsioPropertyType EdsioPropertyType;
622 struct _EdsioPropertyType {
623 const char *type_name;
627 PropSerialize serialize;
628 PropUnserialize unserialize;
631 struct _EdsioHostType {
632 const char *host_name;
633 PropertyTableFunc ptable;
634 PersistSourceFunc source;
635 PersistSinkFunc sink;
636 PersistIssetFunc isset;
637 PersistUnsetFunc unset;
640 struct _EdsioProperty {
642 const char *prop_name;
644 EdsioPropertyType *type;
648 union _EdsioPropertyEntry {
650 SerialEdsioBytes as_bytes;
652 const char* as_string;
655 struct _EdsioGenericProperty
660 static GHashTable* all_property_types = NULL;
661 static GHashTable* all_host_types = NULL;
662 static GHashTable* all_properties = NULL;
663 static GHashTable* all_property_codes = NULL;
664 static guint32 property_code_sequence = 0;
667 edsio_initialize_property_type (const char* t, PropFreeFunc freer, PropGSFunc getter, PropGSFunc setter, PropSerialize ser, PropUnserialize unser)
669 EdsioPropertyType* type;
671 t = edsio_intern_string (t);
673 if (! all_property_types)
674 all_property_types = g_hash_table_new (g_direct_hash, g_direct_equal);
676 if ((type = g_hash_table_lookup (all_property_types, t)) != NULL)
678 if (getter != type->getter ||
679 setter != type->setter ||
680 ser != type->serialize ||
681 unser != type->unserialize)
682 edsio_generate_string_event (EC_EdsioDuplicatePropertyTypeRegistered, t);
686 type = g_new0 (EdsioPropertyType, 1);
690 type->getter = getter;
691 type->setter = setter;
692 type->serialize = ser;
693 type->unserialize = unser;
695 g_hash_table_insert (all_property_types, (gpointer) t, type);
699 edsio_initialize_host_type (const char* ph,
700 PropertyTableFunc ptable,
701 PersistSourceFunc source,
702 PersistSinkFunc sink,
703 PersistIssetFunc isset,
704 PersistUnsetFunc unset)
708 ph = edsio_intern_string (ph);
710 if (! all_host_types)
711 all_host_types = g_hash_table_new (g_direct_hash, g_direct_equal);
713 if (g_hash_table_lookup (all_host_types, ph))
715 edsio_generate_string_event (EC_EdsioDuplicateHostTypeRegistered, ph);
719 host = g_new0 (EdsioHostType, 1);
721 host->host_name = ph;
722 host->ptable = ptable;
723 host->source = source;
728 g_hash_table_insert (all_host_types, (gpointer) ph, host);
733 edsio_new_property (const char* name, const char* ph, const char* t, guint32 flags, EdsioGenericProperty *ret_prop)
736 EdsioPropertyType* type;
739 name = edsio_intern_string (name);
740 ph = edsio_intern_string (ph);
741 t = edsio_intern_string (t);
743 g_assert (all_property_types);
745 if (! all_properties)
747 all_properties = g_hash_table_new (g_direct_hash, g_direct_equal);
748 all_property_codes = g_hash_table_new (g_int_hash, g_int_equal);
751 if ((prop = g_hash_table_lookup (all_properties, name)) != NULL)
753 edsio_generate_string_event (EC_EdsioDuplicatePropertyNameRegistered, name);
754 ret_prop->code = prop->prop_code;
758 if ((type = g_hash_table_lookup (all_property_types, t)) == NULL)
760 edsio_generate_string_event (EC_EdsioNoSuchPropertyType, t);
764 if ((host = g_hash_table_lookup (all_host_types, ph)) == NULL)
766 edsio_generate_string_event (EC_EdsioNoSuchHostType, ph);
770 if (flags & PF_Persistent && ! host->isset)
772 edsio_generate_stringstring_event (EC_EdsioPersistenceUnavailable, name, ph);
776 prop = g_new0 (EdsioProperty, 1);
778 prop->prop_code = ++property_code_sequence;
779 prop->prop_name = name;
780 prop->prop_flags = flags;
784 g_hash_table_insert (all_properties, (gpointer) name, prop);
785 g_hash_table_insert (all_property_codes, & prop->prop_code, prop);
787 ret_prop->code = prop->prop_code;
792 static EdsioProperty*
793 edsio_property_find (const char* ph, const char* t, guint32 code)
797 ph = edsio_intern_string (ph);
798 t = edsio_intern_string (t);
800 if (code <= 0 || code > property_code_sequence)
802 edsio_generate_int_event (EC_EdsioNoSuchProperty, code);
806 if (! (prop = g_hash_table_lookup (all_property_codes, & code)))
808 edsio_generate_int_event (EC_EdsioNoSuchProperty, code);
812 if (prop->host->host_name != ph)
814 edsio_generate_stringstringstring_event (EC_EdsioWrongHostType, prop->prop_name, ph, prop->host->host_name);
818 if (prop->type->type_name != t)
820 edsio_generate_stringstringstring_event (EC_EdsioWrongDataType, prop->prop_name, t, prop->type->type_name);
828 edsio_property_get (gpointer obj, EdsioProperty* prop)
830 EdsioPropertyEntry* ent;
831 GHashTable* table = * prop->host->ptable (obj);
832 gboolean persist = prop->prop_flags & PF_Persistent;
835 g_print ("get %p.%s\n", obj, prop->prop_name);
838 if (table && (ent = g_hash_table_lookup (table, & prop->prop_code)) != NULL)
845 if (! (src = prop->host->source (obj, prop->prop_name)))
848 g_assert (prop->type->unserialize);
850 if (! prop->type->unserialize (src, & ent))
855 if (! src->source_close (src))
858 src->source_free (src);
861 table = (* prop->host->ptable (obj)) = g_hash_table_new (g_int_hash, g_int_equal);
863 g_hash_table_insert (table, & prop->prop_code, ent);
868 edsio_generate_string_event (EC_EdsioPropertyNotSet, prop->prop_name);
873 edsio_property_set (gpointer obj, EdsioProperty* prop, EdsioPropertyEntry* set)
875 EdsioPropertyEntry* ent;
876 gboolean persist = prop->prop_flags & PF_Persistent;
877 GHashTable* table = * prop->host->ptable (obj);
880 g_print ("set %p.%s\n", obj, prop->prop_name);
884 table = (* prop->host->ptable (obj)) = g_hash_table_new (g_int_hash, g_int_equal);
886 ent = g_hash_table_lookup (table, & prop->prop_code);
890 g_hash_table_remove (table, & prop->prop_code);
891 prop->type->freer (ent);
894 g_hash_table_insert (table, & prop->prop_code, set);
900 if (! (sink = prop->host->sink (obj, prop->prop_name)))
903 g_assert (prop->type->serialize);
905 if (! prop->type->serialize (sink, set))
908 if (! sink->sink_close (sink))
911 sink->sink_free (sink);
918 edsio_property_isset (const char* ph, const char* t, guint32 code, gpointer obj)
923 gboolean result = FALSE;
925 if (! (prop = edsio_property_find (ph, t, code)))
928 persist = prop->prop_flags & PF_Persistent;
930 table = * prop->host->ptable (obj);
934 PersistIssetFunc issetfunc = prop->host->isset;
935 if (issetfunc(obj, prop->prop_name))
937 if (! edsio_property_get (obj, prop))
940 table = * prop->host->ptable (obj);
947 result = (g_hash_table_lookup (table, & code) != NULL);
952 g_print ("isset %p.%s = %s\n", obj, prop->prop_name, result ? "true" : "false");
959 edsio_property_unset (const char* ph, const char* t, guint32 code, gpointer obj)
965 if (! (prop = edsio_property_find (ph, t, code)))
969 g_print ("unset %p.%s\n", obj, prop->prop_name);
972 persist = prop->prop_flags & PF_Persistent;
973 table = * prop->host->ptable (obj);
977 EdsioPropertyEntry* ent;
979 ent = g_hash_table_lookup (table, & code);
981 g_hash_table_remove (table, & code);
983 if (g_hash_table_size (table) == 0)
985 g_hash_table_destroy (table);
986 table = (* prop->host->ptable (obj)) = NULL;
994 if (! prop->host->unset (obj, prop->prop_name))
1008 edsio_property_getter (const char* ph, const char* t, guint32 code, EdsioProperty** ep)
1010 if (! ((*ep) = edsio_property_find (ph, t, code)))
1011 return & edsio_false;
1013 return (* ep)->type->getter;
1017 edsio_property_setter (const char* ph, const char* t, guint32 code, EdsioProperty** ep)
1019 if (! ((* ep) = edsio_property_find (ph, t, code)))
1020 return & edsio_false;
1022 return (* ep)->type->setter;
1025 /* Primitive type serializers
1031 edsio_property_uint_getter (gpointer obj, EdsioProperty* prop, guint32* get)
1033 EdsioPropertyEntry *ent;
1035 if (! (ent = edsio_property_get (obj, prop)))
1038 (*get) = ent->as_uint32;
1044 edsio_property_uint_setter (gpointer obj, EdsioProperty* prop, guint32 set)
1046 EdsioPropertyEntry *ent = g_new (EdsioPropertyEntry, 1);
1048 ent->as_uint32 = set;
1050 return edsio_property_set (obj, prop, ent);
1054 edsio_property_uint_free (gpointer obj)
1060 unserialize_uint (SerialSource *source, guint32** x)
1065 if (! unserialize_edsiouint (source, & s))
1068 n = g_new (guint32, 1);
1080 serialize_uint_obj (SerialSink *sink, guint32* x)
1082 return serialize_edsiouint (sink, *x);
1089 edsio_property_string_free (gpointer obj)
1095 edsio_property_string_getter (gpointer obj, EdsioProperty* prop, const char** get)
1097 if (! ((*get) = (const char*) edsio_property_get (obj, prop)))
1104 edsio_property_string_setter (gpointer obj, EdsioProperty* prop, const char* set)
1106 return edsio_property_set (obj, prop, (EdsioPropertyEntry*) set);
1110 unserialize_string (SerialSource *source, const char** x)
1112 SerialEdsioString *s;
1114 if (! unserialize_edsiostring (source, & s))
1117 (*x) = g_strdup (s->val);
1125 serialize_string_obj (SerialSink *sink, const char* x)
1127 return serialize_edsiostring (sink, x);
1134 unserialize_bytes (SerialSource *source, SerialEdsioBytes** x)
1136 return unserialize_edsiobytes (source, x);
1140 serialize_bytes_obj (SerialSink *sink, SerialEdsioBytes *x)
1142 return serialize_edsiobytes_obj (sink, x);
1146 edsio_property_bytes_getter (gpointer obj, EdsioProperty* prop, guint8** get, guint32* get_len)
1148 EdsioPropertyEntry *ent;
1150 if (! (ent = edsio_property_get (obj, prop)))
1153 (* get) = (gpointer) ent->as_bytes.val;
1154 (* get_len) = ent->as_bytes.val_len;
1160 edsio_property_bytes_setter (gpointer obj, EdsioProperty* prop, guint8* set, guint32 set_len)
1162 EdsioPropertyEntry *ent = g_new (EdsioPropertyEntry, 1);
1164 ent->as_bytes.val = set;
1165 ent->as_bytes.val_len = set_len;
1167 return edsio_property_set (obj, prop, ent);
1171 edsio_property_bytes_free (gpointer obj)
1180 edsio_property_vptr_getter (gpointer obj, EdsioProperty* prop, void** get)
1182 if (! ((*get) = edsio_property_get (obj, prop)))
1189 edsio_property_vptr_setter (gpointer obj, EdsioProperty* prop, void* set)
1191 return edsio_property_set (obj, prop, (EdsioPropertyEntry*) set);
1195 edsio_property_vptr_free (gpointer obj)
1203 #ifdef DEBUG_LIBEDSIO
1206 edsio_proptest_property_table (PropTest *pt)
1208 return & pt->_edsio_property_table;
1212 edsio_persist_proptest_source (PropTest *pt, const char* prop_name)
1218 g_warning ("can't get persist property, no table\n");
1222 if (! (array = g_hash_table_lookup (pt->ptable, prop_name)))
1224 g_warning ("can't lookup persist property\n");
1228 return edsio_simple_source (array->data, array->len, SBF_None);
1232 pt_success (gpointer data, GByteArray* result)
1234 PropTest* pt = data;
1239 pt->ptable = g_hash_table_new (g_str_hash, g_str_equal);
1241 old = g_hash_table_lookup (pt->ptable, (gpointer) pt->kludge);
1244 g_byte_array_free (old, TRUE);
1246 g_hash_table_insert (pt->ptable, (gpointer) pt->kludge, result);
1250 edsio_persist_proptest_sink (PropTest *pt, const char* prop_name)
1252 pt->kludge = prop_name;
1254 return edsio_simple_sink (pt, SBF_None, FALSE, pt_success, NULL);
1258 edsio_persist_proptest_isset (PropTest *pt, const char* prop_name)
1263 return g_hash_table_lookup (pt->ptable, prop_name) != NULL;
1267 edsio_persist_proptest_unset (PropTest *pt, const char* prop_name)
1274 old = g_hash_table_lookup (pt->ptable, prop_name);
1278 g_byte_array_free (old, TRUE);
1279 g_hash_table_remove (pt->ptable, prop_name);
1288 /* Misc source/sink stuff
1292 serializeio_gzip_sink (SerialSink* sink)
1294 /* @@@ not implemented */
1299 serializeio_gzip_source (SerialSource* source)
1301 /* @@@ not implemented */
1307 typedef struct _ChecksumSink ChecksumSink;
1309 static gboolean checksum_sink_close (SerialSink* sink);
1310 static gboolean checksum_sink_write (SerialSink* sink, const guint8 *ptr, guint32 len);
1311 static void checksum_sink_free (SerialSink* sink);
1312 static gboolean checksum_sink_quantum (SerialSink* sink);
1314 struct _ChecksumSink
1323 gboolean md5_written;
1327 serializeio_checksum_sink (SerialSink* out)
1329 ChecksumSink* it = g_new0 (ChecksumSink, 1);
1330 SerialSink* sink = (SerialSink*) it;
1332 serializeio_sink_init (sink,
1334 checksum_sink_close,
1335 checksum_sink_write,
1337 checksum_sink_quantum);
1341 edsio_md5_init (& it->ctx);
1347 checksum_sink_write (SerialSink* fsink, const guint8 *ptr, guint32 len)
1349 ChecksumSink* sink = (ChecksumSink*) fsink;
1351 if (! sink->out->sink_write (sink->out, ptr, len))
1354 edsio_md5_update (& sink->ctx, ptr, len);
1360 checksum_sink_close (SerialSink* fsink)
1362 ChecksumSink* sink = (ChecksumSink*) fsink;
1364 if (! sink->md5_done)
1366 edsio_md5_final (sink->md5, & sink->ctx);
1367 sink->md5_done = TRUE;
1370 if (! sink->out->sink_write (sink->out, sink->md5, 16))
1373 if (! sink->out->sink_close (sink->out))
1380 checksum_sink_free (SerialSink* fsink)
1382 ChecksumSink* sink = (ChecksumSink*) fsink;
1384 sink->out->sink_free (sink->out);
1390 checksum_sink_quantum (SerialSink* fsink)
1392 ChecksumSink* sink = (ChecksumSink*) fsink;
1394 if (sink->out->sink_quantum)
1395 return sink->out->sink_quantum (sink->out);
1403 typedef struct _ChecksumSource ChecksumSource;
1405 struct _ChecksumSource {
1406 SerialSource source;
1413 static gboolean checksum_source_close (SerialSource* source);
1414 static gboolean checksum_source_read (SerialSource* source, guint8 *ptr, guint32 len);
1415 static void checksum_source_free (SerialSource* source);
1418 serializeio_checksum_source (SerialSource* in0)
1420 ChecksumSource* it = g_new0 (ChecksumSource, 1);
1421 SerialSource* source = (SerialSource*) it;
1423 serializeio_source_init (source,
1425 checksum_source_close,
1426 checksum_source_read,
1427 checksum_source_free,
1433 edsio_md5_init (& it->ctx);
1439 checksum_source_close (SerialSource* fsource)
1441 ChecksumSource* source = (ChecksumSource*) fsource;
1445 if (! source->in->source_read (source->in, buf1, 16))
1448 edsio_md5_final (buf2, & source->ctx);
1450 if (memcmp (buf1, buf2, 16) != 0)
1452 edsio_generate_void_event (EC_EdsioInvalidStreamChecksum);
1456 if (! source->in->source_close (source->in))
1463 checksum_source_read (SerialSource* fsource, guint8 *ptr, guint32 len)
1465 ChecksumSource* source = (ChecksumSource*) fsource;
1467 if (! source->in->source_read (source->in, ptr, len))
1470 edsio_md5_update (& source->ctx, ptr, len);
1476 checksum_source_free (SerialSource* fsource)
1478 ChecksumSource* source = (ChecksumSource*) fsource;
1480 source->in->source_free (source->in);
1485 /* Missing glib stuff
1491 GQueue *q = g_new (GQueue, 1);
1493 q->list = q->list_end = NULL;
1501 g_queue_free (GQueue *q)
1506 g_list_free (q->list);
1513 g_queue_get_size (GQueue *q)
1515 return (q == NULL) ? 0 : q->list_size;
1520 g_queue_push_front (GQueue *q, gpointer data)
1524 q->list = g_list_prepend (q->list, data);
1526 if (q->list_end == NULL)
1527 q->list_end = q->list;
1535 g_queue_push_back (GQueue *q, gpointer data)
1539 q->list_end = g_list_append (q->list_end, data);
1542 q->list = q->list_end;
1544 q->list_end = q->list_end->next;
1552 g_queue_pop_front (GQueue *q)
1554 gpointer data = NULL;
1556 if ((q) && (q->list))
1565 q->list = q->list_end = NULL;
1570 q->list = node->next;
1571 q->list->prev = NULL;
1575 g_list_free_1 (node);
1583 g_queue_pop_back (GQueue *q)
1585 gpointer data = NULL;
1587 if ((q) && (q->list))
1596 q->list = q->list_end = NULL;
1601 q->list_end = node->prev;
1602 q->list_end->next = NULL;
1606 g_list_free_1 (node);