Typelib changes 2

Nyef nyef at softhome.net
Sat Mar 13 12:37:39 CST 2004


Hello all.

Attached is a patch to improve how the GUID hash system works.
Mainly a cleanup so that the hash lookups can be done from
other functions.

--Alastair Bridgewater
-------------- next part --------------
Index: typelib2.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/typelib2.c,v
retrieving revision 1.13
diff -u -r1.13 typelib2.c
--- typelib2.c	10 Feb 2004 02:26:06 -0000	1.13
+++ typelib2.c	13 Mar 2004 16:35:39 -0000
@@ -254,6 +254,58 @@
 }
 
 /****************************************************************************
+ *	ctl2_hash_guid
+ *
+ *  Generates a hash key from a GUID.
+ *
+ * RETURNS
+ *
+ *  The hash key for the GUID.
+ */
+static int ctl2_hash_guid(
+	REFGUID guid)                /* [I] The guid to find. */
+{
+    int hash;
+    int i;
+
+    hash = 0;
+    for (i = 0; i < 8; i ++) {
+	hash ^= ((short *)guid)[i];
+    }
+
+    return (hash & 0xf) | ((hash & 0x10) & (0 - !!(hash & 0xe0)));
+}
+
+/****************************************************************************
+ *	ctl2_find_guid
+ *
+ *  Locates a guid in a type library.
+ *
+ * RETURNS
+ *
+ *  The offset into the GUID segment of the guid, or -1 if not found.
+ */
+static int ctl2_find_guid(
+	ICreateTypeLib2Impl *This, /* [I] The typelib to operate against. */
+	int hash_key,              /* [I] The hash key for the guid. */
+	REFGUID guid)                /* [I] The guid to find. */
+{
+    int offset;
+    MSFT_GuidEntry *guidentry;
+
+    offset = This->typelib_guidhash_segment[hash_key];
+    while (offset != -1) {
+	guidentry = (MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][offset];
+
+	if (!memcmp(guidentry, guid, sizeof(GUID))) return offset;
+
+	offset = guidentry->next_hash;
+    }
+
+    return offset;
+}
+
+/****************************************************************************
  *	ctl2_find_name
  *
  *  Locates a name in a type library.
@@ -497,17 +549,12 @@
 {
     int offset;
     MSFT_GuidEntry *guid_space;
-    int hash;
     int hash_key;
-    int i;
 
-    for (offset = 0; offset < This->typelib_segdir[MSFT_SEG_GUID].length;
-	 offset += sizeof(MSFT_GuidEntry)) {
-	if (!memcmp(&(This->typelib_segment_data[MSFT_SEG_GUID][offset]),
-		    guid, sizeof(GUID))) {
-	    return offset;
-	}
-    }
+    hash_key = ctl2_hash_guid(&guid->guid);
+
+    offset = ctl2_find_guid(This, hash_key, &guid->guid);
+    if (offset != -1) return offset;
 
     offset = ctl2_alloc_segment(This, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0);
     if (offset == -1) return -1;
@@ -515,17 +562,9 @@
     guid_space = (void *)(This->typelib_segment_data[MSFT_SEG_GUID] + offset);
     *guid_space = *guid;
 
-    hash = 0;
-    for (i = 0; i < 16; i += 2) {
-	hash ^= *((short *)&This->typelib_segment_data[MSFT_SEG_GUID][offset + i]);
-    }
-
-    hash_key = (hash & 0xf) | ((hash & 0x10) & (0 - !!(hash & 0xe0)));
     guid_space->next_hash = This->typelib_guidhash_segment[hash_key];
     This->typelib_guidhash_segment[hash_key] = offset;
 
-    TRACE("Updating GUID hash table (%s,0x%x).\n", debugstr_guid(&guid->guid), hash);
-
     return offset;
 }
 
@@ -1114,8 +1153,8 @@
     TRACE("(%p,%s)\n", iface, debugstr_guid(guid));
 
     guidentry.guid = *guid;
-    guidentry.hreftype = 0;
-    guidentry.next_hash = 0x18;
+    guidentry.hreftype = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
+    guidentry.next_hash = -1;
 
     offset = ctl2_alloc_guid(This->typelib, &guidentry);
     
@@ -1123,6 +1195,10 @@
 
     This->typeinfo->posguid = offset;
 
+    if (IsEqualIID(guid, &IID_IDispatch)) {
+	This->typelib->typelib_header.dispatchpos = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
+    }
+
     return S_OK;
 }
 


More information about the wine-patches mailing list