77 lines
1.4 KiB
D
77 lines
1.4 KiB
D
module sdiff.mmfile;
|
|
|
|
import xdiff;
|
|
|
|
import sdiff.init;
|
|
import sdiff.mmblocks;
|
|
|
|
import std.exception : enforce;
|
|
import std.conv : to;
|
|
import std.string : join, representation;
|
|
|
|
final class MMFile : MM
|
|
{
|
|
private:
|
|
void _write(const(ubyte)[] data)
|
|
{
|
|
if (data.length > 0)
|
|
{
|
|
auto length = data.length.to!long;
|
|
auto wrote = xdl_write_mmfile(&_inner, data.ptr, length);
|
|
enforce(wrote == length,
|
|
"xdl_write_mmfile wrote less than requested (rc=" ~ wrote.to!string ~ ")");
|
|
}
|
|
}
|
|
|
|
public:
|
|
this(const(ubyte)[] data)
|
|
{
|
|
_write(data);
|
|
}
|
|
|
|
this(string data)
|
|
{
|
|
_write(data.representation);
|
|
}
|
|
|
|
this(string[] data)
|
|
{
|
|
_write(data.join('\n').representation);
|
|
}
|
|
|
|
~this()
|
|
{
|
|
if (_inner.head !is null)
|
|
xdl_free_mmfile(&_inner);
|
|
}
|
|
|
|
MMBlocks diff(const scope ref MMFile other, long ctxlen = 3)
|
|
{
|
|
auto patch = new MMBlocks();
|
|
|
|
extern (C) int emitToPatch(void* priv, mmbuffer_t* bufs, int num)
|
|
{
|
|
auto target = cast(MMBlocks) priv;
|
|
foreach (i; 0 .. num)
|
|
{
|
|
auto buf = &bufs[i];
|
|
auto rc = xdl_writem_mmfile(target.ptr(), buf, 1);
|
|
if (rc < 0 || rc != buf.size)
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
xpparam_t xpp = xpparam_t.init;
|
|
|
|
xdemitconf_t xec = xdemitconf_t.init;
|
|
xec.ctxlen = ctxlen;
|
|
|
|
xdemitcb_t ecb = {cast(void*) patch, &emitToPatch};
|
|
|
|
auto rc = xdl_diff(&_inner, cast(mmfile_t*)&other._inner, &xpp, &xec, &ecb);
|
|
enforce(rc == 0, "xdl_diff failed (rc=" ~ rc.to!string ~ ")");
|
|
|
|
return patch;
|
|
}
|
|
}
|