79 lines
1.5 KiB
D
79 lines
1.5 KiB
D
module libxdiff.mmfile;
|
|
|
|
import xdiff;
|
|
|
|
import libxdiff.init;
|
|
import libxdiff.mmblocks;
|
|
|
|
import std.exception : enforce;
|
|
import core.stdc.errno : errno;
|
|
import core.stdc.string : strerror;
|
|
import std.string : fromStringz;
|
|
import std.conv : to;
|
|
import std.string : join, representation;
|
|
|
|
final class MMFile : MM
|
|
{
|
|
private:
|
|
void _write(ByteArray data)
|
|
{
|
|
_inner = initMmfile(0);
|
|
|
|
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: " ~ strerror(errno).fromStringz);
|
|
}
|
|
}
|
|
|
|
public:
|
|
this(ByteArray 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 computePatch(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)
|
|
{
|
|
mmbuffer_t* buf = &bufs[i];
|
|
long written = xdl_writem_mmfile(target.ptr(), buf, 1);
|
|
if (written < 0 || written != buf.size)
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
xpparam_t xpp = {0};
|
|
xdemitconf_t xec = {ctxlen};
|
|
xdemitcb_t ecb = {cast(void*) patch, &emitToPatch};
|
|
|
|
enforce(xdl_diff(&_inner, &other._inner, &xpp, &xec, &ecb) == 0,
|
|
"xdl_diff failed: " ~ strerror(errno).fromStringz);
|
|
|
|
return patch;
|
|
}
|
|
}
|