70 lines
1.5 KiB
D
70 lines
1.5 KiB
D
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;
|
|
}
|
|
}
|