342 lines
7.0 KiB
C
342 lines
7.0 KiB
C
/*
|
|
* Atom table functions
|
|
*
|
|
* Copyright 1993, 1994, 1995 Alexandre Julliard
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
|
|
#include "windows.h"
|
|
#include "xmalloc.h"
|
|
|
|
#ifdef CONFIG_IPC
|
|
#include "dde_atom.h"
|
|
#include "options.h"
|
|
#endif
|
|
|
|
#define MIN_STR_ATOM 0xc000
|
|
|
|
typedef struct
|
|
{
|
|
WORD refCount;
|
|
BYTE length;
|
|
char* str;
|
|
} ATOMDATA;
|
|
|
|
typedef struct
|
|
{
|
|
void* next;
|
|
ATOMDATA a2h[16];
|
|
} ATOMtoHANDLEtable;
|
|
|
|
static ATOMtoHANDLEtable* GlobalAtomTable = NULL;
|
|
static ATOMtoHANDLEtable* LocalAtomTable = NULL;
|
|
|
|
|
|
/***********************************************************************
|
|
* ATOM_Init
|
|
*
|
|
* Global table initialisation.
|
|
*/
|
|
BOOL ATOM_Init(void)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* ATOM_AddAtom
|
|
*/
|
|
static ATOM ATOM_AddAtom( ATOMtoHANDLEtable** tableptr, SEGPTR name )
|
|
{
|
|
ATOMDATA* FirstUnused;
|
|
ATOM FirstUnusedIndex;
|
|
ATOM Index;
|
|
ATOMtoHANDLEtable* table;
|
|
int i,len;
|
|
char *str;
|
|
|
|
/* Check for integer atom */
|
|
|
|
if (!HIWORD(name)) return (ATOM)LOWORD(name);
|
|
str = (char*)name;
|
|
if (str[0] == '#') return atoi( &str[1] );
|
|
|
|
if ((len = strlen( str )) > 255) len = 255;
|
|
table = *tableptr;
|
|
FirstUnused = NULL;
|
|
FirstUnusedIndex = 0;
|
|
Index = MIN_STR_ATOM;
|
|
while (table)
|
|
{
|
|
for(i=0; i<16; i++, Index++)
|
|
{
|
|
if (!table->a2h[i].refCount)
|
|
{
|
|
FirstUnused=&table->a2h[i];
|
|
FirstUnusedIndex=Index;
|
|
}
|
|
else if ((table->a2h[i].length == len) &&
|
|
(!lstrncmpi( table->a2h[i].str, str, len )))
|
|
{
|
|
table->a2h[i].refCount++;
|
|
return Index;
|
|
}
|
|
}
|
|
tableptr = (ATOMtoHANDLEtable**)&table->next;
|
|
table = table->next;
|
|
}
|
|
if(!FirstUnused)
|
|
{
|
|
*tableptr = xmalloc(sizeof(ATOMtoHANDLEtable));
|
|
(*tableptr)->next = NULL;
|
|
for(i=0; i<16; i++)
|
|
{
|
|
(*tableptr)->a2h[i].str = NULL;
|
|
(*tableptr)->a2h[i].refCount = 0;
|
|
}
|
|
FirstUnused = (*tableptr)->a2h;
|
|
FirstUnusedIndex = Index;
|
|
}
|
|
if((FirstUnused->str = malloc(len+1)))
|
|
{
|
|
memcpy( FirstUnused->str, str, len );
|
|
FirstUnused->str[len] = 0;
|
|
}
|
|
else
|
|
return 0;
|
|
FirstUnused->refCount = 1;
|
|
FirstUnused->length = len;
|
|
return FirstUnusedIndex;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* ATOM_DeleteAtom
|
|
*/
|
|
static ATOM ATOM_DeleteAtom( ATOMtoHANDLEtable** tableptr, ATOM atom )
|
|
{
|
|
ATOMtoHANDLEtable* table;
|
|
int i;
|
|
ATOM Index;
|
|
|
|
if (atom < MIN_STR_ATOM) return 0; /* Integer atom */
|
|
|
|
Index = MIN_STR_ATOM;
|
|
table = *tableptr;
|
|
while (table)
|
|
{
|
|
if(atom-Index < 16)
|
|
{
|
|
i=atom-Index;
|
|
|
|
/* Delete atom */
|
|
if (--table->a2h[i].refCount == 0)
|
|
{
|
|
free(table->a2h[i].str);
|
|
table->a2h[i].str=NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
Index+=16;
|
|
table = table->next;
|
|
}
|
|
}
|
|
return atom;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* ATOM_FindAtom
|
|
*/
|
|
static ATOM ATOM_FindAtom( ATOMtoHANDLEtable** tableptr, SEGPTR name )
|
|
{
|
|
ATOM Index;
|
|
ATOMtoHANDLEtable* table;
|
|
int i,len;
|
|
char *str;
|
|
|
|
/* Check for integer atom */
|
|
|
|
if (!HIWORD(name)) return (ATOM)LOWORD(name);
|
|
str = (char*)name;
|
|
if (str[0] == '#') return atoi( &str[1] );
|
|
|
|
if ((len = strlen( str )) > 255) len = 255;
|
|
table=*tableptr;
|
|
Index=MIN_STR_ATOM;
|
|
while (table)
|
|
{
|
|
for(i=0; i<16; i++, Index++)
|
|
{
|
|
if ((table->a2h[i].refCount != 0) &&
|
|
(table->a2h[i].length == len) &&
|
|
(!lstrncmpi( table->a2h[i].str, str, len )))
|
|
return Index;
|
|
}
|
|
table=table->next;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* ATOM_GetAtomName
|
|
*/
|
|
static WORD ATOM_GetAtomName( ATOMtoHANDLEtable** tableptr, ATOM atom,
|
|
LPSTR buffer, short count )
|
|
{
|
|
ATOMtoHANDLEtable* table;
|
|
ATOM Index;
|
|
char * strPtr=NULL;
|
|
int i,len=0;
|
|
char text[8];
|
|
|
|
if (!count) return 0;
|
|
if (atom < MIN_STR_ATOM)
|
|
{
|
|
sprintf( text, "#%d", atom );
|
|
len = strlen(text);
|
|
strPtr = text;
|
|
}
|
|
else
|
|
{
|
|
Index = MIN_STR_ATOM;
|
|
table = *tableptr;
|
|
while (table)
|
|
{
|
|
if(atom-Index < 16)
|
|
{
|
|
i=atom-Index;
|
|
|
|
if (table->a2h[i].refCount == 0)
|
|
table=NULL;
|
|
else
|
|
{
|
|
len = table->a2h[i].length;
|
|
strPtr = table->a2h[i].str;
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
Index+=16;
|
|
table = table->next;
|
|
}
|
|
}
|
|
if(!table)return 0;
|
|
}
|
|
if (len >= count) len = count-1;
|
|
memcpy( buffer, strPtr, len );
|
|
buffer[len] = '\0';
|
|
return len;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* InitAtomTable (KERNEL.68)
|
|
*/
|
|
WORD InitAtomTable( WORD entries )
|
|
{
|
|
return entries;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* GetAtomHandle (KERNEL.73)
|
|
*/
|
|
HANDLE GetAtomHandle( ATOM atom )
|
|
{
|
|
fprintf(stderr,"JBP: GetAtomHandle() called (obsolete).\n");
|
|
return 0;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* AddAtom (KERNEL.70)
|
|
*/
|
|
ATOM AddAtom( SEGPTR str )
|
|
{
|
|
return ATOM_AddAtom( &LocalAtomTable, (SEGPTR)str );
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* DeleteAtom (KERNEL.71)
|
|
*/
|
|
ATOM DeleteAtom( ATOM atom )
|
|
{
|
|
return ATOM_DeleteAtom( &LocalAtomTable, atom );
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* FindAtom (KERNEL.69)
|
|
*/
|
|
ATOM FindAtom( SEGPTR str )
|
|
{
|
|
return ATOM_FindAtom( &LocalAtomTable, str );
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* GetAtomName (KERNEL.72)
|
|
*/
|
|
WORD GetAtomName( ATOM atom, LPSTR buffer, short count )
|
|
{
|
|
return ATOM_GetAtomName( &LocalAtomTable, atom, buffer, count );
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* GlobalAddAtom (USER.268)
|
|
*/
|
|
ATOM GlobalAddAtom( SEGPTR str )
|
|
{
|
|
#ifdef CONFIG_IPC
|
|
if (Options.ipc) return DDE_GlobalAddAtom( str );
|
|
#endif
|
|
return ATOM_AddAtom( &GlobalAtomTable, str );
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* GlobalDeleteAtom (USER.269)
|
|
*/
|
|
ATOM GlobalDeleteAtom( ATOM atom )
|
|
{
|
|
#ifdef CONFIG_IPC
|
|
if (Options.ipc) return DDE_GlobalDeleteAtom( atom );
|
|
#endif
|
|
return ATOM_DeleteAtom( &GlobalAtomTable, atom );
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* GlobalFindAtom (USER.270)
|
|
*/
|
|
ATOM GlobalFindAtom( SEGPTR str )
|
|
{
|
|
#ifdef CONFIG_IPC
|
|
if (Options.ipc) return DDE_GlobalFindAtom( str );
|
|
#endif
|
|
return ATOM_FindAtom( &GlobalAtomTable, str );
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* GlobalGetAtomName (USER.271)
|
|
*/
|
|
WORD GlobalGetAtomName( ATOM atom, LPSTR buffer, short count )
|
|
{
|
|
#ifdef CONFIG_IPC
|
|
if (Options.ipc) return DDE_GlobalGetAtomName( atom, buffer, count );
|
|
#endif
|
|
return ATOM_GetAtomName( &GlobalAtomTable, atom, buffer, count );
|
|
}
|