2018-10-01 10:58:21 +02:00
|
|
|
// Author: Pavel Iakovlev by. pavelyakov
|
|
|
|
|
2018-11-01 22:48:33 +01:00
|
|
|
#ifndef INCLUDE_ARRAY_H
|
|
|
|
#define INCLUDE_ARRAY_H
|
2018-10-01 10:58:21 +02:00
|
|
|
|
2020-03-21 14:38:17 +01:00
|
|
|
#include "../lib/crc32.h"
|
|
|
|
|
2018-10-01 10:58:21 +02:00
|
|
|
// Array memory: [dword key][byte flags][dword left][dword right][dword value] -> 17 bytes = 1 position
|
|
|
|
// If key don't exists then value == 0
|
|
|
|
:struct Array
|
|
|
|
{
|
|
|
|
dword memory;
|
|
|
|
dword offsetMemory;
|
2018-10-03 10:57:58 +02:00
|
|
|
dword lenInitSize;
|
2018-10-01 10:58:21 +02:00
|
|
|
dword recursiveIndex(dword i, address);
|
|
|
|
byte set(dword key, data);
|
|
|
|
dword get(dword key);
|
2018-10-03 10:57:58 +02:00
|
|
|
void reallocMemory(dword newSize);
|
2018-10-01 10:58:21 +02:00
|
|
|
//dword del(dword key);
|
|
|
|
byte init(dword size);
|
|
|
|
};
|
|
|
|
|
2018-10-03 10:57:58 +02:00
|
|
|
:void Array::reallocMemory(dword newSize)
|
|
|
|
{
|
2020-03-21 14:38:17 +01:00
|
|
|
newSize *= 17;
|
2018-10-03 10:57:58 +02:00
|
|
|
memory = realloc(memory, newSize);
|
|
|
|
lenInitSize = newSize;
|
|
|
|
}
|
|
|
|
|
2018-10-01 10:58:21 +02:00
|
|
|
:dword Array::recursiveIndex(dword key, address)
|
|
|
|
{
|
|
|
|
dword flags = 0;
|
|
|
|
IF (DSDWORD[address] == key) RETURN address;
|
2018-10-03 10:57:58 +02:00
|
|
|
flags = DSBYTE[address + 4];
|
2018-10-01 10:58:21 +02:00
|
|
|
//IF (flags & 100b) RETURN address; // if delete
|
|
|
|
IF (flags & 010b) && (DSDWORD[address] < key) RETURN recursiveIndex(key, DSDWORD[address + 5]); // left tree
|
|
|
|
IF (flags & 001b) && (DSDWORD[address] > key) RETURN recursiveIndex(key, DSDWORD[address + 9]); // right tree
|
|
|
|
RETURN address;
|
|
|
|
}
|
2020-03-21 14:38:17 +01:00
|
|
|
|
2018-10-01 10:58:21 +02:00
|
|
|
:byte Array::init(dword size)
|
|
|
|
{
|
2020-03-21 14:38:17 +01:00
|
|
|
dword pointer = 0;
|
2020-05-23 13:26:58 +02:00
|
|
|
if (!size) size = 240;
|
2018-10-01 10:58:21 +02:00
|
|
|
IF(!memory)
|
|
|
|
{
|
2018-10-03 10:57:58 +02:00
|
|
|
lenInitSize = size * 17;
|
|
|
|
memory = malloc(lenInitSize);
|
2020-03-21 14:38:17 +01:00
|
|
|
pointer = memory;
|
|
|
|
DSDWORD[pointer] = 0; pointer += 4;
|
|
|
|
DSBYTE[pointer] = 0; pointer += 1;
|
|
|
|
DSDWORD[pointer] = 0;pointer += 4;
|
|
|
|
DSDWORD[pointer] = 0;pointer += 4;
|
|
|
|
DSDWORD[pointer] = 0;
|
2018-10-01 10:58:21 +02:00
|
|
|
offsetMemory = 17;
|
|
|
|
RETURN 0xFF;
|
|
|
|
}
|
2018-10-03 10:57:58 +02:00
|
|
|
IF(size > lenInitSize)
|
|
|
|
{
|
2020-03-21 14:38:17 +01:00
|
|
|
reallocMemory(size);
|
2018-10-03 10:57:58 +02:00
|
|
|
RETURN 0xFF;
|
|
|
|
}
|
|
|
|
RETURN 0;
|
2018-10-01 10:58:21 +02:00
|
|
|
}
|
|
|
|
:byte Array::set(dword key, data)
|
|
|
|
{
|
|
|
|
dword address = 0;
|
|
|
|
dword newOffset = 0;
|
2018-10-03 10:57:58 +02:00
|
|
|
IF(offsetMemory > lenInitSize) reallocMemory(offsetMemory << 1);
|
2018-10-01 10:58:21 +02:00
|
|
|
address = recursiveIndex(key, memory);
|
|
|
|
/*IF(DSBYTE[address + 4] & 100b)
|
|
|
|
{
|
|
|
|
IF(DSDWORD[address] < key)
|
|
|
|
{
|
|
|
|
DSBYTE[address + 4] |= 10b;
|
|
|
|
DSDWORD[address + 5] = newOffset;
|
|
|
|
}
|
|
|
|
ELSE IF(DSDWORD[address] > key)
|
|
|
|
{
|
|
|
|
DSBYTE[address + 4] |= 01b;
|
|
|
|
DSDWORD[address + 9] = newOffset;
|
|
|
|
}
|
|
|
|
ELSE
|
|
|
|
{
|
|
|
|
DSDWORD[address + 13] = data;
|
|
|
|
RETURN 0xFF;
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
newOffset = memory + offsetMemory;
|
|
|
|
IF(DSDWORD[address] < key)
|
|
|
|
{
|
2018-10-03 10:57:58 +02:00
|
|
|
DSBYTE[address + 4] |= 010b; // set flag left address
|
2018-10-01 10:58:21 +02:00
|
|
|
DSDWORD[address + 5] = newOffset;
|
|
|
|
}
|
|
|
|
ELSE IF(DSDWORD[address] > key)
|
|
|
|
{
|
2018-10-03 10:57:58 +02:00
|
|
|
DSBYTE[address + 4] |= 001b; // set flag right address
|
2018-10-01 10:58:21 +02:00
|
|
|
DSDWORD[address + 9] = newOffset;
|
|
|
|
}
|
|
|
|
ELSE
|
|
|
|
{
|
|
|
|
DSDWORD[address + 13] = data;
|
|
|
|
RETURN 0xFF;
|
|
|
|
}
|
2020-03-21 14:38:17 +01:00
|
|
|
DSDWORD[newOffset] = key; newOffset+=4;
|
|
|
|
DSBYTE[newOffset] = 0; newOffset+=1;
|
|
|
|
DSDWORD[newOffset] = 0; newOffset+=4;
|
|
|
|
DSDWORD[newOffset] = 0; newOffset+=4;
|
|
|
|
DSDWORD[newOffset] = data;
|
2018-10-01 10:58:21 +02:00
|
|
|
offsetMemory += 17;
|
|
|
|
RETURN 0xFF;
|
|
|
|
}
|
|
|
|
:dword Array::get(dword key)
|
|
|
|
{
|
|
|
|
EBX = recursiveIndex(key, memory);
|
|
|
|
IF(DSDWORD[EBX] != key) RETURN 0;
|
|
|
|
IF(DSBYTE[EBX + 4] & 100b) RETURN 0;
|
|
|
|
RETURN DSDWORD[EBX + 13];
|
|
|
|
}
|
|
|
|
/*:dword Array::del(dword key)
|
|
|
|
{
|
|
|
|
dword address = 0;
|
|
|
|
address = recursiveIndex(key, memory);
|
|
|
|
IF(DSDWORD[address] != key) RETURN 0;
|
|
|
|
DSBYTE[address + 4] |= 100b;
|
|
|
|
RETURN 0xFF;
|
|
|
|
}*/
|
|
|
|
|
|
|
|
:struct Dictionary
|
|
|
|
{
|
|
|
|
Array array;
|
|
|
|
dword hash(dword text);
|
|
|
|
byte set(dword key, value);
|
|
|
|
dword get(dword key);
|
|
|
|
byte init(dword size);
|
|
|
|
};
|
|
|
|
|
2020-03-21 14:38:17 +01:00
|
|
|
:dword Dictionary::hash(dword text)
|
2018-10-01 10:58:21 +02:00
|
|
|
{
|
2020-03-21 14:38:17 +01:00
|
|
|
RETURN crc32(text, strlen(text));
|
|
|
|
/*
|
2018-10-03 10:57:58 +02:00
|
|
|
dword checkSum1 = 1;
|
|
|
|
dword checkSum2 = 0;
|
|
|
|
dword beginAddress = 0;
|
2020-04-27 22:18:23 +02:00
|
|
|
|
2018-10-03 10:57:58 +02:00
|
|
|
beginAddress = text;
|
2018-10-01 10:58:21 +02:00
|
|
|
WHILE(DSBYTE[text])
|
|
|
|
{
|
2018-10-03 10:57:58 +02:00
|
|
|
checkSum1 += DSBYTE[text];
|
|
|
|
checkSum2 += checkSum1;
|
2018-10-01 10:58:21 +02:00
|
|
|
text++;
|
|
|
|
}
|
2018-10-03 10:57:58 +02:00
|
|
|
//IF(h1 > 0x03FFF) RETURN h1 << 8 ^ h2;
|
|
|
|
//IF(h2 > 0x3FFFF) RETURN h1 << 8 ^ h2;
|
|
|
|
EAX = text - beginAddress;
|
|
|
|
EAX <<= 23;
|
|
|
|
RETURN EAX | checkSum2;
|
2020-03-21 14:38:17 +01:00
|
|
|
*/
|
2018-10-01 10:58:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
:byte Dictionary::set(dword key, value)
|
|
|
|
{
|
|
|
|
RETURN array.set(hash(key),value);
|
|
|
|
}
|
|
|
|
|
|
|
|
:dword Dictionary::get(dword key)
|
|
|
|
{
|
|
|
|
RETURN array.get(hash(key));
|
|
|
|
}
|
|
|
|
|
|
|
|
:byte Dictionary::init(dword size)
|
|
|
|
{
|
|
|
|
RETURN array.init(size);
|
2018-11-01 22:48:33 +01:00
|
|
|
}
|
|
|
|
|
2020-05-07 10:16:59 +02:00
|
|
|
:dword indexArray(dword address, key)
|
2020-04-27 22:18:23 +02:00
|
|
|
{
|
2020-05-07 10:16:59 +02:00
|
|
|
dword offset = key&0x1FF;
|
2020-04-27 22:18:23 +02:00
|
|
|
dword offsetAddress = offset*4+address;
|
2020-05-07 10:16:59 +02:00
|
|
|
IF (key==offset) RETURN 4*0x200+offsetAddress;
|
|
|
|
IF (!DSDWORD[offsetAddress]) DSDWORD[offsetAddress] = malloc(0x1000);
|
|
|
|
RETURN indexArray(DSDWORD[offsetAddress], key>>9);
|
2020-04-27 22:18:23 +02:00
|
|
|
}
|
|
|
|
|
2020-03-21 14:38:17 +01:00
|
|
|
#endif
|