/*
This code is hereby released to the public domain.
~aaaaaa123456789, 2016-04-18
*/
// NOTE: this is a quick and dirty, untested, sample implementation! Do not use without testing and fixing bugs! It may not even compile!
typedef struct {
char * init_ptr;
unsigned pos;
unsigned len;
} FILE;
// assuming that <stdlib.h> and <string.h> (or suitable equivalents) are included
FILE * fopen (const char * filename, const char * mode) {
// accepts filenames in the form 0x12345678:0xabcd where they are pointer and length
// doesn't give a shit about the mode
const char * sep = strchr(filename, ':');
if (!sep) return NULL;
if (sep == filename) return NULL;
unsigned long ptr, len;
char * p = malloc(sep - filename + 1);
strncpy(p, filename, sep - filename);
p[sep - filename] = 0;
char * perr;
ptr = strtoul(p, &perr, 0);
if (*perr) {
free(p);
return NULL;
}
free(p);
if (!*(++ sep)) return NULL;
len = strtoul(sep, &perr, 0);
if (*perr) return NULL;
FILE * result = malloc(sizeof(FILE));
*result = (FILE) {.init_ptr = (char *) ptr, .pos = 0, .len = len};
return result;
}
size_t fread (void * buffer, size_t element_size, size_t element_count, FILE * fp) {
unsigned read_count;
if ((element_size * element_count) > (fp -> len - fp -> pos))
read_count = (fp -> len - fp -> pos) / element_size;
else
read_count = element_count;
memcpy(buffer, fp -> init_ptr + pos, read_count * element_size);
return read_count;
}
size_t fwrite (const void * buffer, size_t element_size, size_t element_count, FILE * fp) {
unsigned write_count;
if ((element_size * element_count) > (fp -> len - fp -> pos))
write_count = (fp -> len - fp -> pos) / element_size;
else
write_count = element_count;
memcpy(fp -> init_ptr + pos, buffer, write_count * element_size);
return write_count;
}
int feof (FILE * fp) {
return fp -> pos >= fp -> len;
}
int ferror (FILE * fp) {
return 0; // no errors
}
void clearerr (FILE * fp) {} // does nothing
void rewind (FILE * fp) {
fp -> pos = 0;
}
int fseek (FILE * fp, long offset, int whence /* yes, this is the real name of the parameter */) {
switch (whence) {
case 1: case 2:
offset += (whence == 1) ? fp -> pos : fp -> len;
// fallthrough
case 0:
if (offset < 0) return -1;
if (offset > fp -> len) return -1;
fp -> pos = offset;
return 0;
default:
return -1;
}
}
long ftell (FILE * fp) {
return fp -> pos;
}
typedef unsigned fpos_t;
int fgetpos (FILE * fp, fpos_t * pos) {
*pos = fp -> pos;
return 0;
}
int fsetpos (FILE * fp, fpos_t * pos) {
return fseek(fp, *pos, 0);
}
Comments