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; } }