from rust
This commit is contained in:
parent
32203fadc0
commit
1f00cff032
8 changed files with 598 additions and 323 deletions
108
source/xdiff_mmblocks.d
Normal file
108
source/xdiff_mmblocks.d
Normal file
|
@ -0,0 +1,108 @@
|
|||
module xdiff_mmblocks;
|
||||
|
||||
import std.exception : enforce;
|
||||
import xdiff_init : ensureInit, initMmfile;
|
||||
import xdiff;
|
||||
|
||||
final class MMBlocks
|
||||
{
|
||||
private:
|
||||
mmfile_t _inner;
|
||||
bool _owned = true; // владеем ли блоками?
|
||||
enum DEFAULT_BSIZE = 8 * 1024;
|
||||
|
||||
// Глубокая копия: читаем все блоки и записываем в dst
|
||||
static void deepCopyAll(mmfile_t* src, MMBlocks dst)
|
||||
{
|
||||
enforce(xdl_seek_mmfile(src, 0) == 0, "seek(0) failed");
|
||||
|
||||
long sz = 0;
|
||||
auto p = xdl_mmfile_first(src, &sz);
|
||||
while (p !is null && sz > 0)
|
||||
{
|
||||
auto wrote = xdl_write_mmfile(dst.mmfilePtr(), p, sz);
|
||||
enforce(wrote == sz, "write failed during deep copy");
|
||||
p = xdl_mmfile_next(src, &sz);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
this()
|
||||
{
|
||||
_inner = initMmfile(DEFAULT_BSIZE);
|
||||
}
|
||||
|
||||
static MMBlocks fromBytes(const(ubyte)[] data)
|
||||
{
|
||||
auto b = new MMBlocks;
|
||||
if (data.length > 0)
|
||||
{
|
||||
auto wrote = xdl_write_mmfile(&b._inner, data.ptr, cast(long)data.length);
|
||||
enforce(wrote == cast(long)data.length, "xdl_write_mmfile wrote less than requested");
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
~this()
|
||||
{
|
||||
if (_owned && _inner.head !is null)
|
||||
xdl_free_mmfile(&_inner);
|
||||
|
||||
// обнулим на всякий случай
|
||||
_inner.head = null; _inner.tail = null;
|
||||
_inner.rcur = null; _inner.wcur = null;
|
||||
_inner.fsize = 0; _inner.bsize = 0;
|
||||
}
|
||||
|
||||
// доступ к внутреннему mmfile_t*
|
||||
mmfile_t* mmfilePtr() @trusted { return &_inner; }
|
||||
|
||||
size_t size() { return cast(size_t)xdl_mmfile_size(&_inner); }
|
||||
bool isCompact() const { return xdl_mmfile_iscompact(cast(mmfile_t*)&_inner) != 0; }
|
||||
|
||||
int writeBuf(const(ubyte)[] buf)
|
||||
{
|
||||
auto wrote = xdl_write_mmfile(&_inner, buf.ptr, cast(long)buf.length);
|
||||
return (wrote == cast(long)buf.length) ? 0 : -1;
|
||||
}
|
||||
|
||||
/// Глубокая копия (новое владение)
|
||||
MMBlocks clone() const
|
||||
{
|
||||
auto dst = new MMBlocks;
|
||||
// deepCopyAll принимает mmfile_t*, поэтому аккуратно снимаем const с заголовка:
|
||||
deepCopyAll(cast(mmfile_t*)&_inner, dst);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/// Компактизация через пересборку содержимого
|
||||
void toCompact()
|
||||
{
|
||||
if (isCompact()) return;
|
||||
|
||||
auto dst = new MMBlocks;
|
||||
deepCopyAll(&_inner, dst);
|
||||
|
||||
// перехватываем владение содержимым dst
|
||||
if (_owned && _inner.head !is null)
|
||||
xdl_free_mmfile(&_inner);
|
||||
|
||||
_inner = *dst.mmfilePtr();
|
||||
dst._owned = false; // dst больше не владеет
|
||||
dst._inner.head = null; // чтобы финалайзер dst ничего не освободил
|
||||
dst._inner.tail = null;
|
||||
dst._inner.rcur = null;
|
||||
dst._inner.wcur = null;
|
||||
dst._inner.fsize = 0;
|
||||
dst._inner.bsize = 0;
|
||||
}
|
||||
|
||||
/// Снять владение (используется при move в MMFile)
|
||||
void disarm()
|
||||
{
|
||||
_owned = false;
|
||||
_inner.head = null; _inner.tail = null;
|
||||
_inner.rcur = null; _inner.wcur = null;
|
||||
_inner.fsize = 0; _inner.bsize = 0;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue