| /* |
| * 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 ); |
| } |