1 /******************************************************************************
2 *
3 * Copyright (C) 2006, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * ID: hash 18.10.06 0.0.A.
11 *
12 * Author: Alexey Krivonogov ( gentee )
13 *
14 ******************************************************************************/
15
16 #include "hash.h"
17 //! temporary
18 #include "../os/user/defines.h"
19
20 //--------------------------------------------------------------------------
21
22 void STDCALL hash_delete( phash ph )
23 {
24
25 arr_delete( &ph->values );
26 arr_delete( &ph->names );
27 }
28
29 //--------------------------------------------------------------------------
30
31 phashitem STDCALL _hash_find( phash ph, pubyte name, uint create )
32 {
33 pubyte ptr = name;
34 ushort val = 0;
35 uint len = 0;
36 ubyte shift = 0;
37 ushort nameoff;
38 phashitem phi = 0, prev = 0;
39
40 // Вычисляем хэш-значение строки
41 while ( *ptr )
42 {
43 if ( ph->ignore )
44 val += (( ushort )_lower[ *ptr++ ] ) << shift;
45 else
46 val += (( ushort )*ptr++ ) << shift;
47 if ( ++shift > 7 )
48 shift = 0;
49 len++;
50 }
51 // получаем номер в хэш-таблице
52 val &= HASH_SIZE - 1;
53 phi = prev = ( phashitem )arr_getuint( &ph->values, val );
54 nameoff = sizeof( hashitem ) + ph->isize;
55 while ( phi )
56 {
57 // printf("CMp <%s><%s> %i %i\n", name, ( pubyte )phi + nameoff, len, phi->len );
58 if ( len == phi->len && !( ph->ignore ?
59 mem_cmpign( name, ( pubyte )phi + nameoff, len ) :
60 mem_cmp( name, ( pubyte )phi + nameoff, len )))
61 // нашли совпадение
62 return phi;
63 phi = ( phashitem )phi->next;
64 }
65 if ( create )
66 {
67 // Будем добавлять элемент в таблицу имен
68 phi = ( phashitem )mem_alloc( nameoff + len + 1 );
69 phi->len = ( ushort )len;
70 phi->next = ( pvoid )prev;
71 phi->id = arr_count( &ph->names );
72 mem_zero( ( pubyte )phi + sizeof( hashitem ), ph->isize );
73 mem_copy( ( pubyte )phi + nameoff, name, len + 1 );
74 // printf("Append %x %s\n", phi, name );
75 arr_appendnum( &ph->names, ( uint )phi );
76 arr_setuint( &ph->values, val, ( uint )phi );
77 }
78 return phi;
79 }
80
81 //--------------------------------------------------------------------------
82
83 phashitem STDCALL hash_find( phash ph, pubyte name )
84 {
85 return _hash_find( ph, name, 0 );
86 }
87
88 //--------------------------------------------------------------------------
89
90 void STDCALL hash_init( phash ph, uint isize )
91 {
92 arr_init( &ph->values, sizeof( uint ));
93 arr_appenditems( &ph->values, HASH_SIZE );
94
95 arr_init( &ph->names, 0 );
96 arr_step( &ph->names, 512 );
97 ph->isize = isize;
98 ph->ignore = 0;
99 }
100
101 //--------------------------------------------------------------------------
102
103 phashitem STDCALL hash_create( phash ph, pubyte name )
104 {
105 return _hash_find( ph, name, 1 );
106 }
107
108 //--------------------------------------------------------------------------
109
110 uint STDCALL hash_getuint( phash ph, pubyte name )
111 {
112 phashitem phi = _hash_find( ph, name, 0 );
113 if ( phi )
114 return *( puint )( phi + 1 );
115 return 0;
116 }
117
118 //--------------------------------------------------------------------------
119
120 uint STDCALL hash_setuint( phash ph, pubyte name, uint val )
121 {
122 phashitem phi = _hash_find( ph, name, 1 );
123 *( puint )( phi + 1 ) = val;
124
125 return 1;
126 }
127
128 /*-----------------------------------------------------------------------------
129 *
130 * ID: hash_name 30.10.06 0.0.A.
131 *
132 * Summary: Get the object name from its id.
133 *
134 -----------------------------------------------------------------------------*/
135
136 pubyte STDCALL hash_name( phash ph, uint id )
137 {
138 if ( id >= arr_count( &ph->names ))
139 return NULL;
140 return ( pubyte )*(puint)arr_ptr( &ph->names, id ) + sizeof( hashitem ) +
141 ph->isize;
142 }
143
144 //--------------------------------------------------------------------------
145