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