76 lines
1.8 KiB
D
76 lines
1.8 KiB
D
|
|
module patch.utils;
|
||
|
|
|
||
|
|
import core.stdc.stdlib : realloc;
|
||
|
|
import core.stdc.string : memcpy;
|
||
|
|
import patches;
|
||
|
|
|
||
|
|
// Dynamic memory-chunk, with (1) datatype size, (2/3) initialized / allocated chunk, (4) content
|
||
|
|
struct DynamicArray {
|
||
|
|
ubyte elSize;
|
||
|
|
uint initialized; // renamed from 'init' to avoid conflict with D's .init property
|
||
|
|
uint alloc;
|
||
|
|
char* content;
|
||
|
|
}
|
||
|
|
|
||
|
|
// UTF8_ARRAY macro equivalent
|
||
|
|
DynamicArray createUTF8Array() {
|
||
|
|
return DynamicArray(4, 0, 0, null);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Helper function for max
|
||
|
|
T max(T)(T a, T b) {
|
||
|
|
return a > b ? a : b;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Function implementations
|
||
|
|
int p_alloc(DynamicArray* s, uint amount) {
|
||
|
|
uint target = s.initialized + cast(uint)s.elSize * amount;
|
||
|
|
if (s.alloc < target) {
|
||
|
|
uint diff = target - s.alloc;
|
||
|
|
uint nas = s.alloc + max(diff, 15U) * s.elSize;
|
||
|
|
char* tmp = cast(char*)realloc(s.content, nas);
|
||
|
|
if (!tmp) return 0;
|
||
|
|
s.alloc = nas;
|
||
|
|
s.content = tmp;
|
||
|
|
}
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
char* view(DynamicArray* s, uint i) {
|
||
|
|
return s.content + i * s.elSize;
|
||
|
|
}
|
||
|
|
|
||
|
|
char* end(DynamicArray* s, uint i) {
|
||
|
|
return s.content + s.initialized - (i + 1) * s.elSize;
|
||
|
|
}
|
||
|
|
|
||
|
|
uint getU32(DynamicArray* s, uint i, int b) {
|
||
|
|
return *cast(uint*)(b ? view(s, i) : end(s, i));
|
||
|
|
}
|
||
|
|
|
||
|
|
char* expand(DynamicArray* s) {
|
||
|
|
if (!p_alloc(s, 1)) return null;
|
||
|
|
s.initialized += s.elSize;
|
||
|
|
return end(s, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
void pop(DynamicArray* s) {
|
||
|
|
if (s.initialized >= s.elSize) {
|
||
|
|
s.initialized -= s.elSize;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void empty(DynamicArray* s) {
|
||
|
|
s.initialized = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int size(const(DynamicArray)* s) {
|
||
|
|
return cast(int)(s.initialized / s.elSize);
|
||
|
|
}
|
||
|
|
|
||
|
|
void assign(DynamicArray* s, const(DynamicArray)* o) {
|
||
|
|
if (p_alloc(s, size(o))) {
|
||
|
|
memcpy(s.content, o.content, cast(size_t)o.initialized);
|
||
|
|
s.initialized = o.initialized;
|
||
|
|
}
|
||
|
|
}
|