~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/kernel32/atom16.c

Version: ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  1 /*
  2  * Atom table functions - 16 bit variant
  3  *
  4  * Copyright 1993, 1994, 1995 Alexandre Julliard
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 /*
 22  * Warning: The code assumes that LocalAlloc() returns a block aligned
 23  * on a 4-bytes boundary (because of the shifting done in
 24  * HANDLETOATOM).  If this is not the case, the allocation code will
 25  * have to be changed.
 26  */
 27 
 28 #include "config.h"
 29 #include "wine/port.h"
 30 
 31 #include <stdlib.h>
 32 #include <stdarg.h>
 33 #include <stdio.h>
 34 #include <string.h>
 35 #include <ctype.h>
 36 
 37 #include "windef.h"
 38 #include "winbase.h"
 39 #include "winerror.h"
 40 #include "winternl.h"
 41 
 42 #include "wine/unicode.h"
 43 #include "wine/winbase16.h"
 44 #include "kernel16_private.h"
 45 
 46 #include "wine/debug.h"
 47 
 48 WINE_DEFAULT_DEBUG_CHANNEL(atom);
 49 
 50 #define DEFAULT_ATOMTABLE_SIZE    37
 51 #define MAX_ATOM_LEN              255
 52 
 53 #define ATOMTOHANDLE(atom)        ((HANDLE16)(atom) << 2)
 54 #define HANDLETOATOM(handle)      ((ATOM)(0xc000 | ((handle) >> 2)))
 55 
 56 typedef struct
 57 {
 58     HANDLE16    next;
 59     WORD        refCount;
 60     BYTE        length;
 61     CHAR        str[1];
 62 } ATOMENTRY;
 63 
 64 typedef struct
 65 {
 66     WORD        size;
 67     HANDLE16    entries[1];
 68 } ATOMTABLE;
 69 
 70 
 71 /***********************************************************************
 72  *           ATOM_GetTable
 73  *
 74  * Return a pointer to the atom table of a given segment, creating
 75  * it if necessary.
 76  *
 77  * RETURNS
 78  *      Pointer to table: Success
 79  *      NULL: Failure
 80  */
 81 static ATOMTABLE *ATOM_GetTable( BOOL create  /* [in] Create */ )
 82 {
 83     INSTANCEDATA *ptr = MapSL( MAKESEGPTR( CURRENT_DS, 0 ) );
 84     if (ptr->atomtable)
 85     {
 86         ATOMTABLE *table = (ATOMTABLE *)((char *)ptr + ptr->atomtable);
 87         if (table->size) return table;
 88     }
 89     if (!create) return NULL;
 90     if (!InitAtomTable16( 0 )) return NULL;
 91     /* Reload ptr in case it moved in linear memory */
 92     ptr = MapSL( MAKESEGPTR( CURRENT_DS, 0 ) );
 93     return (ATOMTABLE *)((char *)ptr + ptr->atomtable);
 94 }
 95 
 96 
 97 /***********************************************************************
 98  *           ATOM_Hash
 99  * RETURNS
100  *      The hash value for the input string
101  */
102 static WORD ATOM_Hash(
103             WORD entries, /* [in] Total number of entries */
104             LPCSTR str,   /* [in] Pointer to string to hash */
105             WORD len      /* [in] Length of string */
106 ) {
107     WORD i, hash = 0;
108 
109     TRACE("%x, %s, %x\n", entries, str, len);
110 
111     for (i = 0; i < len; i++) hash ^= toupper(str[i]) + i;
112     return hash % entries;
113 }
114 
115 
116 /***********************************************************************
117  *           ATOM_IsIntAtomA
118  */
119 static BOOL ATOM_IsIntAtomA(LPCSTR atomstr,WORD *atomid)
120 {
121     UINT atom = 0;
122     if (!HIWORD(atomstr)) atom = LOWORD(atomstr);
123     else
124     {
125         if (*atomstr++ != '#') return FALSE;
126         while (*atomstr >= '' && *atomstr <= '9')
127         {
128             atom = atom * 10 + *atomstr - '';
129             atomstr++;
130         }
131         if (*atomstr) return FALSE;
132     }
133     if (atom >= MAXINTATOM)
134     {
135         SetLastError( ERROR_INVALID_PARAMETER );
136         atom = 0;
137     }
138     *atomid = atom;
139     return TRUE;
140 }
141 
142 
143 /***********************************************************************
144  *           ATOM_MakePtr
145  *
146  * Make an ATOMENTRY pointer from a handle (obtained from GetAtomHandle()).
147  */
148 static inline ATOMENTRY *ATOM_MakePtr( HANDLE16 handle /* [in] Handle */ )
149 {
150     return MapSL( MAKESEGPTR( CURRENT_DS, handle ) );
151 }
152 
153 
154 /***********************************************************************
155  *           InitAtomTable   (KERNEL.68)
156  */
157 WORD WINAPI InitAtomTable16( WORD entries )
158 {
159     int i;
160     HANDLE16 handle;
161     ATOMTABLE *table;
162 
163       /* Allocate the table */
164 
165     if (!entries) entries = DEFAULT_ATOMTABLE_SIZE;  /* sanity check */
166     handle = LocalAlloc16( LMEM_FIXED, sizeof(ATOMTABLE) + (entries-1) * sizeof(HANDLE16) );
167     if (!handle) return 0;
168     table = MapSL( MAKESEGPTR( CURRENT_DS, handle ) );
169     table->size = entries;
170     for (i = 0; i < entries; i++) table->entries[i] = 0;
171 
172       /* Store a pointer to the table in the instance data */
173 
174     ((INSTANCEDATA *)MapSL( MAKESEGPTR( CURRENT_DS, 0 )))->atomtable = handle;
175     return handle;
176 }
177 
178 /***********************************************************************
179  *           GetAtomHandle   (KERNEL.73)
180  */
181 HANDLE16 WINAPI GetAtomHandle16( ATOM atom )
182 {
183     if (atom < MAXINTATOM) return 0;
184     return ATOMTOHANDLE( atom );
185 }
186 
187 
188 /***********************************************************************
189  *           AddAtom   (KERNEL.70)
190  *
191  * Windows DWORD aligns the atom entry size.
192  * The remaining unused string space created by the alignment
193  * gets padded with '\0's in a certain way to ensure
194  * that at least one trailing '\0' remains.
195  *
196  * RETURNS
197  *      Atom: Success
198  *      0: Failure
199  */
200 ATOM WINAPI AddAtom16( LPCSTR str )
201 {
202     char buffer[MAX_ATOM_LEN+1];
203     WORD hash;
204     HANDLE16 entry;
205     ATOMENTRY * entryPtr;
206     ATOMTABLE * table;
207     int len, ae_len;
208     WORD iatom;
209 
210     if (ATOM_IsIntAtomA( str, &iatom )) return iatom;
211 
212     TRACE("%s\n",debugstr_a(str));
213 
214     if (!(table = ATOM_GetTable( TRUE ))) return 0;
215 
216     /* Make a copy of the string to be sure it doesn't move in linear memory. */
217     lstrcpynA( buffer, str, sizeof(buffer) );
218 
219     len = strlen( buffer );
220     hash = ATOM_Hash( table->size, buffer, len );
221     entry = table->entries[hash];
222     while (entry)
223     {
224         entryPtr = ATOM_MakePtr( entry );
225         if ((entryPtr->length == len) &&
226             (!strncasecmp( entryPtr->str, buffer, len )))
227         {
228             entryPtr->refCount++;
229             TRACE("-- existing 0x%x\n", entry);
230             return HANDLETOATOM( entry );
231         }
232         entry = entryPtr->next;
233     }
234 
235     ae_len = (sizeof(ATOMENTRY)+len+3) & ~3;
236     entry = LocalAlloc16( LMEM_FIXED, ae_len );
237     if (!entry) return 0;
238     /* Reload the table ptr in case it moved in linear memory */
239     table = ATOM_GetTable( FALSE );
240     entryPtr = ATOM_MakePtr( entry );
241     entryPtr->next = table->entries[hash];
242     entryPtr->refCount = 1;
243     entryPtr->length = len;
244     memcpy( entryPtr->str, buffer, len);
245     /* Some applications _need_ the '\0' padding provided by memset */
246     /* Note that 1 byte of the str is accounted for in the ATOMENTRY struct */
247     memset( entryPtr->str+len, 0, ae_len - sizeof(ATOMENTRY) - (len - 1));
248     table->entries[hash] = entry;
249     TRACE("-- new 0x%x\n", entry);
250     return HANDLETOATOM( entry );
251 }
252 
253 
254 /***********************************************************************
255  *           DeleteAtom   (KERNEL.71)
256  */
257 ATOM WINAPI DeleteAtom16( ATOM atom )
258 {
259     ATOMENTRY * entryPtr;
260     ATOMTABLE * table;
261     HANDLE16 entry, *prevEntry;
262     WORD hash;
263 
264     if (atom < MAXINTATOM) return 0;  /* Integer atom */
265 
266     TRACE("0x%x\n",atom);
267 
268     if (!(table = ATOM_GetTable( FALSE ))) return 0;
269     entry = ATOMTOHANDLE( atom );
270     entryPtr = ATOM_MakePtr( entry );
271 
272     /* Find previous atom */
273     hash = ATOM_Hash( table->size, entryPtr->str, entryPtr->length );
274     prevEntry = &table->entries[hash];
275     while (*prevEntry && *prevEntry != entry)
276     {
277         ATOMENTRY * prevEntryPtr = ATOM_MakePtr( *prevEntry );
278         prevEntry = &prevEntryPtr->next;
279     }
280     if (!*prevEntry) return atom;
281 
282     /* Delete atom */
283     if (--entryPtr->refCount == 0)
284     {
285         *prevEntry = entryPtr->next;
286         LocalFree16( entry );
287     }
288     return 0;
289 }
290 
291 
292 /***********************************************************************
293  *           FindAtom   (KERNEL.69)
294  */
295 ATOM WINAPI FindAtom16( LPCSTR str )
296 {
297     ATOMTABLE * table;
298     WORD hash,iatom;
299     HANDLE16 entry;
300     int len;
301 
302     TRACE("%s\n",debugstr_a(str));
303 
304     if (ATOM_IsIntAtomA( str, &iatom )) return iatom;
305     if ((len = strlen( str )) > 255) len = 255;
306     if (!(table = ATOM_GetTable( FALSE ))) return 0;
307     hash = ATOM_Hash( table->size, str, len );
308     entry = table->entries[hash];
309     while (entry)
310     {
311         ATOMENTRY * entryPtr = ATOM_MakePtr( entry );
312         if ((entryPtr->length == len) &&
313             (!strncasecmp( entryPtr->str, str, len )))
314         {
315             TRACE("-- found %x\n", entry);
316             return HANDLETOATOM( entry );
317         }
318         entry = entryPtr->next;
319     }
320     TRACE("-- not found\n");
321     return 0;
322 }
323 
324 
325 /***********************************************************************
326  *           GetAtomName   (KERNEL.72)
327  */
328 UINT16 WINAPI GetAtomName16( ATOM atom, LPSTR buffer, INT16 count )
329 {
330     ATOMENTRY * entryPtr;
331     HANDLE16 entry;
332     char * strPtr;
333     INT len;
334     char text[8];
335 
336     TRACE("%x\n",atom);
337 
338     if (!count) return 0;
339     if (atom < MAXINTATOM)
340     {
341         sprintf( text, "#%d", atom );
342         len = strlen(text);
343         strPtr = text;
344     }
345     else
346     {
347         if (!ATOM_GetTable( FALSE )) return 0;
348         entry = ATOMTOHANDLE( atom );
349         entryPtr = ATOM_MakePtr( entry );
350         len = entryPtr->length;
351         strPtr = entryPtr->str;
352     }
353     if (len >= count) len = count-1;
354     memcpy( buffer, strPtr, len );
355     buffer[len] = '\0';
356     return len;
357 }
358 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.