]> git.saurik.com Git - wxWidgets.git/blame - src/common/hash.cpp
1. added range checks in wxGridStringTable
[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
c2bb85e9
VZ
122// ----------------------------------------------------------------------------
123// wxHashTableLong
124// ----------------------------------------------------------------------------
125
126void wxHashTableLong::Init(size_t size)
127{
128 m_hashSize = size;
129 m_values = new wxArrayLong *[size];
130 m_keys = new wxArrayLong *[size];
131
132 for ( size_t n = 0; n < m_hashSize; n++ )
133 {
134 m_values[n] =
135 m_keys[n] = (wxArrayLong *)NULL;
136 }
137
138 m_count = 0;
139}
140
141void wxHashTableLong::Destroy()
142{
143 for ( size_t n = 0; n < m_hashSize; n++ )
144 {
145 delete m_values[n];
146 delete m_keys[n];
147 }
148
149 delete [] m_values;
150 delete [] m_keys;
151 m_hashSize = 0;
152 m_count = 0;
153}
154
155void wxHashTableLong::Put(long key, long value)
156{
157 wxCHECK_RET( m_hashSize, _T("must call Create() first") );
158
159 size_t slot = (size_t)abs(key % m_hashSize);
160
161 if ( !m_keys[slot] )
162 {
163 m_keys[slot] = new wxArrayLong;
164 m_values[slot] = new wxArrayLong;
165 }
166
167 m_keys[slot]->Add(key);
168 m_values[slot]->Add(value);
169
170 m_count++;
171}
172
173long wxHashTableLong::Get(long key) const
174{
175 wxCHECK_MSG( m_hashSize, wxNOT_FOUND, _T("must call Create() first") );
176
177 size_t slot = (size_t)abs(key % m_hashSize);
178
179 wxArrayLong *keys = m_keys[slot];
180 if ( keys )
181 {
182 size_t count = keys->GetCount();
183 for ( size_t n = 0; n < count; n++ )
184 {
185 if ( keys->Item(n) == key )
186 {
187 return m_values[slot]->Item(n);
188 }
189 }
190 }
191
192 return wxNOT_FOUND;
193}
194
195long wxHashTableLong::Delete(long key)
196{
197 wxCHECK_MSG( m_hashSize, wxNOT_FOUND, _T("must call Create() first") );
198
199 size_t slot = (size_t)abs(key % m_hashSize);
200
201 wxArrayLong *keys = m_keys[slot];
202 if ( keys )
203 {
204 size_t count = keys->GetCount();
205 for ( size_t n = 0; n < count; n++ )
206 {
207 if ( keys->Item(n) == key )
208 {
209 long val = m_values[slot]->Item(n);
210
211 keys->RemoveAt(n);
212 m_values[slot]->RemoveAt(n);
213
214 m_count--;
215
216 return val;
217 }
218 }
219 }
220
221 return wxNOT_FOUND;
222}
223
bcaa23de
VZ
224// ----------------------------------------------------------------------------
225// old not type safe wxHashTable
226// ----------------------------------------------------------------------------
227
debe6624 228wxHashTable::wxHashTable (int the_key_type, int size)
c801d85f 229{
17d8ee1c
JS
230 n = 0;
231 hash_table = (wxList**) NULL;
232 Create(the_key_type, size);
5692876f 233 m_count = 0;
c7fb814a 234 m_deleteContents = FALSE;
17d8ee1c 235/*
c801d85f
KB
236 n = size;
237 current_position = -1;
c67daf87 238 current_node = (wxNode *) NULL;
c801d85f
KB
239
240 key_type = the_key_type;
241 hash_table = new wxList *[size];
242 int i;
243 for (i = 0; i < size; i++)
c67daf87 244 hash_table[i] = (wxList *) NULL;
17d8ee1c 245*/
c801d85f
KB
246}
247
bcaa23de 248wxHashTable::~wxHashTable ()
c801d85f 249{
e55ad60e
RR
250 Destroy();
251}
252
bcaa23de 253void wxHashTable::Destroy()
e55ad60e
RR
254{
255 if (!hash_table) return;
c801d85f
KB
256 int i;
257 for (i = 0; i < n; i++)
258 if (hash_table[i])
259 delete hash_table[i];
260 delete[] hash_table;
e55ad60e 261 hash_table = NULL;
c801d85f
KB
262}
263
debe6624 264bool wxHashTable::Create(int the_key_type, int size)
c801d85f 265{
17d8ee1c
JS
266 Destroy();
267
c801d85f
KB
268 n = size;
269 current_position = -1;
c67daf87 270 current_node = (wxNode *) NULL;
c801d85f
KB
271
272 key_type = the_key_type;
c801d85f
KB
273 hash_table = new wxList *[size];
274 int i;
275 for (i = 0; i < size; i++)
c67daf87 276 hash_table[i] = (wxList *) NULL;
c801d85f
KB
277 return TRUE;
278}
279
4e67bfc7
VS
280
281void wxHashTable::DoCopy(const wxHashTable& table)
282{
283 n = table.n;
284 current_position = table.current_position;
285 current_node = NULL; // doesn't matter - Next() will reconstruct it
286 key_type = table.key_type;
287
288 hash_table = new wxList *[n];
289 for (int i = 0; i < n; i++) {
290 if (table.hash_table[i] == NULL)
291 hash_table[i] = NULL;
292 else {
293 hash_table[i] = new wxList(key_type);
294 *(hash_table[i]) = *(table.hash_table[i]);
295 }
296 }
297}
298
debe6624 299void wxHashTable::Put (long key, long value, wxObject * object)
c801d85f
KB
300{
301 // Should NEVER be
302 long k = (long) key;
c801d85f
KB
303
304 int position = (int) (k % n);
ffae916f
BJ
305 if (position < 0) position = -position;
306
c801d85f 307 if (!hash_table[position])
c7fb814a 308 {
c801d85f 309 hash_table[position] = new wxList (wxKEY_INTEGER);
c7fb814a
VS
310 if (m_deleteContents) hash_table[position]->DeleteContents(TRUE);
311 }
c801d85f
KB
312
313 hash_table[position]->Append (value, object);
5692876f 314 m_count++;
c801d85f
KB
315}
316
50920146 317void wxHashTable::Put (long key, const wxChar *value, wxObject * object)
c801d85f
KB
318{
319 // Should NEVER be
bcaa23de 320 long k = (long) key;
c801d85f
KB
321
322 int position = (int) (k % n);
ffae916f 323 if (position < 0) position = -position;
bcaa23de 324
c801d85f 325 if (!hash_table[position])
c7fb814a 326 {
c801d85f 327 hash_table[position] = new wxList (wxKEY_INTEGER);
c7fb814a
VS
328 if (m_deleteContents) hash_table[position]->DeleteContents(TRUE);
329 }
c801d85f
KB
330
331 hash_table[position]->Append (value, object);
5692876f 332 m_count++;
c801d85f
KB
333}
334
debe6624 335void wxHashTable::Put (long key, wxObject * object)
c801d85f
KB
336{
337 // Should NEVER be
338 long k = (long) key;
bcaa23de 339
c801d85f 340 int position = (int) (k % n);
ffae916f
BJ
341 if (position < 0) position = -position;
342
c801d85f 343 if (!hash_table[position])
c7fb814a 344 {
c801d85f 345 hash_table[position] = new wxList (wxKEY_INTEGER);
c7fb814a
VS
346 if (m_deleteContents) hash_table[position]->DeleteContents(TRUE);
347 }
bcaa23de 348
c801d85f 349 hash_table[position]->Append (k, object);
5692876f 350 m_count++;
c801d85f
KB
351}
352
50920146 353void wxHashTable::Put (const wxChar *key, wxObject * object)
c801d85f
KB
354{
355 int position = (int) (MakeKey (key) % n);
ffae916f 356 if (position < 0) position = -position;
c801d85f
KB
357
358 if (!hash_table[position])
c7fb814a 359 {
c801d85f 360 hash_table[position] = new wxList (wxKEY_STRING);
c7fb814a
VS
361 if (m_deleteContents) hash_table[position]->DeleteContents(TRUE);
362 }
c801d85f
KB
363
364 hash_table[position]->Append (key, object);
5692876f 365 m_count++;
c801d85f
KB
366}
367
debe6624 368wxObject *wxHashTable::Get (long key, long value) const
c801d85f
KB
369{
370 // Should NEVER be
371 long k = (long) key;
c801d85f
KB
372
373 int position = (int) (k % n);
ffae916f
BJ
374 if (position < 0) position = -position;
375
c801d85f 376 if (!hash_table[position])
c67daf87 377 return (wxObject *) NULL;
c801d85f
KB
378 else
379 {
380 wxNode *node = hash_table[position]->Find (value);
381 if (node)
bcaa23de 382 return node->Data ();
c801d85f 383 else
bcaa23de 384 return (wxObject *) NULL;
c801d85f
KB
385 }
386}
387
50920146 388wxObject *wxHashTable::Get (long key, const wxChar *value) const
c801d85f
KB
389{
390 // Should NEVER be
391 long k = (long) key;
bcaa23de 392
c801d85f 393 int position = (int) (k % n);
ffae916f
BJ
394 if (position < 0) position = -position;
395
c801d85f 396 if (!hash_table[position])
c67daf87 397 return (wxObject *) NULL;
c801d85f
KB
398 else
399 {
400 wxNode *node = hash_table[position]->Find (value);
401 if (node)
bcaa23de 402 return node->Data ();
c801d85f 403 else
bcaa23de 404 return (wxObject *) NULL;
c801d85f
KB
405 }
406}
407
debe6624 408wxObject *wxHashTable::Get (long key) const
c801d85f
KB
409{
410 // Should NEVER be
411 long k = (long) key;
c801d85f
KB
412
413 int position = (int) (k % n);
ffae916f
BJ
414 if (position < 0) position = -position;
415
c801d85f 416 if (!hash_table[position])
c67daf87 417 return (wxObject *) NULL;
c801d85f
KB
418 else
419 {
420 wxNode *node = hash_table[position]->Find (k);
421 return node ? node->Data () : (wxObject*)NULL;
422 }
423}
424
50920146 425wxObject *wxHashTable::Get (const wxChar *key) const
c801d85f
KB
426{
427 int position = (int) (MakeKey (key) % n);
ffae916f 428 if (position < 0) position = -position;
c801d85f
KB
429
430 if (!hash_table[position])
c67daf87 431 return (wxObject *) NULL;
c801d85f
KB
432 else
433 {
434 wxNode *node = hash_table[position]->Find (key);
435 return node ? node->Data () : (wxObject*)NULL;
436 }
437}
438
debe6624 439wxObject *wxHashTable::Delete (long key)
c801d85f
KB
440{
441 // Should NEVER be
442 long k = (long) key;
c801d85f
KB
443
444 int position = (int) (k % n);
ffae916f
BJ
445 if (position < 0) position = -position;
446
c801d85f 447 if (!hash_table[position])
c67daf87 448 return (wxObject *) NULL;
c801d85f
KB
449 else
450 {
451 wxNode *node = hash_table[position]->Find (k);
452 if (node)
bcaa23de
VZ
453 {
454 wxObject *data = node->Data ();
455 delete node;
456 m_count--;
457 return data;
458 }
c801d85f 459 else
bcaa23de 460 return (wxObject *) NULL;
c801d85f
KB
461 }
462}
463
50920146 464wxObject *wxHashTable::Delete (const wxChar *key)
c801d85f
KB
465{
466 int position = (int) (MakeKey (key) % n);
ffae916f
BJ
467 if (position < 0) position = -position;
468
c801d85f 469 if (!hash_table[position])
c67daf87 470 return (wxObject *) NULL;
c801d85f
KB
471 else
472 {
473 wxNode *node = hash_table[position]->Find (key);
474 if (node)
bcaa23de
VZ
475 {
476 wxObject *data = node->Data ();
477 delete node;
478 m_count--;
479 return data;
480 }
c801d85f 481 else
bcaa23de 482 return (wxObject *) NULL;
c801d85f
KB
483 }
484}
485
debe6624 486wxObject *wxHashTable::Delete (long key, int value)
c801d85f
KB
487{
488 // Should NEVER be
bcaa23de 489 long k = (long) key;
c801d85f
KB
490
491 int position = (int) (k % n);
ffae916f
BJ
492 if (position < 0) position = -position;
493
c801d85f 494 if (!hash_table[position])
c67daf87 495 return (wxObject *) NULL;
c801d85f
KB
496 else
497 {
498 wxNode *node = hash_table[position]->Find (value);
499 if (node)
bcaa23de
VZ
500 {
501 wxObject *data = node->Data ();
502 delete node;
503 m_count--;
504 return data;
505 }
c801d85f 506 else
bcaa23de 507 return (wxObject *) NULL;
c801d85f
KB
508 }
509}
510
50920146 511wxObject *wxHashTable::Delete (long key, const wxChar *value)
c801d85f
KB
512{
513 int position = (int) (key % n);
ffae916f
BJ
514 if (position < 0) position = -position;
515
c801d85f 516 if (!hash_table[position])
c67daf87 517 return (wxObject *) NULL;
c801d85f
KB
518 else
519 {
520 wxNode *node = hash_table[position]->Find (value);
521 if (node)
bcaa23de
VZ
522 {
523 wxObject *data = node->Data ();
524 delete node;
525 m_count--;
526 return data;
527 }
c801d85f 528 else
bcaa23de 529 return (wxObject *) NULL;
c801d85f
KB
530 }
531}
532
50920146 533long wxHashTable::MakeKey (const wxChar *string) const
c801d85f
KB
534{
535 long int_key = 0;
536
537 while (*string)
50920146 538 int_key += (wxUChar) *string++;
c801d85f
KB
539
540 return int_key;
541}
542
bcaa23de 543void wxHashTable::BeginFind ()
c801d85f
KB
544{
545 current_position = -1;
c67daf87 546 current_node = (wxNode *) NULL;
c801d85f
KB
547}
548
bcaa23de 549wxNode *wxHashTable::Next ()
c801d85f 550{
c67daf87 551 wxNode *found = (wxNode *) NULL;
c801d85f
KB
552 bool end = FALSE;
553 while (!end && !found)
554 {
555 if (!current_node)
bcaa23de
VZ
556 {
557 current_position++;
558 if (current_position >= n)
559 {
560 current_position = -1;
561 current_node = (wxNode *) NULL;
562 end = TRUE;
563 }
564 else
565 {
566 if (hash_table[current_position])
567 {
568 current_node = hash_table[current_position]->First ();
569 found = current_node;
570 }
571 }
572 }
c801d85f 573 else
bcaa23de
VZ
574 {
575 current_node = current_node->Next ();
576 found = current_node;
577 }
c801d85f
KB
578 }
579 return found;
580}
581
debe6624 582void wxHashTable::DeleteContents (bool flag)
c801d85f
KB
583{
584 int i;
c7fb814a 585 m_deleteContents = flag;
c801d85f
KB
586 for (i = 0; i < n; i++)
587 {
588 if (hash_table[i])
bcaa23de 589 hash_table[i]->DeleteContents (flag);
c801d85f
KB
590 }
591}
592
bcaa23de 593void wxHashTable::Clear ()
c801d85f
KB
594{
595 int i;
596 for (i = 0; i < n; i++)
597 {
598 if (hash_table[i])
bcaa23de 599 hash_table[i]->Clear ();
c801d85f 600 }
5692876f 601 m_count = 0;
c801d85f
KB
602}
603