diff --git a/pkg/tinyvcdiff/Kconfig b/pkg/tinyvcdiff/Kconfig index a31b3d46b2..af1617a348 100644 --- a/pkg/tinyvcdiff/Kconfig +++ b/pkg/tinyvcdiff/Kconfig @@ -36,4 +36,11 @@ config TINYVCDIFF_MTD_WRITE_SIZE endif # MODULE_TINYVCDIFF_MTD +config MODULE_TINYVCDIFF_VFS + bool "VFS Backend" + depends on MODULE_VFS + default y + help + Use a VFS file as VCDIFF target or source. + endif # PACKAGE_TINYVCDIFF diff --git a/pkg/tinyvcdiff/Makefile.dep b/pkg/tinyvcdiff/Makefile.dep index 7ce9d749d9..ca535c2365 100644 --- a/pkg/tinyvcdiff/Makefile.dep +++ b/pkg/tinyvcdiff/Makefile.dep @@ -1,3 +1,7 @@ ifneq (,$(filter mtd,$(USEMODULE))) USEMODULE += tinyvcdiff_mtd endif + +ifneq (,$(filter vfs,$(USEMODULE))) + USEMODULE += tinyvcdiff_vfs +endif diff --git a/pkg/tinyvcdiff/Makefile.include b/pkg/tinyvcdiff/Makefile.include index 6c0d32f480..a12fa96aa1 100644 --- a/pkg/tinyvcdiff/Makefile.include +++ b/pkg/tinyvcdiff/Makefile.include @@ -13,3 +13,7 @@ INCLUDES += -I$(RIOTPKG)/tinyvcdiff/include ifneq (,$(filter tinyvcdiff_mtd,$(USEMODULE))) DIRS += $(RIOTPKG)/tinyvcdiff/contrib/tinyvcdiff_mtd endif + +ifneq (,$(filter tinyvcdiff_vfs,$(USEMODULE))) + DIRS += $(RIOTPKG)/tinyvcdiff/contrib/tinyvcdiff_vfs +endif diff --git a/pkg/tinyvcdiff/contrib/tinyvcdiff_vfs/Makefile b/pkg/tinyvcdiff/contrib/tinyvcdiff_vfs/Makefile new file mode 100644 index 0000000000..6a1da20345 --- /dev/null +++ b/pkg/tinyvcdiff/contrib/tinyvcdiff_vfs/Makefile @@ -0,0 +1,3 @@ +MODULE = tinyvcdiff_vfs + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/tinyvcdiff/contrib/tinyvcdiff_vfs/vfs.c b/pkg/tinyvcdiff/contrib/tinyvcdiff_vfs/vfs.c new file mode 100644 index 0000000000..359f900cc0 --- /dev/null +++ b/pkg/tinyvcdiff/contrib/tinyvcdiff_vfs/vfs.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2022 Juergen Fitschen + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include "vcdiff_vfs.h" +#include +#include "errno.h" + +static int _read (void *dev, uint8_t *dest, size_t offset, size_t len) +{ + int rc; + vcdiff_vfs_t *vfs = dev; + + /* seek to the given offset */ + rc = vfs_lseek(vfs->fd, offset, SEEK_SET); + if (rc < 0) { + return rc; + } else if ((size_t) rc != offset) { + return -EFAULT; + } + + /* read from file into the buffer */ + rc = vfs_read(vfs->fd, dest, len); + if (rc < 0) { + return rc; + } else if ((size_t) rc != len) { + return -EFAULT; + } + + return 0; +} + +static int _write (void *dev, uint8_t *src, size_t offset, size_t len) +{ + int rc; + vcdiff_vfs_t *vfs = dev; + + /* make sure to stay in the set file size bounds */ + if (offset + len > vfs->max_size) { + return -EFBIG; + } + + /* seek to the given offset */ + rc = vfs_lseek(vfs->fd, offset, SEEK_SET); + if (rc < 0) { + return rc; + } else if ((size_t) rc != offset) { + return -EFAULT; + } + + /* write all bytes to the file */ + rc = vfs_write(vfs->fd, src, len); + if (rc < 0) { + return rc; + } else if ((size_t) rc != len) { + return -EFAULT; + } + + return 0; +} + +const vcdiff_driver_t vcdiff_vfs_driver = { + .read = _read, + .write = _write +}; diff --git a/pkg/tinyvcdiff/include/vcdiff_vfs.h b/pkg/tinyvcdiff/include/vcdiff_vfs.h new file mode 100644 index 0000000000..8c11625367 --- /dev/null +++ b/pkg/tinyvcdiff/include/vcdiff_vfs.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2022 Juergen Fitschen + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @{ + * + * @file + * @ingroup pkg_tinyvcdiff + * + * @author Juergen Fitschen + */ + +#ifndef VCDIFF_VFS_H +#define VCDIFF_VFS_H + +#include "vcdiff.h" +#include "vfs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Driver for accessing VFS-based file access + */ +extern const vcdiff_driver_t vcdiff_vfs_driver; + +/** + * @brief Context for the underlying file + */ +typedef struct { + int fd; /**< File descriptor of the VFS file */ + size_t max_size; /**< Maxmimum file size for vcdiff target files */ +} vcdiff_vfs_t; + +/** + * @brief Initializes vcdiff_vfs_t with maximum allowed file size + */ +#define VCDIFF_VFS_INIT_MAX_SIZE(FD, SIZE) { .fd = FD, .max_size = SIZE } + +/** + * @brief Initializes vcdiff_vfs_t + */ +#define VCDIFF_VFS_INIT(FD) VCDIFF_VFS_INIT_MAX_SIZE(FD, SIZE_MAX) + +#ifdef __cplusplus +} +#endif + +#endif /* VCDIFF_VFS_H */ +/** @} */