2015-12-13 16:28:06 +03:00
|
|
|
#ifndef INCLUDE_COLLECTION_H
|
|
|
|
#define INCLUDE_COLLECTION_H
|
|
|
|
#print "[include <collection.h>]\n"
|
|
|
|
|
2020-05-23 14:26:58 +03:00
|
|
|
/*========================================================
|
|
|
|
= =
|
|
|
|
= Integer =
|
|
|
|
= =
|
|
|
|
========================================================*/
|
|
|
|
|
|
|
|
struct collection_int
|
|
|
|
{
|
|
|
|
dword buf;
|
|
|
|
dword buf_size;
|
|
|
|
unsigned count;
|
|
|
|
void alloc();
|
|
|
|
void add();
|
|
|
|
dword get();
|
|
|
|
void set();
|
|
|
|
void swap();
|
|
|
|
dword len();
|
|
|
|
dword get_last();
|
|
|
|
void pop();
|
|
|
|
void drop();
|
|
|
|
};
|
|
|
|
|
|
|
|
:void collection_int::alloc() {
|
|
|
|
if (!buf) {
|
|
|
|
buf_size = 4096;
|
|
|
|
buf = malloc(4096);
|
|
|
|
} else {
|
|
|
|
buf_size += 4096;
|
|
|
|
buf = realloc(buf, buf_size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
:void collection_int::add(dword _in) {
|
|
|
|
if (!buf) || (count * sizeof(dword) >= buf_size) alloc();
|
|
|
|
EAX = count * sizeof(dword) + buf;
|
|
|
|
ESDWORD[EAX] = _in;
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
:dword collection_int::get(dword pos) {
|
|
|
|
if (pos<0) || (pos>=count) return 0;
|
|
|
|
return ESDWORD[pos * sizeof(dword) + buf];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
:void collection_int::set(dword pos, _in) {
|
|
|
|
while (pos >= count) add(0);
|
|
|
|
EAX = pos * sizeof(dword) + buf;
|
|
|
|
ESDWORD[EAX] = _in;
|
|
|
|
}
|
|
|
|
|
|
|
|
:void collection_int::swap(dword pos1, pos2) {
|
|
|
|
while (pos1 >= count) add(0);
|
|
|
|
while (pos2 >= count) add(0);
|
|
|
|
EAX = pos1 * sizeof(dword) + buf;
|
|
|
|
EBX = pos2 * sizeof(dword) + buf;
|
|
|
|
ESDWORD[EAX] >< ESDWORD[EBX];
|
|
|
|
}
|
|
|
|
|
|
|
|
:dword collection_int::len(dword pos) {
|
|
|
|
if (pos<0) || (pos+1>=count) return 0;
|
|
|
|
return get(pos+1) - get(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
:dword collection_int::get_last() {
|
|
|
|
return get(count-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
:void collection_int::pop() {
|
|
|
|
if (count>0) count--;
|
|
|
|
}
|
|
|
|
|
|
|
|
:void collection_int::drop() {
|
|
|
|
count = 0;
|
|
|
|
}
|
|
|
|
|
2016-02-23 17:41:55 +03:00
|
|
|
/*========================================================
|
|
|
|
= =
|
|
|
|
= String =
|
|
|
|
= =
|
|
|
|
========================================================*/
|
|
|
|
|
2015-12-13 16:28:06 +03:00
|
|
|
struct collection
|
|
|
|
{
|
2015-12-15 19:18:38 +03:00
|
|
|
int realloc_size, count;
|
|
|
|
dword data_start;
|
2015-12-13 16:28:06 +03:00
|
|
|
dword data_size;
|
2020-05-23 14:26:58 +03:00
|
|
|
collection_int offset;
|
2015-12-15 19:18:38 +03:00
|
|
|
int add();
|
2017-10-05 01:59:57 +03:00
|
|
|
int addn();
|
2020-03-18 03:45:36 +03:00
|
|
|
dword get(); //get_name_by_pos
|
|
|
|
dword get_pos_by_name();
|
2015-12-13 16:28:06 +03:00
|
|
|
void drop();
|
2015-12-15 19:18:38 +03:00
|
|
|
void increase_data_size();
|
2020-05-06 18:53:34 +03:00
|
|
|
dword get_last();
|
2020-05-07 13:05:01 +03:00
|
|
|
bool pop();
|
2015-12-13 16:28:06 +03:00
|
|
|
};
|
|
|
|
|
2018-05-22 15:04:44 +03:00
|
|
|
:void collection::increase_data_size() {
|
2015-12-15 19:18:38 +03:00
|
|
|
int filled_size;
|
|
|
|
if (realloc_size<4096) realloc_size = 4096;
|
|
|
|
if (!data_size) {
|
|
|
|
data_size = realloc_size;
|
|
|
|
data_start = malloc(realloc_size);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
data_size = data_size + realloc_size;
|
|
|
|
data_start = realloc(data_start, data_size);
|
|
|
|
}
|
2015-12-13 16:28:06 +03:00
|
|
|
}
|
|
|
|
|
2018-05-22 15:04:44 +03:00
|
|
|
:int collection::add(dword in) {
|
2017-10-05 01:59:57 +03:00
|
|
|
return addn(in, strlen(in));
|
|
|
|
}
|
|
|
|
|
2018-05-22 15:04:44 +03:00
|
|
|
:int collection::addn(dword in, len) {
|
2020-05-23 14:26:58 +03:00
|
|
|
if (offset.get(count)+len+2 > data_size) {
|
2015-12-15 19:18:38 +03:00
|
|
|
increase_data_size();
|
2017-10-05 01:59:57 +03:00
|
|
|
addn(in, len);
|
|
|
|
return 1;
|
2015-12-15 19:18:38 +03:00
|
|
|
}
|
2020-05-23 14:26:58 +03:00
|
|
|
strncpy(data_start+offset.get(count), in, len);
|
2015-12-13 16:28:06 +03:00
|
|
|
count++;
|
2020-05-23 14:26:58 +03:00
|
|
|
offset.set(count, offset.get(count-1) + len + 1);
|
2015-12-15 19:18:38 +03:00
|
|
|
return 1;
|
2015-12-13 16:28:06 +03:00
|
|
|
}
|
|
|
|
|
2018-05-22 15:04:44 +03:00
|
|
|
:dword collection::get(dword pos) {
|
2015-12-16 19:13:34 +03:00
|
|
|
if (pos<0) || (pos>=count) return 0;
|
2020-05-23 14:26:58 +03:00
|
|
|
return data_start + offset.get(pos);
|
2015-12-13 16:28:06 +03:00
|
|
|
}
|
|
|
|
|
2020-05-06 18:53:34 +03:00
|
|
|
:dword collection::get_last() {
|
|
|
|
return get(count-1);
|
|
|
|
}
|
|
|
|
|
2020-03-18 03:45:36 +03:00
|
|
|
:dword collection::get_pos_by_name(dword name) {
|
|
|
|
dword i;
|
|
|
|
for (i=0; i<count; i++) {
|
2020-05-23 14:26:58 +03:00
|
|
|
if (strcmp(data_start + offset.get(i), name)==0) return i;
|
2020-03-18 03:45:36 +03:00
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2018-05-22 15:04:44 +03:00
|
|
|
:void collection::drop() {
|
2015-12-15 19:18:38 +03:00
|
|
|
if (data_start) free(data_start);
|
2020-04-10 19:19:52 +03:00
|
|
|
data_size = 0;
|
|
|
|
data_start = 0;
|
2020-05-23 14:26:58 +03:00
|
|
|
offset.drop();
|
2020-04-10 19:19:52 +03:00
|
|
|
count = 0;
|
2015-12-13 16:28:06 +03:00
|
|
|
}
|
|
|
|
|
2020-05-07 13:05:01 +03:00
|
|
|
:bool collection::pop() {
|
|
|
|
if (count>0) count--;
|
2020-05-06 18:53:34 +03:00
|
|
|
}
|
2016-02-23 17:41:55 +03:00
|
|
|
|
2015-12-13 16:28:06 +03:00
|
|
|
#endif
|