108 lines
3.7 KiB
C
108 lines
3.7 KiB
C
// 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 <stdbool.h>
|
|
#include <sys/types.h>
|
|
#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"
|