]> git.saurik.com Git - wxWidgets.git/blame - src/common/hash.cpp
correction for Fit() which didn't handle properly windows positioned at (-1, -1)
[wxWidgets.git] / src / common / hash.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: hash.cpp
3// Purpose: wxHashTable implementation
4// Author: Julian Smart
bcaa23de 5// Modified by: VZ at 25.02.00: type safe hashes with WX_DECLARE_HASH()
c801d85f
KB
6// Created: 01/02/97
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
bcaa23de 9// Licence: wxWindows licence
c801d85f
KB
10/////////////////////////////////////////////////////////////////////////////
11
bcaa23de
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
c801d85f
KB
20#ifdef __GNUG__
21#pragma implementation "hash.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28#pragma hdrstop
29#endif
30
31#ifndef WX_PRECOMP
32#include "wx/list.h"
33#endif
34
35#include "wx/hash.h"
36
37#include <string.h>
38#include <stdarg.h>
39
bcaa23de
VZ
40// ----------------------------------------------------------------------------
41// wxWin macros
42// ----------------------------------------------------------------------------
43
c801d85f 44IMPLEMENT_DYNAMIC_CLASS(wxHashTable, wxObject)
c801d85f 45
bcaa23de
VZ
46// ============================================================================
47// implementation
48// ============================================================================
49
50// ----------------------------------------------------------------------------
51// wxHashTablleBase for working with "void *" data
52// ----------------------------------------------------------------------------
53
54wxHashTableBase::wxHashTableBase()
55{
56 m_deleteContents = FALSE;
57 m_hashTable = (wxListBase **)NULL;
58 m_hashSize = 0;
59 m_count = 0;
60 m_keyType = wxKEY_NONE;
61}
62
63void wxHashTableBase::Create(wxKeyType keyType, size_t size)
64{
65 Destroy();
66
67 m_hashSize = size;
68 m_keyType = keyType;
69 m_hashTable = new wxListBase *[size];
70 for ( size_t n = 0; n < m_hashSize; n++ )
71 {
72 m_hashTable[n] = (wxListBase *) NULL;
73 }
74}
75
76void wxHashTableBase::Destroy()
77{
78 if ( m_hashTable )
79 {
80 for ( size_t n = 0; n < m_hashSize; n++ )
81 {
82 delete m_hashTable[n];
83 }
84
85 delete [] m_hashTable;
86
87 m_hashTable = (wxListBase **)NULL;
88
89 m_count = 0;
90 }
91}
92
93void wxHashTableBase::DeleteContents(bool flag)
94{
95 m_deleteContents = flag;
96 for ( size_t n = 0; n < m_hashSize; n++ )
97 {
98 if ( m_hashTable[n] )
99 {
100 m_hashTable[n]->DeleteContents(flag);
101 }
102 }
103}
104
105wxNodeBase *wxHashTableBase::GetNode(long key, long value) const
106{
107 size_t slot = (size_t)abs(key % m_hashSize);
108
109 wxNodeBase *node;
110 if ( m_hashTable[slot] )
111 {
112 node = m_hashTable[slot]->Find(wxListKey(value));
113 }
114 else
115 {
116 node = (wxNodeBase *)NULL;
117 }
118
119 return node;
120}
121
122// ----------------------------------------------------------------------------
123// old not type safe wxHashTable
124// ----------------------------------------------------------------------------
125
debe6624 126wxHashTable::wxHashTable (int the_key_type, int size)
c801d85f 127{
17d8ee1c
JS
128 n = 0;
129 hash_table = (wxList**) NULL;
130 Create(the_key_type, size);
5692876f 131 m_count = 0;
c7fb814a 132 m_deleteContents = FALSE;
17d8ee1c 133/*
c801d85f
KB
134 n = size;
135 current_position = -1;
c67daf87 136 current_node = (wxNode *) NULL;
c801d85f
KB
137
138 key_type = the_key_type;
139 hash_table = new wxList *[size];
140 int i;
141 for (i = 0; i < size; i++)
c67daf87 142 hash_table[i] = (wxList *) NULL;
17d8ee1c 143*/
c801d85f
KB
144}
145
bcaa23de 146wxHashTable::~wxHashTable ()
c801d85f 147{
e55ad60e
RR
148 Destroy();
149}
150
bcaa23de 151void wxHashTable::Destroy()
e55ad60e
RR
152{
153 if (!hash_table) return;
c801d85f
KB
154 int i;
155 for (i = 0; i < n; i++)
156 if (hash_table[i])
157 delete hash_table[i];
158 delete[] hash_table;
e55ad60e 159 hash_table = NULL;
c801d85f
KB
160}
161
debe6624 162bool wxHashTable::Create(int the_key_type, int size)
c801d85f 163{
17d8ee1c
JS
164 Destroy();
165
c801d85f
KB
166 n = size;
167 current_position = -1;
c67daf87 168 current_node = (wxNode *) NULL;
c801d85f
KB
169
170 key_type = the_key_type;
c801d85f
KB
171 hash_table = new wxList *[size];
172 int i;
173 for (i = 0; i < size; i++)
c67daf87 174 hash_table[i] = (wxList *) NULL;
c801d85f
KB
175 return TRUE;
176}
177
4e67bfc7
VS
178
179void wxHashTable::DoCopy(const wxHashTable& table)
180{
181 n = table.n;
182 current_position = table.current_position;
183 current_node = NULL; // doesn't matter - Next() will reconstruct it
184 key_type = table.key_type;
185
186 hash_table = new wxList *[n];
187 for (int i = 0; i < n; i++) {
188 if (table.hash_table[i] == NULL)
189 hash_table[i] = NULL;
190 else {
191 hash_table[i] = new wxList(key_type);
192 *(hash_table[i]) = *(table.hash_table[i]);
193 }
194 }
195}
196
debe6624 197void wxHashTable::Put (long key, long value, wxObject * object)
c801d85f
KB
198{
199 // Should NEVER be
200 long k = (long) key;
c801d85f
KB
201
202 int position = (int) (k % n);
ffae916f
BJ
203 if (position < 0) position = -position;
204
c801d85f 205 if (!hash_table[position])
c7fb814a 206 {
c801d85f 207 hash_table[position] = new wxList (wxKEY_INTEGER);
c7fb814a
VS
208 if (m_deleteContents) hash_table[position]->DeleteContents(TRUE);
209 }
c801d85f
KB
210
211 hash_table[position]->Append (value, object);
5692876f 212 m_count++;
c801d85f
KB
213}
214
50920146 215void wxHashTable::Put (long key, const wxChar *value, wxObject * object)
c801d85f
KB
216{
217 // Should NEVER be
bcaa23de 218 long k = (long) key;
c801d85f
KB
219
220 int position = (int) (k % n);
ffae916f 221 if (position < 0) position = -position;
bcaa23de 222
c801d85f 223 if (!hash_table[position])
c7fb814a 224 {
c801d85f 225 hash_table[position] = new wxList (wxKEY_INTEGER);
c7fb814a
VS
226 if (m_deleteContents) hash_table[position]->DeleteContents(TRUE);
227 }
c801d85f
KB
228
229 hash_table[position]->Append (value, object);
5692876f 230 m_count++;
c801d85f
KB
231}
232
debe6624 233void wxHashTable::Put (long key, wxObject * object)
c801d85f
KB
234{
235 // Should NEVER be
236 long k = (long) key;
bcaa23de 237
c801d85f 238 int position = (int) (k % n);
ffae916f
BJ
239 if (position < 0) position = -position;
240
c801d85f 241 if (!hash_table[position])
c7fb814a 242 {
c801d85f 243 hash_table[position] = new wxList (wxKEY_INTEGER);
c7fb814a
VS
244 if (m_deleteContents) hash_table[position]->DeleteContents(TRUE);
245 }
bcaa23de 246
c801d85f 247 hash_table[position]->Append (k, object);
5692876f 248 m_count++;
c801d85f
KB
249}
250
50920146 251void wxHashTable::Put (const wxChar *key, wxObject * object)
c801d85f
KB
252{
253 int position = (int) (MakeKey (key) % n);
ffae916f 254 if (position < 0) position = -position;
c801d85f
KB
255
256 if (!hash_table[position])
c7fb814a 257 {
c801d85f 258 hash_table[position] = new wxList (wxKEY_STRING);
c7fb814a
VS
259 if (m_deleteContents) hash_table[position]->DeleteContents(TRUE);
260 }
c801d85f
KB
261
262 hash_table[position]->Append (key, object);
5692876f 263 m_count++;
c801d85f
KB
264}
265
debe6624 266wxObject *wxHashTable::Get (long key, long value) const
c801d85f
KB
267{
268 // Should NEVER be
269 long k = (long) key;
c801d85f
KB
270
271 int position = (int) (k % n);
ffae916f
BJ
272 if (position < 0) position = -position;
273
c801d85f 274 if (!hash_table[position])
c67daf87 275 return (wxObject *) NULL;
c801d85f
KB
276 else
277 {
278 wxNode *node = hash_table[position]->Find (value);
279 if (node)
bcaa23de 280 return node->Data ();
c801d85f 281 else
bcaa23de 282 return (wxObject *) NULL;
c801d85f
KB
283 }
284}
285
50920146 286wxObject *wxHashTable::Get (long key, const wxChar *value) const
c801d85f
KB
287{
288 // Should NEVER be
289 long k = (long) key;
bcaa23de 290
c801d85f 291 int position = (int) (k % n);
ffae916f
BJ
292 if (position < 0) position = -position;
293
c801d85f 294 if (!hash_table[position])
c67daf87 295 return (wxObject *) NULL;
c801d85f
KB
296 else
297 {
298 wxNode *node = hash_table[position]->Find (value);
299 if (node)
bcaa23de 300 return node->Data ();
c801d85f 301 else
bcaa23de 302 return (wxObject *) NULL;
c801d85f
KB
303 }
304}
305
debe6624 306wxObject *wxHashTable::Get (long key) const
c801d85f
KB
307{
308 // Should NEVER be
309 long k = (long) key;
c801d85f
KB
310
311 int position = (int) (k % n);
ffae916f
BJ
312 if (position < 0) position = -position;
313
c801d85f 314 if (!hash_table[position])
c67daf87 315 return (wxObject *) NULL;
c801d85f
KB
316 else
317 {
318 wxNode *node = hash_table[position]->Find (k);
319 return node ? node->Data () : (wxObject*)NULL;
320 }
321}
322
50920146 323wxObject *wxHashTable::Get (const wxChar *key) const
c801d85f
KB
324{
325 int position = (int) (MakeKey (key) % n);
ffae916f 326 if (position < 0) position = -position;
c801d85f
KB
327
328 if (!hash_table[position])
c67daf87 329 return (wxObject *) NULL;
c801d85f
KB
330 else
331 {
332 wxNode *node = hash_table[position]->Find (key);
333 return node ? node->Data () : (wxObject*)NULL;
334 }
335}
336
debe6624 337wxObject *wxHashTable::Delete (long key)
c801d85f
KB
338{
339 // Should NEVER be
340 long k = (long) key;
c801d85f
KB
341
342 int position = (int) (k % n);
ffae916f
BJ
343 if (position < 0) position = -position;
344
c801d85f 345 if (!hash_table[position])
c67daf87 346 return (wxObject *) NULL;
c801d85f
KB
347 else
348 {
349 wxNode *node = hash_table[position]->Find (k);
350 if (node)
bcaa23de
VZ
351 {
352 wxObject *data = node->Data ();
353 delete node;
354 m_count--;
355 return data;
356 }
c801d85f 357 else
bcaa23de 358 return (wxObject *) NULL;
c801d85f
KB
359 }
360}
361
50920146 362wxObject *wxHashTable::Delete (const wxChar *key)
c801d85f
KB
363{
364 int position = (int) (MakeKey (key) % n);
ffae916f
BJ
365 if (position < 0) position = -position;
366
c801d85f 367 if (!hash_table[position])
c67daf87 368 return (wxObject *) NULL;
c801d85f
KB
369 else
370 {
371 wxNode *node = hash_table[position]->Find (key);
372 if (node)
bcaa23de
VZ
373 {
374 wxObject *data = node->Data ();
375 delete node;
376 m_count--;
377 return data;
378 }
c801d85f 379 else
bcaa23de 380 return (wxObject *) NULL;
c801d85f
KB
381 }
382}
383
debe6624 384wxObject *wxHashTable::Delete (long key, int value)
c801d85f
KB
385{
386 // Should NEVER be
bcaa23de 387 long k = (long) key;
c801d85f
KB
388
389 int position = (int) (k % n);
ffae916f
BJ
390 if (position < 0) position = -position;
391
c801d85f 392 if (!hash_table[position])
c67daf87 393 return (wxObject *) NULL;
c801d85f
KB
394 else
395 {
396 wxNode *node = hash_table[position]->Find (value);
397 if (node)
bcaa23de
VZ
398 {
399 wxObject *data = node->Data ();
400 delete node;
401 m_count--;
402 return data;
403 }
c801d85f 404 else
bcaa23de 405 return (wxObject *) NULL;
c801d85f
KB
406 }
407}
408
50920146 409wxObject *wxHashTable::Delete (long key, const wxChar *value)
c801d85f
KB
410{
411 int position = (int) (key % n);
ffae916f
BJ
412 if (position < 0) position = -position;
413
c801d85f 414 if (!hash_table[position])
c67daf87 415 return (wxObject *) NULL;
c801d85f
KB
416 else
417 {
418 wxNode *node = hash_table[position]->Find (value);
419 if (node)
bcaa23de
VZ
420 {
421 wxObject *data = node->Data ();
422 delete node;
423 m_count--;
424 return data;
425 }
c801d85f 426 else
bcaa23de 427 return (wxObject *) NULL;
c801d85f
KB
428 }
429}
430
50920146 431long wxHashTable::MakeKey (const wxChar *string) const
c801d85f
KB
432{
433 long int_key = 0;
434
435 while (*string)
50920146 436 int_key += (wxUChar) *string++;
c801d85f
KB
437
438 return int_key;
439}
440
bcaa23de 441void wxHashTable::BeginFind ()
c801d85f
KB
442{
443 current_position = -1;
c67daf87 444 current_node = (wxNode *) NULL;
c801d85f
KB
445}
446
bcaa23de 447wxNode *wxHashTable::Next ()
c801d85f 448{
c67daf87 449 wxNode *found = (wxNode *) NULL;
c801d85f
KB
450 bool end = FALSE;
451 while (!end && !found)
452 {
453 if (!current_node)
bcaa23de
VZ
454 {
455 current_position++;
456 if (current_position >= n)
457 {
458 current_position = -1;
459 current_node = (wxNode *) NULL;
460 end = TRUE;
461 }
462 else
463 {
464 if (hash_table[current_position])
465 {
466 current_node = hash_table[current_position]->First ();
467 found = current_node;
468 }
469 }
470 }
c801d85f 471 else
bcaa23de
VZ
472 {
473 current_node = current_node->Next ();
474 found = current_node;
475 }
c801d85f
KB
476 }
477 return found;
478}
479
debe6624 480void wxHashTable::DeleteContents (bool flag)
c801d85f
KB
481{
482 int i;
c7fb814a 483 m_deleteContents = flag;
c801d85f
KB
484 for (i = 0; i < n; i++)
485 {
486 if (hash_table[i])
bcaa23de 487 hash_table[i]->DeleteContents (flag);
c801d85f
KB
488 }
489}
490
bcaa23de 491void wxHashTable::Clear ()
c801d85f
KB
492{
493 int i;
494 for (i = 0; i < n; i++)
495 {
496 if (hash_table[i])
bcaa23de 497 hash_table[i]->Clear ();
c801d85f 498 }
5692876f 499 m_count = 0;
c801d85f
KB
500}
501