From d9b8f7bda83e746617ce1001972ba255ffdebed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Tue, 22 May 2018 16:25:23 +0200 Subject: text: allow to specify how the file content should be loaded --- text.c | 8 +++++--- text.h | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/text.c b/text.c index 5d5f814..548805b 100644 --- a/text.c +++ b/text.c @@ -1120,9 +1120,11 @@ ssize_t text_write_range(Text *txt, Filerange *range, int fd) { return size - rem; } -/* load the given file as starting point for further editing operations. - * to start with an empty document, pass NULL as filename. */ Text *text_load(const char *filename) { + return text_load_method(filename, TEXT_LOAD_AUTO); +} + +Text *text_load_method(const char *filename, enum TextLoadMethod method) { int fd = -1; size_t size = 0; Text *txt = calloc(1, sizeof *txt); @@ -1144,7 +1146,7 @@ Text *text_load(const char *filename) { // XXX: use lseek(fd, 0, SEEK_END); instead? size = txt->info.st_size; if (size > 0) { - if (size < BLOCK_MMAP_SIZE) + if (method == TEXT_LOAD_READ || (method == TEXT_LOAD_AUTO && size < BLOCK_MMAP_SIZE)) txt->block = block_read(txt, size, fd); else txt->block = block_mmap(txt, size, fd, 0); diff --git a/text.h b/text.h index 2fa6aea..be99894 100644 --- a/text.h +++ b/text.h @@ -58,10 +58,48 @@ typedef struct { * @defgroup load * @{ */ +/** + * Method used to load existing file content. + */ +enum TextLoadMethod { + /** Automatically chose best option. */ + TEXT_LOAD_AUTO, + /** + * Read file content and copy it to an in-memory buffer. + * Subsequent changes to the underlying file will have no + * effect on this text instance. + * + * @rst + * .. note:: Load time is linear in the file size. + * @endrst + */ + TEXT_LOAD_READ, + /** + * Memory map the the file from disk. Use file system / virtual memory + * subsystem as a caching layer. + * @rst + * .. note:: Load time is (almost) independent of the file size. + * .. warning:: Inplace modifications of the underlying file + * will be reflected in the current text content. + * In particular, truncatenation will raise ``SIGBUS`` + * and result in data loss. + * @endrst + */ + TEXT_LOAD_MMAP, +}; +/** + * Create a text instance populated with the given file content. + * + * @rst + * .. note:: Equivalent to ``text_load_method(filename, TEXT_LOAD_AUTO)``. + * @endrst + */ +Text *text_load(const char *filename); /** * Create a text instance populated with the given file content. * * @param filename The name of the file to load, if ``NULL`` an empty text is created. + * @param method How the file content should be loaded. * @return The new Text object or ``NULL`` in case of an error. * @rst * .. note:: When attempting to load a non-regular file, ``errno`` will be set to: @@ -70,7 +108,7 @@ typedef struct { * - ``ENOTSUP`` otherwise. * @endrst */ -Text *text_load(const char *filename); +Text *text_load_method(const char *filename, enum TextLoadMethod); /** Release all ressources associated with this text instance. */ void text_free(Text*); /** -- cgit v1.2.3