// source: A data source to read and edit // // This header provides the main definitions for data sources, which back the // data that is shown and edited in the application. Data sources implement a // base interface for reading and writing chunks, with some optional features // being defined by capabilities. #pragma once #include #include #include "buffer.h" // Data source capabilities // /* The data source is writable and can be modified by API. */ #define SOURCE_WRITE 0x01 /* The data source can by resized, adding or removing new bytes. */ #define SOURCE_RESIZE 0x02 /* The data source can save to an external file */ #define SOURCE_SAVEAS 0x04 // Interface to data sources // typedef struct { /* Interface name */ char const *name; /* Whether the source should be closed before we return to menu */ bool close_on_return_to_menu; /* Load a chunk from the data source into a buffer. */ ssize_t (*read)(void *_cookie, void *buf, off_t offset, size_t size); /* Write from a buffer into a segment of the data source. If the interface has the SOURCE_RESIZE capability, the buffer might be of a different size than the segment. */ bool (*write)(void *_cookie, void *buf, size_t buf_size, off_t offset, size_t segment_size); /* Current source data size. */ size_t (*size)(void *_cookie); /* Whether the source is currently dirty (ie. requires a save). */ bool (*dirty)(void *_cookie); /* Save the data to its original medium, or, if the SOURCE_SAVEAS capability is available and outfile is not NULL, a file. */ bool (*save)(void *_cookie, char const *outfile); /* Close the data source. */ void (*close)(void *_cookie); } source_intf_t; // An open data source // typedef struct { /* Interface identifier, and opaque interface data */ source_intf_t *intf; void *cookie; /* Source capabilities */ int cap; /* Source name. Can be any string: file path, "memory at X", etc. */ char *origin; /* If set, there is no origin and the "SAVE" button is disabled (only useful if "SAVE AS" is enabled) */ bool no_origin; /* Front buffer for edition */ buffer_t *buf; /* Address of the front buffer in the source */ off_t buf_offset; /* Length of the front buffer in the source */ int buf_segment_size; } source_t; /* Open a data source; this is a low-level function used by source-specific opening functions. */ source_t *source_open(source_intf_t *intf, void *cookie, char const *origin); /* Size of the source's data. Might be inaccurate if the front buffer has been expanded */ size_t source_size(source_t *s); /* Whether the source has been modified and needs a save. */ bool source_dirty(source_t *s); /* Replace the source's buffer's contents with data read from the source. */ ssize_t source_load(source_t *s, off_t offset, size_t segment_size); /* Determine whether the `n` bytes following `offset` are currently loaded in the front buffer. */ bool source_requires_load(source_t *s, off_t offset, int n); /* Make sure that the `n` bytes following `offset` are loaded in the front buffer. If not, load the region around there. Returns true if the region changed, otherwise false. */ void source_ensure_loaded(source_t *s, off_t offset, int n); /* Push the front buffer into the data source. */ bool source_save_front_buffer(source_t *s); /* Save the source. The `outfile` is NULL for the current origin, or a file path to save as (if supported). */ bool source_save(source_t *s, char const *outfile); /* Free a source and its data. */ void source_free(source_t *s); // Supported data sources // #include "source-loaded-file.h" #include "source-lazy-file.h" #include "source-memory.h"