From 44ddd57f55158d4d0ec97db4934270930182f6cf Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Thu, 13 Jan 2022 12:46:36 +0100 Subject: [PATCH] Moved archive C bindings into separate file --- src/archive.v | 87 ------------------------------------------ src/archive/archive.v | 43 +++++++++++++++++++++ src/archive/bindings.v | 46 ++++++++++++++++++++++ 3 files changed, 89 insertions(+), 87 deletions(-) delete mode 100644 src/archive.v create mode 100644 src/archive/archive.v create mode 100644 src/archive/bindings.v diff --git a/src/archive.v b/src/archive.v deleted file mode 100644 index 1ecc8a6c..00000000 --- a/src/archive.v +++ /dev/null @@ -1,87 +0,0 @@ -module archive - -import os - -#flag -larchive -#include "archive.h" -#include "archive_entry.h" -#include - -struct C.archive {} - -struct C.archive_entry {} - -// Create a new archive struct -fn C.archive_read_new() &C.archive -fn C.archive_entry_new() &C.archive_entry -fn C.archive_read_support_filter_all(&C.archive) -fn C.archive_read_support_format_all(&C.archive) -// Open an archive for reading -fn C.archive_read_open_filename(&C.archive, &char, int) int -fn C.archive_read_next_header(&C.archive, &&C.archive_entry) int -fn C.archive_read_next_header2(&C.archive, &C.archive_entry) int -fn C.archive_entry_pathname(&C.archive_entry) &char -fn C.archive_read_data_skip(&C.archive) -fn C.archive_read_free(&C.archive) int -fn C.archive_read_data(&C.archive, voidptr, int) -fn C.archive_entry_size(&C.archive_entry) int - -fn C.strcmp(&char, &char) int - -// pub fn list_filenames() { -// a := C.archive_read_new() -// entry := &C.archive_entry{} -// mut r := 0 - -// C.archive_read_support_filter_all(a) -// C.archive_read_support_format_all(a) - -// r = C.archive_read_open_filename(a, c'test/homebank-5.5.1-1-x86_64.pkg.tar.zst', 10240) - -// for (C.archive_read_next_header(a, &entry) == C.ARCHIVE_OK) { -// println(cstring_to_vstring(C.archive_entry_pathname(entry))) -// C.archive_read_data_skip(a) // Note 2 -// } - -// r = C.archive_read_free(a) // Note 3 -// } - -pub fn get_pkg_info(pkg_path string) ?string { - if !os.is_file(pkg_path) { - return error("'$pkg_path' doesn't exist or isn't a file.") - } - - a := C.archive_read_new() - entry := C.archive_entry_new() - mut r := 0 - - C.archive_read_support_filter_all(a) - C.archive_read_support_format_all(a) - - // TODO find out where does this 10240 come from - r = C.archive_read_open_filename(a, &char(pkg_path.str), 10240) - defer { - C.archive_read_free(a) - } - - if r != C.ARCHIVE_OK { - return error('Failed to open package.') - } - - // We iterate over every header in search of the .PKGINFO one - mut buf := voidptr(0) - for C.archive_read_next_header(a, &entry) == C.ARCHIVE_OK { - if C.strcmp(C.archive_entry_pathname(entry), c'.PKGINFO') == 0 { - size := C.archive_entry_size(entry) - - // TODO can this unsafe block be avoided? - buf = unsafe { malloc(size) } - C.archive_read_data(a, voidptr(buf), size) - break - }else{ - C.archive_read_data_skip(a) - } - } - - return unsafe { cstring_to_vstring(&char(buf)) } -} diff --git a/src/archive/archive.v b/src/archive/archive.v new file mode 100644 index 00000000..ca911c70 --- /dev/null +++ b/src/archive/archive.v @@ -0,0 +1,43 @@ +module archive + +import os + +pub fn get_pkg_info(pkg_path string) ?string { + if !os.is_file(pkg_path) { + return error("'$pkg_path' doesn't exist or isn't a file.") + } + + a := C.archive_read_new() + entry := C.archive_entry_new() + mut r := 0 + + C.archive_read_support_filter_all(a) + C.archive_read_support_format_all(a) + + // TODO find out where does this 10240 come from + r = C.archive_read_open_filename(a, &char(pkg_path.str), 10240) + defer { + C.archive_read_free(a) + } + + if r != C.ARCHIVE_OK { + return error('Failed to open package.') + } + + // We iterate over every header in search of the .PKGINFO one + mut buf := voidptr(0) + for C.archive_read_next_header(a, &entry) == C.ARCHIVE_OK { + if C.strcmp(C.archive_entry_pathname(entry), c'.PKGINFO') == 0 { + size := C.archive_entry_size(entry) + + // TODO can this unsafe block be avoided? + buf = unsafe { malloc(size) } + C.archive_read_data(a, voidptr(buf), size) + break + } else { + C.archive_read_data_skip(a) + } + } + + return unsafe { cstring_to_vstring(&char(buf)) } +} diff --git a/src/archive/bindings.v b/src/archive/bindings.v new file mode 100644 index 00000000..678d715f --- /dev/null +++ b/src/archive/bindings.v @@ -0,0 +1,46 @@ +module archive + +#flag -larchive + +#include "archive.h" + +struct C.archive {} + +// Create a new archive struct +fn C.archive_read_new() &C.archive +fn C.archive_read_support_filter_all(&C.archive) +fn C.archive_read_support_format_all(&C.archive) + +// Open an archive for reading +fn C.archive_read_open_filename(&C.archive, &char, int) int + +// Go to next entry header in archive +fn C.archive_read_next_header(&C.archive, &&C.archive_entry) int + +// Skip reading the current entry +fn C.archive_read_data_skip(&C.archive) + +// Free an archive +fn C.archive_read_free(&C.archive) int + +// Read an archive entry's contents into a pointer +fn C.archive_read_data(&C.archive, voidptr, int) + +#include "archive_entry.h" + +struct C.archive_entry {} + +// Create a new archive_entry struct +fn C.archive_entry_new() &C.archive_entry + +// Get the filename of the given entry +fn C.archive_entry_pathname(&C.archive_entry) &char + +// Get an entry's file size +// Note: this function actually returns an i64, but as this can't be used as an arugment to malloc, we'll just roll with it & assume an entry is never bigger than 4 gigs +fn C.archive_entry_size(&C.archive_entry) int + +#include + +// Compare two C strings; 0 means they're equal +fn C.strcmp(&char, &char) int