g_strcase_hash & G_GET_DOUBLE_LE suggestion




Hi,

	I sent this some time ago and either it is more worthless than I
suspected or it bounced silently; anyway here goes:

        Something we use in gnumeric is a case insensitive string
hash, so attached is a patch for that ( perhaps this is a stupid idea ? )
it doesn't fit the namespace so nicely as g_strcase_hash but I don't know
what to do about that.

        Secondly, we use a routine that will convert an array of 8 guint8s
into a double a lot. [ this double written by an x86 eg. as output by
Excel, Lotus123, DBase etc. ]. Possibly this has a wider application, so I
have hacked up a second patch implementing a get/set interface for this.
Unfortunately this is horribly processor specific :-) My current
reservations are:

        It will only work on machines that can cope with arbitarily
aligned double pointers.
        It assumes that machines write a double as 8 consecutive bytes in
an endianness comparable to their word writing endianness ( apparently not
true of the ARM in some cases (?) ).

        I think neither of these are insuperable, since it is clearly
possible to write more generic routines for these processors. Arguably the
generic routines should always be used, but this would create an immense
performance drop off for most processors. Also much as I love m4 I don't
know how to hack up an autoconf test for such things.

        So could these go in glib ? is this the right place ? am I wasting
my time ?

	Regards,

		Michael Meeks.

-- 
 michael@imaginator.com  <><, Pseudo Engineer, itinerant idiot
? strhash.patch
Index: glib.h
===================================================================
RCS file: /cvs/gnome/glib/glib.h,v
retrieving revision 1.132
diff -u -r1.132 glib.h
--- glib.h	1999/07/24 18:50:55	1.132
+++ glib.h	1999/07/26 16:45:19
@@ -1832,13 +1832,17 @@
 
 /* Hash Functions
  */
-gint  g_str_equal (gconstpointer   v,
-		   gconstpointer   v2);
-guint g_str_hash  (gconstpointer   v);
+gint  g_str_equal     (gconstpointer   v,
+		       gconstpointer   v2);
+guint g_str_hash      (gconstpointer   v);
 
-gint  g_int_equal (gconstpointer   v,
-		   gconstpointer   v2);
-guint g_int_hash  (gconstpointer   v);
+gint  g_strcase_equal (gconstpointer   v,
+		       gconstpointer   v2);
+guint g_strcase_hash  (gconstpointer   v);
+
+gint  g_int_equal     (gconstpointer   v,
+		       gconstpointer   v2);
+guint g_int_hash      (gconstpointer   v);
 
 /* This "hash" function will just return the key's adress as an
  * unsigned integer. Useful for hashing on plain adresses or
Index: gstring.c
===================================================================
RCS file: /cvs/gnome/glib/gstring.c,v
retrieving revision 1.13
diff -u -r1.13 gstring.c
--- gstring.c	1999/07/24 18:50:55	1.13
+++ gstring.c	1999/07/26 16:45:21
@@ -92,6 +92,30 @@
   return h /* % M */;
 }
 
+gint
+g_strcase_equal (gconstpointer v, gconstpointer v2)
+{
+	return g_strcasecmp ((const gchar*) v, (const gchar*)v2) == 0;
+}
+
+/* a char* hash function from ASU */
+guint
+g_strcase_hash (gconstpointer v)
+{
+	const unsigned char *s = (const unsigned char *)v;
+	const unsigned char *p;
+	guint h = 0, g;
+
+	for(p = s; *p != '\0'; p += 1) {
+		h = ( h << 4 ) + tolower (*p);
+		if ( ( g = h & 0xf0000000 ) ) {
+			h = h ^ (g >> 24);
+			h = h ^ g;
+		}
+	}
+
+	return h /* % M */;
+}
 
 /* String Chunks.
  */
? strhash.patch
? tmp.txt
? tmp.c
? double.patch
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/glib/ChangeLog,v
retrieving revision 1.313
diff -u -r1.313 ChangeLog
--- ChangeLog	1999/07/24 18:50:55	1.313
+++ ChangeLog	1999/07/26 17:04:09
@@ -1,3 +1,9 @@
+1999-07-26  Michael Meeks  <michael@edenproject.org>
+
+	* glib.h: Added G_(GET/SET)_DOUBLE_LE
+
+	* gutils.c (g_get_double_le, g_set_double_le): Created.
+
 Sat Jul 24 20:11:35 1999  Tim Janik  <timj@gtk.org>
 
 	* merged GLib 1.3.0 with glib-1.2.3 from Fri Jul 16 22:18:36.
Index: glib.h
===================================================================
RCS file: /cvs/gnome/glib/glib.h,v
retrieving revision 1.132
diff -u -r1.132 glib.h
--- glib.h	1999/07/24 18:50:55	1.132
+++ glib.h	1999/07/26 17:04:12
@@ -650,6 +650,15 @@
 #define g_htonl(val) (GUINT32_TO_BE (val))
 #define g_htons(val) (GUINT16_TO_BE (val))
 
+/* manipulate IEEE numbers in a guint8 array
+ */
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#  define G_GET_DOUBLE_LE(p)   (*((const double *)(p)))
+#  define G_SET_DOUBLE_LE(p,q) (*((double *)(p))=(q))
+#else
+#  define G_GET_DOUBLE_LE(p)   (g_get_double_le(p))
+#  define G_SET_DOUBLE_LE(p,q) (g_set_double_le(p,q))
+#endif
 
 /* Glib version.
  * we prefix variable declarations so they can
Index: gutils.c
===================================================================
RCS file: /cvs/gnome/glib/gutils.c,v
retrieving revision 1.50
diff -u -r1.50 gutils.c
--- gutils.c	1999/07/24 18:50:56	1.50
+++ gutils.c	1999/07/26 17:04:13
@@ -704,6 +704,31 @@
   return *(const gint*) v;
 }
 
+double
+g_get_double_le (const guint8 *p)
+{
+    double d;
+    int i;
+    guint8 *t = (guint8 *)&d;
+    int sd = sizeof (d);
+
+    for (i = 0; i < sd; i++)
+      t[i] = p[sd - 1 - i];
+
+    return d;
+}
+
+void
+g_set_double_le (guint8 *p, const double d)
+{
+    int i;
+    guint8 *t = (guint8 *)&d;
+    int sd = sizeof (d);
+
+    for (i = 0; i < sd; i++)
+	    p[sd - 1 - i] = t[i];
+}
+
 #ifdef NATIVE_WIN32
 
 int


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]