summaryrefslogtreecommitdiff
path: root/db3x_autobackups/dbmodulechain.c
diff options
context:
space:
mode:
Diffstat (limited to 'db3x_autobackups/dbmodulechain.c')
-rw-r--r--db3x_autobackups/dbmodulechain.c152
1 files changed, 106 insertions, 46 deletions
diff --git a/db3x_autobackups/dbmodulechain.c b/db3x_autobackups/dbmodulechain.c
index 352a06c..9508850 100644
--- a/db3x_autobackups/dbmodulechain.c
+++ b/db3x_autobackups/dbmodulechain.c
@@ -2,8 +2,8 @@
Miranda IM: the free IM client for Microsoft* Windows*
-Copyright 2000-2003 Miranda ICQ/IM project,
-all portions of this codebase are copyrighted to the people
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
listed in contributors.txt.
This program is free software; you can redistribute it and/or
@@ -22,42 +22,73 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "commonheaders.h"
-#include "database.h"
-
-extern struct DBHeader dbHeader;
static int EnumModuleNames(WPARAM wParam,LPARAM lParam);
-struct ModuleName {
+typedef struct {
char *name;
- DWORD hash;
DWORD ofs;
-};
-static struct ModuleName *moduleName;
-static int moduleNameCount;
+} ModuleName;
+
+HANDLE hModHeap = NULL;
+static SortedList lMods, lOfs;
+
+static int ModCompare( ModuleName *mn1, ModuleName *mn2 )
+{
+ return strcmp( mn1->name, mn2->name );
+}
+
+static int OfsCompare( ModuleName *mn1, ModuleName *mn2 )
+{
+ return ( mn1->ofs - mn2->ofs );
+}
+
+void AddToList(char *name, DWORD len, DWORD ofs)
+{
+ int index;
+ ModuleName *mn = (ModuleName*)HeapAlloc(hModHeap,0,sizeof(ModuleName));
+ mn->name = name;
+ mn->ofs = ofs;
+
+ if (li.List_GetIndex(&lMods,mn,&index))
+ DatabaseCorruption("%s (Module Name not unique)");
+
+ li.List_Insert(&lMods,mn,index);
+
+ if (li.List_GetIndex(&lOfs,mn,&index))
+ DatabaseCorruption("%s (Module Offset not unique)");
+
+ li.List_Insert(&lOfs,mn,index);
+}
+
int InitModuleNames(void)
{
struct DBModuleName *dbmn;
- DWORD ofsThis,ofsNext;
+ DWORD ofsThis;
int nameLen;
+ char *mod;
+
+ hModHeap=HeapCreate(0,0,0);
+ lMods.sortFunc=ModCompare;
+ lMods.increment=50;
+ lOfs.sortFunc=OfsCompare;
+ lOfs.increment=50;
- moduleNameCount=0;
- moduleName=NULL;
ofsThis=dbHeader.ofsFirstModuleName;
dbmn=(struct DBModuleName*)DBRead(ofsThis,sizeof(struct DBModuleName),NULL);
while(ofsThis) {
- if(dbmn->signature!=DBMODULENAME_SIGNATURE) DatabaseCorruption();
- moduleName=(struct ModuleName*)mir_realloc(moduleName,sizeof(struct ModuleName)*(moduleNameCount+1));
- moduleName[moduleNameCount].ofs=ofsThis;
- moduleName[moduleNameCount].hash=dbmn->cbName; //very very simple hash so far
- moduleName[moduleNameCount].name=(char*)mir_alloc(dbmn->cbName+1);
- ofsNext=dbmn->ofsNext;
+ if(dbmn->signature!=DBMODULENAME_SIGNATURE) DatabaseCorruption(NULL);
+
nameLen=dbmn->cbName;
- CopyMemory(moduleName[moduleNameCount].name,DBRead(ofsThis+offsetof(struct DBModuleName,name),nameLen,NULL),nameLen);
- moduleName[moduleNameCount].name[nameLen]=0;
- moduleNameCount++;
- ofsThis=ofsNext;
+
+ mod = (char*)HeapAlloc(hModHeap,0,nameLen+1);
+ CopyMemory(mod,DBRead(ofsThis+offsetof(struct DBModuleName,name),nameLen,NULL),nameLen);
+ mod[nameLen] = 0;
+
+ AddToList(mod, nameLen, ofsThis);
+
+ ofsThis=dbmn->ofsNext;
dbmn=(struct DBModuleName*)DBRead(ofsThis,sizeof(struct DBModuleName),NULL);
}
CreateServiceFunction(MS_DB_MODULES_ENUM,EnumModuleNames);
@@ -66,16 +97,29 @@ int InitModuleNames(void)
void UninitModuleNames(void)
{
- int i;
- for(i=0;i<moduleNameCount;i++) mir_free(moduleName[i].name);
- if(moduleNameCount) mir_free(moduleName);
+ HeapDestroy(hModHeap);
+ li.List_Destroy(&lMods);
+ li.List_Destroy(&lOfs);
}
-static DWORD FindExistingModuleNameOfs(const char *szName,int nameLen)
+static DWORD FindExistingModuleNameOfs(const char *szName)
{
- int i;
- for(i=0;i<moduleNameCount;i++)
- if(moduleName[i].hash==(DWORD)nameLen && !strcmp(moduleName[i].name,szName)) return moduleName[i].ofs;
+ static ModuleName *lastmn = NULL;
+ ModuleName mn, *pmn;
+ int index;
+
+ mn.name = (char*)szName;
+ mn.ofs = 0;
+
+ if (lastmn && ModCompare(&mn,lastmn) == 0)
+ return lastmn->ofs;
+
+ if (li.List_GetIndex(&lMods,&mn,&index)) {
+ pmn = (ModuleName*)lMods.items[index];
+ lastmn = pmn;
+ return pmn->ofs;
+ }
+
return 0;
}
@@ -83,11 +127,15 @@ static DWORD FindExistingModuleNameOfs(const char *szName,int nameLen)
DWORD GetModuleNameOfs(const char *szName)
{
struct DBModuleName dbmn;
- int nameLen=strlen(szName);
+ int nameLen;
DWORD ofsNew,ofsExisting;
+ char *mod;
- ofsExisting=FindExistingModuleNameOfs(szName,nameLen);
+ ofsExisting=FindExistingModuleNameOfs(szName);
if(ofsExisting) return ofsExisting;
+
+ nameLen = strlen(szName);
+
//need to create the module name
ofsNew=CreateNewSpace(nameLen+offsetof(struct DBModuleName,name));
dbmn.signature=DBMODULENAME_SIGNATURE;
@@ -98,34 +146,46 @@ DWORD GetModuleNameOfs(const char *szName)
DBWrite(ofsNew,&dbmn,offsetof(struct DBModuleName,name));
DBWrite(ofsNew+offsetof(struct DBModuleName,name),(PVOID)szName,nameLen);
DBFlush(0);
+
//add to cache
- moduleName=(struct ModuleName*)mir_realloc(moduleName,sizeof(struct ModuleName)*(moduleNameCount+1));
- moduleName[moduleNameCount].ofs=ofsNew;
- moduleName[moduleNameCount].hash=nameLen; //very very simple hash so far
- moduleName[moduleNameCount].name=(char*)mir_alloc(nameLen+1);
- strcpy(moduleName[moduleNameCount].name,szName);
- moduleNameCount++;
+ mod = (char*)HeapAlloc(hModHeap,0,nameLen+1);
+ strcpy(mod,szName);
+ AddToList(mod, nameLen, ofsNew);
+
//quit
return ofsNew;
}
-//it's OK that this is a bit slow - it's rarely used
char *GetModuleNameByOfs(DWORD ofs)
{
- int i;
+ static ModuleName *lastmn = NULL;
+ ModuleName mn, *pmn;
+ int index;
+
+ if (lastmn && lastmn->ofs == ofs)
+ return lastmn->name;
- for(i=0;i<moduleNameCount;i++)
- if(moduleName[i].ofs==ofs) return moduleName[i].name;
- DatabaseCorruption();
+ mn.name = NULL;
+ mn.ofs = ofs;
+
+ if (li.List_GetIndex(&lOfs,&mn,&index)) {
+ pmn = (ModuleName*)lOfs.items[index];
+ lastmn = pmn;
+ return pmn->name;
+ }
+
+ DatabaseCorruption(NULL);
return NULL;
-}
+}
static int EnumModuleNames(WPARAM wParam,LPARAM lParam)
{
int i;
int ret;
- for(i=0;i<moduleNameCount;i++) {
- ret=((DBMODULEENUMPROC)lParam)(moduleName[i].name,moduleName[i].ofs,wParam);
+ ModuleName *pmn;
+ for(i = 0; i < lMods.realCount; i++) {
+ pmn = (ModuleName *)lMods.items[i];
+ ret=((DBMODULEENUMPROC)lParam)(pmn->name,pmn->ofs,wParam);
if(ret) return ret;
}
return 0;