]> git.saurik.com Git - wxWidgets.git/blame - src/common/hash.cpp
added GetBorder(flags)
[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$
55d99c7a 8// Copyright: (c) Julian Smart
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{
3ca6a5f0 107 size_t slot = (size_t)abs((int)(key % (long)m_hashSize));
bcaa23de
VZ
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
ba8c1601
MB
122#if WXWIN_COMPATIBILITY_2_4
123
c2bb85e9
VZ
124// ----------------------------------------------------------------------------
125// wxHashTableLong
126// ----------------------------------------------------------------------------
127
a95e38c0
VZ
128wxHashTableLong::~wxHashTableLong()
129{
130 Destroy();
131}
132
c2bb85e9
VZ
133void wxHashTableLong::Init(size_t size)
134{
135 m_hashSize = size;
136 m_values = new wxArrayLong *[size];
137 m_keys = new wxArrayLong *[size];
138
139 for ( size_t n = 0; n < m_hashSize; n++ )
140 {
141 m_values[n] =
142 m_keys[n] = (wxArrayLong *)NULL;
143 }
144
145 m_count = 0;
146}
147
b7aaabf8
VS
148void wxHashTableLong::Create(size_t size)
149{
150 Init(size);
151}
152
c2bb85e9
VZ
153void wxHashTableLong::Destroy()
154{
155 for ( size_t n = 0; n < m_hashSize; n++ )
156 {
157 delete m_values[n];
158 delete m_keys[n];
159 }
160
161 delete [] m_values;
162 delete [] m_keys;
163 m_hashSize = 0;
164 m_count = 0;
165}
166
167void wxHashTableLong::Put(long key, long value)
168{
169 wxCHECK_RET( m_hashSize, _T("must call Create() first") );
170
3ca6a5f0 171 size_t slot = (size_t)abs((int)(key % (long)m_hashSize));
c2bb85e9
VZ
172
173 if ( !m_keys[slot] )
174 {
175 m_keys[slot] = new wxArrayLong;
176 m_values[slot] = new wxArrayLong;
177 }
178
179 m_keys[slot]->Add(key);
180 m_values[slot]->Add(value);
181
182 m_count++;
183}
184
185long wxHashTableLong::Get(long key) const
186{
187 wxCHECK_MSG( m_hashSize, wxNOT_FOUND, _T("must call Create() first") );
188
3ca6a5f0 189 size_t slot = (size_t)abs((int)(key % (long)m_hashSize));
c2bb85e9
VZ
190
191 wxArrayLong *keys = m_keys[slot];
192 if ( keys )
193 {
194 size_t count = keys->GetCount();
195 for ( size_t n = 0; n < count; n++ )
196 {
197 if ( keys->Item(n) == key )
198 {
199 return m_values[slot]->Item(n);
200 }
201 }
202 }
203
204 return wxNOT_FOUND;
205}
206
207long wxHashTableLong::Delete(long key)
208{
209 wxCHECK_MSG( m_hashSize, wxNOT_FOUND, _T("must call Create() first") );
210
3ca6a5f0 211 size_t slot = (size_t)abs((int)(key % (long)m_hashSize));
c2bb85e9
VZ
212
213 wxArrayLong *keys = m_keys[slot];
214 if ( keys )
215 {
216 size_t count = keys->GetCount();
217 for ( size_t n = 0; n < count; n++ )
218 {
219 if ( keys->Item(n) == key )
220 {
221 long val = m_values[slot]->Item(n);
222
223 keys->RemoveAt(n);
224 m_values[slot]->RemoveAt(n);
225
226 m_count--;
227
228 return val;
229 }
230 }
231 }
232
233 return wxNOT_FOUND;
234}
235
bd83cb56
VZ
236// ----------------------------------------------------------------------------
237// wxStringHashTable: more efficient than storing strings in a list
238// ----------------------------------------------------------------------------
239
240wxStringHashTable::wxStringHashTable(size_t sizeTable)
241{
242 m_keys = new wxArrayLong *[sizeTable];
243 m_values = new wxArrayString *[sizeTable];
244
245 m_hashSize = sizeTable;
246 for ( size_t n = 0; n < m_hashSize; n++ )
247 {
248 m_values[n] = (wxArrayString *)NULL;
249 m_keys[n] = (wxArrayLong *)NULL;
250 }
251}
252
253wxStringHashTable::~wxStringHashTable()
254{
255 Destroy();
256}
257
258void wxStringHashTable::Destroy()
259{
260 for ( size_t n = 0; n < m_hashSize; n++ )
261 {
262 delete m_values[n];
263 delete m_keys[n];
264 }
265
266 delete [] m_values;
267 delete [] m_keys;
268 m_hashSize = 0;
269}
270
271void wxStringHashTable::Put(long key, const wxString& value)
272{
273 wxCHECK_RET( m_hashSize, _T("must call Create() first") );
274
275 size_t slot = (size_t)abs((int)(key % (long)m_hashSize));
276
277 if ( !m_keys[slot] )
278 {
279 m_keys[slot] = new wxArrayLong;
280 m_values[slot] = new wxArrayString;
281 }
282
283 m_keys[slot]->Add(key);
284 m_values[slot]->Add(value);
285}
286
287wxString wxStringHashTable::Get(long key, bool *wasFound) const
288{
289 wxCHECK_MSG( m_hashSize, _T(""), _T("must call Create() first") );
290
291 size_t slot = (size_t)abs((int)(key % (long)m_hashSize));
292
293 wxArrayLong *keys = m_keys[slot];
294 if ( keys )
295 {
296 size_t count = keys->GetCount();
297 for ( size_t n = 0; n < count; n++ )
298 {
299 if ( keys->Item(n) == key )
300 {
301 if ( wasFound )
302 *wasFound = TRUE;
303
304 return m_values[slot]->Item(n);
305 }
306 }
307 }
308
309 if ( wasFound )
310 *wasFound = FALSE;
311
312 return _T("");
313}
314
53e112a0
JS
315bool wxStringHashTable::Delete(long key) const
316{
317 wxCHECK_MSG( m_hashSize, FALSE, _T("must call Create() first") );
318
319 size_t slot = (size_t)abs((int)(key % (long)m_hashSize));
320
321 wxArrayLong *keys = m_keys[slot];
322 if ( keys )
323 {
324 size_t count = keys->GetCount();
325 for ( size_t n = 0; n < count; n++ )
326 {
327 if ( keys->Item(n) == key )
328 {
f8305caf 329 keys->RemoveAt(n);
53e112a0
JS
330 m_values[slot]->RemoveAt(n);
331 return TRUE;
332 }
333 }
334 }
335
336 return FALSE;
337}
338
ba8c1601
MB
339#endif // WXWIN_COMPATIBILITY_2_4
340
bcaa23de
VZ
341// ----------------------------------------------------------------------------
342// old not type safe wxHashTable
343// ----------------------------------------------------------------------------
344
debe6624 345wxHashTable::wxHashTable (int the_key_type, int size)
c801d85f 346{
17d8ee1c
JS
347 n = 0;
348 hash_table = (wxList**) NULL;
349 Create(the_key_type, size);
5692876f 350 m_count = 0;
c7fb814a 351 m_deleteContents = FALSE;
17d8ee1c 352/*
c801d85f
KB
353 n = size;
354 current_position = -1;
c67daf87 355 current_node = (wxNode *) NULL;
c801d85f
KB
356
357 key_type = the_key_type;
358 hash_table = new wxList *[size];
359 int i;
360 for (i = 0; i < size; i++)
c67daf87 361 hash_table[i] = (wxList *) NULL;
17d8ee1c 362*/
c801d85f
KB
363}
364
bcaa23de 365wxHashTable::~wxHashTable ()
c801d85f 366{
e55ad60e
RR
367 Destroy();
368}
369
bcaa23de 370void wxHashTable::Destroy()
e55ad60e
RR
371{
372 if (!hash_table) return;
c801d85f
KB
373 int i;
374 for (i = 0; i < n; i++)
375 if (hash_table[i])
376 delete hash_table[i];
377 delete[] hash_table;
e55ad60e 378 hash_table = NULL;
c801d85f
KB
379}
380
debe6624 381bool wxHashTable::Create(int the_key_type, int size)
c801d85f 382{
17d8ee1c
JS
383 Destroy();
384
c801d85f
KB
385 n = size;
386 current_position = -1;
c67daf87 387 current_node = (wxNode *) NULL;
c801d85f
KB
388
389 key_type = the_key_type;
c801d85f
KB
390 hash_table = new wxList *[size];
391 int i;
392 for (i = 0; i < size; i++)
c67daf87 393 hash_table[i] = (wxList *) NULL;
c801d85f
KB
394 return TRUE;
395}
396
4e67bfc7
VS
397
398void wxHashTable::DoCopy(const wxHashTable& table)
399{
400 n = table.n;
ea450825 401 m_count = table.m_count;
4e67bfc7
VS
402 current_position = table.current_position;
403 current_node = NULL; // doesn't matter - Next() will reconstruct it
404 key_type = table.key_type;
405
406 hash_table = new wxList *[n];
407 for (int i = 0; i < n; i++) {
408 if (table.hash_table[i] == NULL)
409 hash_table[i] = NULL;
410 else {
411 hash_table[i] = new wxList(key_type);
412 *(hash_table[i]) = *(table.hash_table[i]);
413 }
414 }
415}
416
debe6624 417void wxHashTable::Put (long key, long value, wxObject * object)
c801d85f
KB
418{
419 // Should NEVER be
420 long k = (long) key;
c801d85f
KB
421
422 int position = (int) (k % n);
ffae916f
BJ
423 if (position < 0) position = -position;
424
c801d85f 425 if (!hash_table[position])
c7fb814a 426 {
cbb26e3f 427 hash_table[position] = new wxList (wxKEY_INTEGER);
c7fb814a
VS
428 if (m_deleteContents) hash_table[position]->DeleteContents(TRUE);
429 }
c801d85f
KB
430
431 hash_table[position]->Append (value, object);
5692876f 432 m_count++;
c801d85f
KB
433}
434
50920146 435void wxHashTable::Put (long key, const wxChar *value, wxObject * object)
c801d85f
KB
436{
437 // Should NEVER be
bcaa23de 438 long k = (long) key;
c801d85f
KB
439
440 int position = (int) (k % n);
ffae916f 441 if (position < 0) position = -position;
bcaa23de 442
c801d85f 443 if (!hash_table[position])
c7fb814a 444 {
cbb26e3f 445 hash_table[position] = new wxList (wxKEY_STRING);
c7fb814a
VS
446 if (m_deleteContents) hash_table[position]->DeleteContents(TRUE);
447 }
c801d85f
KB
448
449 hash_table[position]->Append (value, object);
5692876f 450 m_count++;
c801d85f
KB
451}
452
debe6624 453void wxHashTable::Put (long key, wxObject * object)
c801d85f
KB
454{
455 // Should NEVER be
456 long k = (long) key;
bcaa23de 457
c801d85f 458 int position = (int) (k % n);
ffae916f
BJ
459 if (position < 0) position = -position;
460
c801d85f 461 if (!hash_table[position])
c7fb814a 462 {
c801d85f 463 hash_table[position] = new wxList (wxKEY_INTEGER);
c7fb814a
VS
464 if (m_deleteContents) hash_table[position]->DeleteContents(TRUE);
465 }
bcaa23de 466
c801d85f 467 hash_table[position]->Append (k, object);
5692876f 468 m_count++;
c801d85f
KB
469}
470
50920146 471void wxHashTable::Put (const wxChar *key, wxObject * object)
c801d85f
KB
472{
473 int position = (int) (MakeKey (key) % n);
ffae916f 474 if (position < 0) position = -position;
c801d85f
KB
475
476 if (!hash_table[position])
c7fb814a 477 {
c801d85f 478 hash_table[position] = new wxList (wxKEY_STRING);
c7fb814a
VS
479 if (m_deleteContents) hash_table[position]->DeleteContents(TRUE);
480 }
c801d85f
KB
481
482 hash_table[position]->Append (key, object);
5692876f 483 m_count++;
c801d85f
KB
484}
485
debe6624 486wxObject *wxHashTable::Get (long key, long value) const
c801d85f
KB
487{
488 // Should NEVER be
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)
b1d4dd7a 500 return node->GetData ();
c801d85f 501 else
bcaa23de 502 return (wxObject *) NULL;
c801d85f
KB
503 }
504}
505
50920146 506wxObject *wxHashTable::Get (long key, const wxChar *value) const
c801d85f
KB
507{
508 // Should NEVER be
509 long k = (long) key;
bcaa23de 510
c801d85f 511 int position = (int) (k % n);
ffae916f
BJ
512 if (position < 0) position = -position;
513
c801d85f 514 if (!hash_table[position])
c67daf87 515 return (wxObject *) NULL;
c801d85f
KB
516 else
517 {
518 wxNode *node = hash_table[position]->Find (value);
519 if (node)
b1d4dd7a 520 return node->GetData ();
c801d85f 521 else
bcaa23de 522 return (wxObject *) NULL;
c801d85f
KB
523 }
524}
525
debe6624 526wxObject *wxHashTable::Get (long key) const
c801d85f
KB
527{
528 // Should NEVER be
529 long k = (long) key;
c801d85f
KB
530
531 int position = (int) (k % n);
ffae916f
BJ
532 if (position < 0) position = -position;
533
c801d85f 534 if (!hash_table[position])
c67daf87 535 return (wxObject *) NULL;
c801d85f
KB
536 else
537 {
538 wxNode *node = hash_table[position]->Find (k);
b1d4dd7a 539 return node ? node->GetData () : (wxObject*)NULL;
c801d85f
KB
540 }
541}
542
50920146 543wxObject *wxHashTable::Get (const wxChar *key) const
c801d85f
KB
544{
545 int position = (int) (MakeKey (key) % n);
ffae916f 546 if (position < 0) position = -position;
c801d85f
KB
547
548 if (!hash_table[position])
c67daf87 549 return (wxObject *) NULL;
c801d85f
KB
550 else
551 {
552 wxNode *node = hash_table[position]->Find (key);
b1d4dd7a 553 return node ? node->GetData () : (wxObject*)NULL;
c801d85f
KB
554 }
555}
556
debe6624 557wxObject *wxHashTable::Delete (long key)
c801d85f
KB
558{
559 // Should NEVER be
560 long k = (long) key;
c801d85f
KB
561
562 int position = (int) (k % n);
ffae916f
BJ
563 if (position < 0) position = -position;
564
c801d85f 565 if (!hash_table[position])
c67daf87 566 return (wxObject *) NULL;
c801d85f
KB
567 else
568 {
569 wxNode *node = hash_table[position]->Find (k);
570 if (node)
bcaa23de 571 {
b1d4dd7a 572 wxObject *data = node->GetData ();
bcaa23de
VZ
573 delete node;
574 m_count--;
575 return data;
576 }
c801d85f 577 else
bcaa23de 578 return (wxObject *) NULL;
c801d85f
KB
579 }
580}
581
50920146 582wxObject *wxHashTable::Delete (const wxChar *key)
c801d85f
KB
583{
584 int position = (int) (MakeKey (key) % n);
ffae916f
BJ
585 if (position < 0) position = -position;
586
c801d85f 587 if (!hash_table[position])
c67daf87 588 return (wxObject *) NULL;
c801d85f
KB
589 else
590 {
591 wxNode *node = hash_table[position]->Find (key);
592 if (node)
bcaa23de 593 {
b1d4dd7a 594 wxObject *data = node->GetData ();
bcaa23de
VZ
595 delete node;
596 m_count--;
597 return data;
598 }
c801d85f 599 else
bcaa23de 600 return (wxObject *) NULL;
c801d85f
KB
601 }
602}
603
debe6624 604wxObject *wxHashTable::Delete (long key, int value)
c801d85f
KB
605{
606 // Should NEVER be
bcaa23de 607 long k = (long) key;
c801d85f
KB
608
609 int position = (int) (k % n);
ffae916f
BJ
610 if (position < 0) position = -position;
611
c801d85f 612 if (!hash_table[position])
c67daf87 613 return (wxObject *) NULL;
c801d85f
KB
614 else
615 {
616 wxNode *node = hash_table[position]->Find (value);
617 if (node)
bcaa23de 618 {
b1d4dd7a 619 wxObject *data = node->GetData ();
bcaa23de
VZ
620 delete node;
621 m_count--;
622 return data;
623 }
c801d85f 624 else
bcaa23de 625 return (wxObject *) NULL;
c801d85f
KB
626 }
627}
628
50920146 629wxObject *wxHashTable::Delete (long key, const wxChar *value)
c801d85f
KB
630{
631 int position = (int) (key % n);
ffae916f
BJ
632 if (position < 0) position = -position;
633
c801d85f 634 if (!hash_table[position])
c67daf87 635 return (wxObject *) NULL;
c801d85f
KB
636 else
637 {
638 wxNode *node = hash_table[position]->Find (value);
639 if (node)
bcaa23de 640 {
b1d4dd7a 641 wxObject *data = node->GetData ();
bcaa23de
VZ
642 delete node;
643 m_count--;
644 return data;
645 }
c801d85f 646 else
bcaa23de 647 return (wxObject *) NULL;
c801d85f
KB
648 }
649}
650
50920146 651long wxHashTable::MakeKey (const wxChar *string) const
c801d85f
KB
652{
653 long int_key = 0;
654
655 while (*string)
50920146 656 int_key += (wxUChar) *string++;
c801d85f
KB
657
658 return int_key;
659}
660
bcaa23de 661void wxHashTable::BeginFind ()
c801d85f
KB
662{
663 current_position = -1;
c67daf87 664 current_node = (wxNode *) NULL;
c801d85f
KB
665}
666
bcaa23de 667wxNode *wxHashTable::Next ()
c801d85f 668{
c67daf87 669 wxNode *found = (wxNode *) NULL;
c801d85f
KB
670 bool end = FALSE;
671 while (!end && !found)
672 {
673 if (!current_node)
bcaa23de
VZ
674 {
675 current_position++;
676 if (current_position >= n)
677 {
678 current_position = -1;
679 current_node = (wxNode *) NULL;
680 end = TRUE;
681 }
682 else
683 {
684 if (hash_table[current_position])
685 {
b1d4dd7a 686 current_node = hash_table[current_position]->GetFirst ();
bcaa23de
VZ
687 found = current_node;
688 }
689 }
690 }
c801d85f 691 else
bcaa23de 692 {
b1d4dd7a 693 current_node = current_node->GetNext ();
bcaa23de
VZ
694 found = current_node;
695 }
c801d85f
KB
696 }
697 return found;
698}
699
debe6624 700void wxHashTable::DeleteContents (bool flag)
c801d85f
KB
701{
702 int i;
c7fb814a 703 m_deleteContents = flag;
c801d85f
KB
704 for (i = 0; i < n; i++)
705 {
706 if (hash_table[i])
bcaa23de 707 hash_table[i]->DeleteContents (flag);
c801d85f
KB
708 }
709}
710
bcaa23de 711void wxHashTable::Clear ()
c801d85f 712{
19230604
RD
713 int i;
714 if (hash_table)
c801d85f 715 {
19230604
RD
716 for (i = 0; i < n; i++)
717 {
718 if (hash_table[i])
719 hash_table[i]->Clear ();
720 }
c801d85f 721 }
5692876f 722 m_count = 0;
c801d85f
KB
723}
724