blob: 48fbfbe3d0d50d9e23bdf7ee294b5465a7923e83 [file] [log] [blame]
/*
* 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) &&
(!strncasecmp( 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) &&
(!strncasecmp( 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 );
}