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

16
.gitignore vendored Normal file
View file

@ -0,0 +1,16 @@
.dub
docs.json
__dummy.html
docs/
/libxdiff
libxdiff.so
libxdiff.dylib
libxdiff.dll
libxdiff.a
libxdiff.lib
libxdiff-test-*
*.exe
*.pdb
*.o
*.obj
*.lst

5
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,5 @@
{
"editor.insertSpaces": false,
"editor.tabSize": 4,
"editor.detectIndentation": false
}

23
LICENSE Normal file
View file

@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

31
README.md Normal file
View file

@ -0,0 +1,31 @@
# xdiff
Low-level wrapper over the C API [LibXDiff](http://www.xmailserver.org/xdiff-lib.html) for D. All values are taken from uapi `<xdiff.h>`.
## Installation
Add to `dub.json`:
```json
{
"dependencies": {
"xdiff": "~>0.1.0"
}
}
```
Or to `dub.sdl`:
```
dependency "xdiff" version="~>0.1.0"
```
Run `dub build`.
## Usage
Import the module: `import xdiff;`
## License
Boost Software License 1.0. See [LICENSE](LICENSE).

10
dub.json Normal file
View file

@ -0,0 +1,10 @@
{
"authors": [
"Alexander Zhirov"
],
"copyright": "Copyright © 2025, Alexander Zhirov",
"description": "The LibXDiff library implements basic and yet complete functionalities to create file differences/patches to both binary and text files.",
"license": "BSL-1.0",
"name": "xdiff",
"targetType": "library"
}

4
dub.settings.json Normal file
View file

@ -0,0 +1,4 @@
{
"defaultArchitecture": "x86_64",
"defaultCompiler": "ldc2"
}

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);