aaaaaa123456789 icon

Quick and dirty sample <stdio.h> implementation

aaaaaa123456789 | PRO | 04/18/16 09:38:12 PM UTC | 0 ⭐ | 489 👁️ | Never ⏰ | []
C |

2.71 KB

|

None

|

0 👍

/

0 👎

/*
   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