5.6 KiB
Specification of DUMBFILE_SYSTEM
DUMB is designed filesystem-agnostic, even though the C standard library already defines an abstraction over files on a disk. This is useful because Allegro 4 and 5 define their own abstractions.
To register your own filesystem abstraction with DUMB, you must create an
instance of struct DUMBFILE_SYSTEM
, fill in your own function pointers
according to the specification below, and call register_dumbfile_system
on
your instance.
The header dumb.h
defines DUMBFILE_SYSTEM
as a struct of function pointers:
typedef struct DUMBFILE_SYSTEM
{
void *(*open)(const char *filename);
int (*skip)(void *f, dumb_off_t n);
int (*getc)(void *f);
dumb_ssize_t (*getnc)(char *ptr, size_t n, void *f);
void (*close)(void *f);
int (*seek)(void *f, dumb_off_t n);
dumb_off_t (*get_size)(void *f);
}
DUMBFILE_SYSTEM;
Here, dumb_off_t
is a signed integer at least 64 bits wide, it is intended
to measure file offsets. The return type dumb_ssize_t
is a signed integer
exactly as wide as size_t
, it is intended to store either a size_t
or a
negative error code. Both dumb_*_t
are defined in dumb.h
.
The function pointers skip
and getnc
are optional, i.e., you may set
some of these to NULL
in your struct instance. DUMB will then try to
mimick the missing functions' behavior by calling your getc
several times.
If DUMB is built with debugging flags, it will assert that all other
functions are not NULL
. In release mode, DUMB will silently fail.
Your non-NULL
function pointers must conform to the following specification.
open
void *(*open)(const char *filename);
Open a file for reading.
Arguments:
const char *filename
: A normal filename as understood by the operating system. Will be opened for reading.
Returns as void *
:
-
the address of a file handle on successfully opening the file. DUMB will pass this file handle as argument to other functions of the
DUMBFILE_SYSTEM
. -
NULL
on error during opening the file.
Each file has a position internally managed by DUMB. A newly opened file
has a position of 0. Other functions from the DUMBFILE_SYSTEM
can move
this position around.
DUMB allocates memory for the successfully opened file, and will store opaque
information in that memory, e.g., the DUMB-internal file position. This memory
be freed when DUMB calls close
on the file's handle. The memory is separate
from your own filesystem implementation: You are responsible for supplying the
data, and DUMB is responsible for storing anything about interpreting that
data.
skip
int (*skip)(void *f, dumb_off_t n);
Advance the position in the file.
Arguments:
-
void *f
: A file handle thatopen
returned. Guaranteed non-NULL
. -
dumb_off_t n
: Number of bytes to advance in the file. DUMB will only call this withn >= 0
. Forn < 0
, the behavior ofskip
is undefined.
Returns as int
:
-
0
on successfully skipping ahead byn
bytes. -
-1
on error.
It is legal to set skip = NULL
in a DUMBFILE_SYSTEM
. DUMB will then call
getc
a total of n
times to skip ahead in a file. For speed, it is
advisable to supply a proper skip
implementation.
getc
int (*getc)(void *f);
Read a byte from the file.
Arguments:
void *f
: A file handle thatopen
returned. Guaranteed non-NULL
.
Returns as int
:
-
the value of the byte read, on successfully reading one byte.
-
-1
on error.
After a succesful read, DUMB will treat the file as advanced by one byte.
getnc
dumb_ssize_t (*getnc)(char *ptr, size_t n, void *f);
Read up to the given number of bytes from the file into a given buffer.
-
char *ptr
: The start of a buffer provided by DUMB. -
size_t n
: The length of the number of bytes to be read. -
void *f
: A file handle thatopen
returned. Guaranteed non-NULL
.
Returns as dumb_ssize_t
:
-
the number of bytes successfully read, if it was possible to read at least one byte.
-
-1
on error.
This function shall bytes from the file f
and store them in sequence in the
buffer beginning at ptr
. It shall read fewer than n
bytes if end of file
is encountered before n
bytes could have been read, otherwise it should read
n
bytes.
It is legal to set skip = NULL
in a DUMBFILE_SYSTEM
. DUMB will then call
getc
a total of n
times and store the results in its buffer.
close
void (*close)(void *f);
Closes a file that has been opened before with open
.
Arguments:
void *f
: A file handle thatopen
returned. Guaranteed non-NULL
.
DUMB will deallocate the memory that it used to interpret the file. You are
free to treat your resource however you would like: You may deallocate it, or
keep it around for other things. For example, Allegro 5's implementation
of close
takes a void pointer and does nothing with it at all.
seek
int (*seek)(void *f, dumb_off_t n);
Jump to an arbitrary position in the file.
Arguments:
-
void *f
: A file handle thatopen
returned. Guaranteed non-NULL
. -
dumb_off_t n
: The position in the file, relative to the beginning. There is no guarantee whethern >= 0
.
Returns as int
:
-
0
on successfully seeking in the file. -
-1
on error.
DUMB will modify its internal position of the file accordingly.
A value of n < 0
shall set the file into an erroneous state from which no
bytes can be read.
get_size
dumb_off_t (*get_size)(void *f);
Get the length in bytes, i.e., the position after the final byte, of a file.
Arguments:
void *f
: A file handle thatopen
returned. Guaranteed non-NULL
.
Returns as dumb_off_t
:
- the length of the file in bytes.