This commit is contained in:
Alexander Zhirov 2025-08-31 00:28:30 +03:00
commit e2396bc172
Signed by: alexander
GPG key ID: C8D8BE544A27C511
7 changed files with 239 additions and 0 deletions

150
source/xdiff.d Normal file
View file

@ -0,0 +1,150 @@
module xdiff;
extern (C):
// ------------------------------------------------------------
// Константы и флаги
// ------------------------------------------------------------
// Режимы и опции diff/patch
enum XDF_NEED_MINIMAL = 1 << 1; // минимальный алгоритм различий
enum XDL_PATCH_NORMAL = '-'; // обычный патч
enum XDL_PATCH_REVERSE = '+'; // обратный патч
enum XDL_PATCH_MODEMASK = (1 << 8) - 1; // маска для режима патча
enum XDL_PATCH_IGNOREBSPACE = 1 << 8; // игнорировать пробелы при сравнении
// Флаги для mmfile (memory mapped file)
enum XDL_MMB_READONLY = 1 << 0; // доступ только для чтения
enum XDL_MMF_ATOMIC = 1 << 0; // атомарный доступ к файлу в памяти
// Операции бинарного diff
enum XDL_BDOP_INS = 1; // вставка
enum XDL_BDOP_CPY = 2; // копирование
enum XDL_BDOP_INSB = 3; // вставка блока
// ------------------------------------------------------------
// Структуры
// ------------------------------------------------------------
// Кастомный аллокатор памяти, который можно подставить в libxdiff
struct memallocator_t
{
void* priv; // приватный указатель пользователя
void* function(void*, uint) malloc; // функция выделения памяти
void function(void*, void*) free; // функция освобождения памяти
void* function(void*, void*, uint) realloc; // функция перераспределения памяти
}
// Блок памяти, используемый внутри mmfile
struct mmblock_t
{
mmblock_t* next; // следующий блок
ulong flags; // флаги блока
long size; // размер данных
long bsize; // размер блока
char* ptr; // указатель на данные
}
// "Файл" в памяти, который хранит список блоков
struct mmfile_t
{
ulong flags; // флаги файла
mmblock_t* head; // первый блок
mmblock_t* tail; // последний блок
long bsize; // размер блока по умолчанию
long fsize; // общий размер файла
long rpos; // текущая позиция чтения
mmblock_t* rcur; // блок для чтения
mmblock_t* wcur; // блок для записи
}
// Буфер данных (указатель + длина)
struct mmbuffer_t
{
char* ptr; // данные
long size; // размер буфера
}
// Параметры алгоритма diff
struct xpparam_t
{
ulong flags; // флаги diff
}
// Callback для вывода данных (например, печать патча)
struct xdemitcb_t
{
void* priv; // приватный указатель
int function(void*, mmbuffer_t*, int) outf; // функция вывода
}
// Конфигурация вывода diff
struct xdemitconf_t
{
long ctxlen; // длина контекста (кол-во строк вокруг изменений)
}
// Параметры бинарного diff
struct bdiffparam_t
{
long bsize; // размер блока
}
// ------------------------------------------------------------
// Функции из libxdiff
// ------------------------------------------------------------
// Установка пользовательского аллокатора
int xdl_set_allocator(memallocator_t* malt);
// Врапперы для malloc/free/realloc из libxdiff
void* xdl_malloc(uint size);
void xdl_free(void* ptr);
void* xdl_realloc(void* ptr, uint size);
// Работа с mmfile (инициализация, освобождение, чтение/запись и т.д.)
int xdl_init_mmfile(mmfile_t* mmf, long bsize, ulong flags);
void xdl_free_mmfile(mmfile_t* mmf);
int xdl_mmfile_iscompact(mmfile_t* mmf);
int xdl_seek_mmfile(mmfile_t* mmf, long off);
long xdl_read_mmfile(mmfile_t* mmf, void* data, long size);
long xdl_write_mmfile(mmfile_t* mmf, const(void)* data, long size);
long xdl_writem_mmfile(mmfile_t* mmf, mmbuffer_t* mb, int nbuf);
void* xdl_mmfile_writeallocate(mmfile_t* mmf, long size);
long xdl_mmfile_ptradd(mmfile_t* mmf, char* ptr, long size, ulong flags);
long xdl_copy_mmfile(mmfile_t* mmf, long size, xdemitcb_t* ecb);
void* xdl_mmfile_first(mmfile_t* mmf, long* size);
void* xdl_mmfile_next(mmfile_t* mmf, long* size);
long xdl_mmfile_size(mmfile_t* mmf);
int xdl_mmfile_cmp(mmfile_t* mmf1, mmfile_t* mmf2);
int xdl_mmfile_compact(mmfile_t* mmfo, mmfile_t* mmfc, long bsize, ulong flags);
// Основные операции diff/patch/merge
int xdl_diff(mmfile_t* mf1, mmfile_t* mf2,
const(xpparam_t)* xpp,
const(xdemitconf_t)* xecfg,
xdemitcb_t* ecb);
int xdl_patch(mmfile_t* mf, mmfile_t* mfp, int mode,
xdemitcb_t* ecb,
xdemitcb_t* rjecb);
int xdl_merge3(mmfile_t* mmfo, mmfile_t* mmf1, mmfile_t* mmf2,
xdemitcb_t* ecb,
xdemitcb_t* rjecb);
// Бинарный diff и patch
int xdl_bdiff_mb(mmbuffer_t* mmb1, mmbuffer_t* mmb2,
const(bdiffparam_t)* bdp,
xdemitcb_t* ecb);
int xdl_bdiff(mmfile_t* mmf1, mmfile_t* mmf2,
const(bdiffparam_t)* bdp,
xdemitcb_t* ecb);
int xdl_rabdiff_mb(mmbuffer_t* mmb1, mmbuffer_t* mmb2, xdemitcb_t* ecb);
int xdl_rabdiff(mmfile_t* mmf1, mmfile_t* mmf2, xdemitcb_t* ecb);
long xdl_bdiff_tgsize(mmfile_t* mmfp);
int xdl_bpatch(mmfile_t* mmf, mmfile_t* mmfp, xdemitcb_t* ecb);
int xdl_bpatch_multi(mmbuffer_t* base, mmbuffer_t* mbpch, int n,
xdemitcb_t* ecb);