commit e2396bc172eba813cdcd1a96c494e35d687f576a Author: Alexander Zhirov Date: Sun Aug 31 00:28:30 2025 +0300 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..740b38e --- /dev/null +++ b/.gitignore @@ -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 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..d1c022f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "editor.insertSpaces": false, + "editor.tabSize": 4, + "editor.detectIndentation": false +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..36b7cd9 --- /dev/null +++ b/LICENSE @@ -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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..818ffdd --- /dev/null +++ b/README.md @@ -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 ``. + +## 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). diff --git a/dub.json b/dub.json new file mode 100644 index 0000000..3f02880 --- /dev/null +++ b/dub.json @@ -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" +} \ No newline at end of file diff --git a/dub.settings.json b/dub.settings.json new file mode 100644 index 0000000..9da886c --- /dev/null +++ b/dub.settings.json @@ -0,0 +1,4 @@ +{ + "defaultArchitecture": "x86_64", + "defaultCompiler": "ldc2" +} diff --git a/source/xdiff.d b/source/xdiff.d new file mode 100644 index 0000000..d7cbcbb --- /dev/null +++ b/source/xdiff.d @@ -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);