module libxdiff.init; import xdiff; import core.stdc.stdlib : malloc, free, realloc; import std.exception : enforce; import core.stdc.errno : errno; import core.stdc.string : strerror; import std.string : fromStringz; import std.conv : to; private __gshared bool _allocatorReady = false; package(libxdiff) alias ByteArray = const(ubyte)[]; extern (C) { private void* wrap_malloc(void*, uint size) { return malloc(size); } private void wrap_free(void*, void* p) { free(p); } private void* wrap_realloc(void*, void* p, uint size) { return realloc(p, size); } } private void setAllocator() { if (_allocatorReady) return; memallocator_t m = {null, &wrap_malloc, &wrap_free, &wrap_realloc}; enforce(xdl_set_allocator(&m) == 0, "xdl_set_allocator failed: " ~ strerror(errno).fromStringz); _allocatorReady = true; } mmfile_t initMmfile(size_t len) { setAllocator(); mmfile_t mf; enforce(xdl_init_mmfile(&mf, len.to!long, XDL_MMF_ATOMIC) == 0, "xdl_init_mmfile failed: " ~ strerror(errno).fromStringz); return mf; } abstract class MM { protected: mmfile_t _inner; public: final @property size_t size() { return xdl_mmfile_size(&_inner).to!size_t; } // Проверка «компактности» — содержимое лежит в одном блоке // (важно для бинарных функций, которым нужно сплошное непрерывное представление). final bool isCompact() const { return xdl_mmfile_iscompact(cast(mmfile_t*)&_inner) != 0; } }