1 /*
2 * Seven Kingdoms: Ancient Adversaries
3 *
4 * Copyright 1997,1998 Enlight Software Ltd.
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21 //Filename :: ODYNARR.H
22 //Description :: Dynamic Array Object
23
24 #ifndef __ODYNARR_H
25 #define __ODYNARR_H
26
27 #ifndef __ALL_H
28 #include <ALL.h>
29 #endif
30
31 #ifndef __STRING_H
32 #include <string.h>
33 #endif
34
35
36 //--------- Define constant ------------//
37
38 #define DEF_DYNARRAY_BLOCK_SIZE 30 // default allocation block size (no. of unities each block has)
39
40 //---------- Define sort types --------//
41
42 enum { SORT_INT=1,
43 SORT_SHORT,
44 SORT_CHAR,
45 SORT_CHAR_PTR,
46 SORT_CHAR_STR };
47
48
49 //-------- BEGIN OF CLASS DynArrary ---------//
50
51 #pragma pack(1)
52 class DynArray
53 {
54 public :
55
56 int ele_num; // the size of the whole array
57 int block_num; // the number of element of each block
58 int cur_pos; // current position
59 int last_ele; // last element position ( the array is not fully used )
60 int ele_size; // the size of each element
61
62 int sort_offset;
63 char sort_type;
64
65 short body_lock_cnt;
66 char* body_buf; // cur_pos and last_ele are start from 1 (not 0)
67
68 //----------------------------------------------//
69
70 public :
71
72 DynArray(int,int=DEF_DYNARRAY_BLOCK_SIZE);
73 ~DynArray();
74
75 void resize(int);
lock_body()76 void lock_body() { body_lock_cnt++; };
unlock_body()77 void unlock_body() { body_lock_cnt--; };
78
79 void linkin(const void*);
80 void linkin_unique(const void*);
81 void linkout(int= -1);
82 void update(const void*, int= -1);
83 void insert(const void*);
84 void insert_at(int,const void*);
85 void add_blank(int);
86
87 void init_sort(int,char);
88 void linkin_sort_scan_from_bottom(void*);
89 // void resort(int);
90
91 void* get();
92 void* get(int);
93 void* get_ptr() const;
94 void* get_ptr(int) const;
95 void read(void*);
96
97 int check_pos();
98
99 void push(const void*);
100 void pop(void* =0);
101
102 void start();
103 void end();
104 int fwd();
105 int bkwd();
106
107 void jump(int);
108 void go(int);
109 int recno();
110 int size() const;
111
112 int is_start();
113 int is_end();
114
115 int scan_whole(void*);
116 int scan(void*,int,char,int=0);
117 int compare(void*,int,char);
118
119 void quick_sort( int(*cmpFun)(const void*, const void*) );
120
121 void clean_up(int* =0);
122 void free_ptr(void*,int*);
123 void zap(int resizeFlag=1);
124
125 int write_file(File*); // Write current dynamic array to file
126 int read_file(File*); // Read dynamic array from file
127 };
128 #pragma pack()
129
130 //--------- END OF CLASS DynArray ---------//
131
132
133 //--------- BEGIN OF FUNCTION DynArray::get -----------//
134 //
135 // Return : the memory pointer to the body_buf of current element
136 // NULL if the record no. is invalid.
137 //
get()138 inline void* DynArray::get()
139 {
140 if( cur_pos == 0 )
141 return NULL;
142
143 return (void*) (body_buf+(cur_pos-1)*ele_size);
144 }
145
get(int specRec)146 inline void* DynArray::get(int specRec)
147 {
148 if( specRec<1 || specRec>last_ele )
149 return NULL;
150
151 return (void*) (body_buf+(specRec-1)*ele_size);
152 }
153
154 //--------- END OF FUNCTION DynArray::get -----------//
155
156
157 //--------- BEGIN OF FUNCTION DynArray::get_ptr -----------//
158 //
159 // The content of the entry is a pointer, return the content
160 // is a pointer
161 //
162 // Return : the pointer
163 // NULL if the record no. is invalid.
164
get_ptr()165 inline void* DynArray::get_ptr() const
166 {
167 if( cur_pos == 0 )
168 return NULL;
169
170 return (void*) *((char**)(body_buf+(cur_pos-1)*ele_size));
171 }
172
get_ptr(int specRec)173 inline void* DynArray::get_ptr(int specRec) const
174 {
175 if( specRec < 1 || specRec > last_ele )
176 return NULL;
177
178 return (void*) *((char**)(body_buf+(specRec-1)*ele_size));
179 }
180
181 //--------- END OF FUNCTION DynArray::get_ptr -----------//
182
183
184 //--------- BEGIN OF FUNCTION DynArray::read -----------//
185 //
186 // Read current record into the given buffer
187 //
read(void * ent)188 inline void DynArray::read(void* ent)
189 {
190 if( ent )
191 memcpy(ent, get(), ele_size );
192 }
193 //---------- END OF FUNCTION DynArray::read -----------//
194
195
196
197 //--------- BEGIN OF FUNCTIONO DynArray::push,pop -----------//
198
199 // <void*> ent = the address of the entity to be linked into the array
200
push(const void * ent)201 inline void DynArray::push(const void* ent)
202 {
203 linkin(ent);
204 }
205
206 // [void*] ent = the address of the entity to be overwritten by current element
207
pop(void * ent)208 inline void DynArray::pop(void* ent)
209 {
210 end();
211 read(ent);
212 linkout();
213 }
214
215 //----------- END OF FUNCTION DynArray::push,pop ----------//
216
217
218 //-------- BEGIN OF FUNCTIONO DynArray::start,end,fwd,bkwd -------------//
219 //
start()220 inline void DynArray::start()
221 {
222 cur_pos = MIN(1,last_ele);
223 }
224
end()225 inline void DynArray::end()
226 {
227 cur_pos = last_ele;
228 }
229
fwd()230 inline int DynArray::fwd()
231 {
232 if (cur_pos < last_ele )
233 {
234 cur_pos++;
235 return 1;
236 }
237 else
238 return 0;
239 }
240
bkwd()241 inline int DynArray::bkwd()
242 {
243 if (cur_pos > 1)
244 {
245 cur_pos--;
246 return 1;
247 }
248 else
249 return 0;
250 }
251
252 //---------- END OF FUNCTION DynArray::start,end,fwd,bkwd ---------//
253
254
255 //--------- BEGIN OF FUNCTION DynArray::jump,go,pos,size ----------//
256
257
jump(int step)258 inline void DynArray::jump(int step)
259 {
260 cur_pos+=step;
261
262 if ( cur_pos < 0 )
263 cur_pos = MIN(1,last_ele) ;
264
265 if ( cur_pos > last_ele )
266 cur_pos = last_ele;
267 }
268
269
go(int desPos)270 inline void DynArray::go(int desPos)
271 {
272 if ( desPos >= 1 && desPos <= last_ele )
273 cur_pos = desPos;
274 }
275
recno()276 inline int DynArray::recno()
277 {
278 return cur_pos;
279 }
280
size()281 inline int DynArray::size() const
282 {
283 return last_ele;
284 }
285
286 //----------- END OF FUNCTION DynArray::jump,go,pos,size ---------//
287
288
289 //-------- BEGIN OF FUNCTION DynArray::isstart,isend ------//
290
is_start()291 inline int DynArray::is_start()
292 {
293 return( cur_pos <= 1 );
294 }
295
is_end()296 inline int DynArray::is_end()
297 {
298 return( cur_pos >= last_ele );
299 }
300
301 //-------- END OF FUNCTION DynArray::isstart,isend --------//
302
303
304
305 #endif
306