1 #include <memory.h>
2 #include <assert.h>
3 #include <stdio.h>
4 #include "tmplvect.h"
5 #include "try.h"
6
7 /* PtrTry */
PtrTry(char letter)8 PtrTry::PtrTry(char letter)
9 {
10 _letter = letter;
11 _list = NULL;
12 _next = NULL;
13 }
14
~PtrTry()15 PtrTry::~PtrTry()
16 {
17 if (_next) {
18 int count = _next->Elements();
19 for (int i = 0; i < count; i++) {
20 delete _next->Element(i);
21 }
22 _next->Clear();
23 }
24 if (_list != NULL) _list->Clear();
25 }
26
27 /* ʸ�������ꤷ�ƥǡ������ɲä��� */
Add(void * newobj,char * key)28 void PtrTry::Add(void* newobj, char* key)
29 {
30 if (! *key) {
31 // ʸ����ü �����˥ǡ����ȥ�����
32 if (_list == NULL) _list = new PtrVect<void*>;
33 if (_list->Find(newobj) < 0) _list->Add(newobj);
34 } else {
35 // ����ʸ����õ��
36 if (!_next) {
37 _next = new PtrVect<PtrTry*>;
38 } else {
39 int count = _next->Elements();
40 for (int i = 0; i < count; i++) {
41 if (_next->Element(i)->_letter == *key) {
42 key++;
43 _next->Element(i)->Add(newobj, key);
44 return;
45 }
46 }
47 }
48 PtrTry* newTry = new PtrTry(*key);
49 key++;
50 _next->Add(newTry);
51 newTry->Add(newobj, key);
52 }
53 }
54
55 /* key ��õ������������ꥹ�Ȥ��֤�
56 �ꥹ�Ȥ����ξ�硢 NULL ���֤� */
Find(const char * key,PtrVect<void * > & result,char cond) const57 void PtrTry::Find(const char* key, PtrVect<void*>& result, char cond) const
58 {
59 if (! *key) {
60 // �����ǥޥå�����
61 if (_list != NULL) {
62 result = *_list;
63 return;
64 }
65 if (cond != MATCH_LONGER) {
66 result.Clear();
67 return;
68 }
69 result.Clear();
70 if (!_next) return;
71 int count = _next->Elements();
72 PtrVect<void*> tmplist;
73 for (int i = 0; i < count; i++) {
74 _next->Element(i)->Find(key, tmplist, cond);
75 result += tmplist;
76 }
77 return;
78 }
79 if (_next == NULL) {
80 // ����ʾ���פ���ꥹ�Ȥ�¸�ߤ��ʤ�
81 if (cond == MATCH_EXACT) {
82 result.Clear();
83 return;
84 } else {
85 if (_list) {
86 result = *_list;
87 } else {
88 result.Clear();
89 }
90 return;
91 }
92 }
93 int count = _next->Elements();
94 PtrVect<void*> list;
95 for (int i = 0; i < count; i++) {
96 if (_next->Element(i)->_letter == *key) {
97 key++;
98 _next->Element(i)->Find(key, list, cond);
99 if (list.Elements() > 0 || cond == MATCH_EXACT) {
100 result = list;
101 return;
102 }
103 if (_list != NULL) {
104 result = *_list;
105 return;
106 }
107 break;
108 }
109 }
110 if (_list) result = *_list;
111 else result.Clear();
112 return; // ����ʾ���פ��ʤ��Τǡ���Ĺ���פ��֤�
113 }
114
Remove(void * obj,char * key)115 void PtrTry::Remove(void* obj, char* key)
116 {
117 if (! *key) {
118 if (_list) {
119 _list->Remove(obj);
120 }
121 return;
122 }
123 if (_next == NULL) return;
124 int count = _next->Elements();
125 for (int i = 0; i < count; i++) {
126 if (_next->Element(i)->_letter == *key) {
127 key++;
128 _next->Element(i)->Remove(obj, key);
129 return;
130 }
131 }
132 return; // ��������ǡ���̵��
133 }
134
Clear(void)135 void PtrTry::Clear(void)
136 {
137 _letter = 0;
138 delete _list;
139 _list = NULL;
140 if (_next) {
141 _next->ClearElements();
142 }
143 delete _next;
144 _next = NULL;
145 }
146
147 unsigned int statics[STATICS_SIZE];
148
MakeStatics(void)149 void PtrTry::MakeStatics(void)
150 {
151 if (!_next) {
152 statics[0]++;
153 return;
154 }
155 int count = _next->Elements();
156 if (count < STATICS_SIZE - 1) statics[count]++;
157 else statics[STATICS_SIZE - 1]++;
158 for (int i = 0; i < count; i++) {
159 _next->Element(i)->MakeStatics();
160 }
161 }
162
QSort(int (* fcmp)(const void *,const void *))163 void PtrTry::QSort(int (*fcmp)(const void*, const void*))
164 {
165 if (_list) _list->QSort(fcmp);
166 if (_next) {
167 int count = _next->Elements();
168 for (int i = 0; i < count; i++) {
169 _next->Element(i)->QSort(fcmp);
170 }
171 }
172 }
173
174 /* StaticPtrTry */
offset(void * p,long base)175 static void* offset(void* p, long base) {
176 return (void*)((char*)p + base);
177 }
178
StaticPtrTry(PtrTry * key)179 StaticPtrTry::StaticPtrTry(PtrTry* key) {
180 int i;
181 _letter = key->_letter;
182 if (key->_list) {
183 _nList = key->_list->Elements();
184 _pList = (long*)malloc(sizeof(long) * _nList);
185 } else {
186 _nList = 0;
187 _pList = NULL;
188 }
189 if (key->_next) {
190 _nNext = key->_next->Elements();
191 _pNext = (StaticPtrTry**)malloc(sizeof(StaticPtrTry*) * _nNext);
192 } else {
193 _nNext = 0;
194 _pNext = NULL;
195 }
196 for (i = 0; i < _nList; i++) {
197 _pList[i] = long(key->_list->Element(i));
198 }
199 for (i = 0; i < _nNext; i++) {
200 _pNext[i] = new StaticPtrTry(key->_next->Element(i));
201 }
202 }
203
packedSize(void)204 unsigned long StaticPtrTry::packedSize(void) {
205 unsigned long size = sizeof(StaticPtrTry);
206 size += sizeof(long) * this->_nList;
207 size += sizeof(StaticPtrTry*) * this->_nNext;
208 for (int i = 0; i < this->_nNext; i++) {
209 size += this->_pNext[i]->packedSize();
210 }
211 return size;
212 }
213
pack(StaticPtrTry * newaddress,long base)214 StaticPtrTry* StaticPtrTry::pack(StaticPtrTry* newaddress, long base) {
215 int i;
216 char* cp = (char*)newaddress;
217 StaticPtrTry* newnode = (StaticPtrTry*)(offset(newaddress, base));
218 memcpy(newnode, this, sizeof(StaticPtrTry));
219 cp += sizeof(StaticPtrTry);
220 memcpy(offset(cp, base), this->_pList, sizeof(long) * this->_nList);
221 newnode->_pList = (long*)cp;
222 cp += sizeof(long) * this->_nList;
223 newnode->_pNext = (StaticPtrTry**)cp;
224 cp += sizeof(StaticPtrTry*) * this->_nNext;
225
226 StaticPtrTry** pp;
227 for (i = 0; i < this->_nNext; i++) {
228 pp = (StaticPtrTry**)(offset(newnode->_pNext + i, base));
229 *pp = (StaticPtrTry*)cp;
230 cp = (char*)(this->_pNext[i]->pack((StaticPtrTry*)cp, base));
231 }
232 return (StaticPtrTry*)cp;
233 }
234
235 /* key ��õ������������ꥹ�Ȥ��֤�
236 �ꥹ�Ȥ����ξ�硢 NULL ���֤� */
Find(const char * key,PtrVect<long> & result,char cond,long base)237 void StaticPtrTry::Find(const char* key, PtrVect<long>& result, char cond, long base)
238 {
239 int i;
240 StaticPtrTry* node;
241 if (! *key) {
242 // �����ǥޥå�����
243 if (_nList > 0) {
244 result.Clear();
245 for (i = 0; i < _nList; i++) {
246 result.Add(this->list(i, base));
247 }
248 return;
249 }
250 if (cond != MATCH_LONGER) {
251 result.Clear();
252 return;
253 }
254 result.Clear();
255 if (_nNext == 0) return;
256 int count = _nNext;
257 PtrVect<long> tmplist;
258 for (i = 0; i < count; i++) {
259 node = next(i, base);
260 node->Find(key, tmplist, cond, base);
261 result += tmplist;
262 }
263 return;
264 }
265 if (_nNext == 0) {
266 // ����ʾ���פ���ꥹ�Ȥ�¸�ߤ��ʤ�
267 if (cond == MATCH_EXACT) {
268 result.Clear();
269 return;
270 } else {
271 if (_nList > 0) {
272 result.Clear();
273 for (i = 0; i < _nList; i++) {
274 result.Add(this->list(i, base));
275 }
276 } else {
277 result.Clear();
278 }
279 return;
280 }
281 }
282 int count = _nNext;
283 PtrVect<long> list;
284 StaticPtrTry** pp;
285 for (int i = 0; i < count; i++) {
286 node = this->next(i, base);
287 if (node->_letter == *key) {
288 key++;
289 node->Find(key, list, cond, base);
290 if (list.Elements() > 0 || cond == MATCH_EXACT) {
291 result = list;
292 return;
293 }
294 if (_nList > 0) {
295 result.Clear();
296 for (i = 0; i < _nList; i++) {
297 result.Add(this->list(i, base));
298 }
299 return;
300 }
301 break;
302 }
303 }
304 result.Clear();
305 if (_nList > 0) {
306 for (i = 0; i < _nList; i++) {
307 result.Add(this->list(i, base));
308 }
309 }
310 return; // ����ʾ���פ��ʤ��Τǡ���Ĺ���פ��֤�
311 }
312
list(int i,long base)313 long StaticPtrTry::list(int i, long base) {
314 long l;
315 l = *(long*)(offset(_pList + i, base));
316 return l;
317 }
318
next(int i,long base)319 StaticPtrTry* StaticPtrTry::next(int i, long base) {
320 StaticPtrTry* p;
321 p = *(StaticPtrTry**)(offset(_pNext + i, base));
322 p = (StaticPtrTry*)(offset(p, base));
323 return p;
324 }
325