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