static size_t slice_fread(ALLEGRO_FILE *f, void *ptr, size_t size) { SLICE_DATA *slice = al_get_file_userdata(f); if (!(slice->mode & SLICE_READ)) { /* no read permissions */ return 0; } if (!(slice->mode & SLICE_EXPANDABLE) && slice->pos + size > slice->size) { /* don't read past the buffer size if not expandable */ size = slice->size - slice->pos; } if (!size) { return 0; } else { /* unbuffered, read directly from parent file */ size_t b = al_fread(slice->fp, ptr, size); slice->pos += b; if (slice->pos > slice->size) slice->size = slice->pos; return b; } }
static USERDATA *get_userdata(ALLEGRO_FILE *f) { if (f) return al_get_file_userdata(f); else return NULL; }
static bool memfile_fseek(ALLEGRO_FILE *fp, int64_t offset, int whence) { ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); int64_t pos = mf->pos; switch (whence) { case ALLEGRO_SEEK_SET: pos = offset; break; case ALLEGRO_SEEK_CUR: pos = mf->pos + offset; break; case ALLEGRO_SEEK_END: pos = mf->size + offset; break; } if (pos >= mf->size) pos = mf->size; else if (pos < 0) pos = 0; mf->pos = pos; mf->eof = false; return true; }
static FILE *get_fp(ALLEGRO_FILE *f) { if (f) return (FILE *)al_get_file_userdata(f); else return NULL; }
static bool slice_fseek(ALLEGRO_FILE *f, int64_t offset, int whence) { SLICE_DATA *slice = al_get_file_userdata(f); if (whence == ALLEGRO_SEEK_SET) { offset = slice->anchor + offset; } else if (whence == ALLEGRO_SEEK_CUR) { offset = slice->anchor + slice->pos + offset; } else if (whence == ALLEGRO_SEEK_END) { offset = slice->anchor + slice->size + offset; } else { return false; } if ((size_t) offset < slice->anchor) { offset = slice->anchor; } else if ((size_t) offset > slice->anchor + slice->size) { if (!(slice->mode & SLICE_EXPANDABLE)) { offset = slice->anchor + slice->size; } } if (al_fseek(slice->fp, offset, ALLEGRO_SEEK_SET)) { slice->pos = offset - slice->anchor; if (slice->pos > slice->size) slice->size = slice->pos; return true; } return false; }
static size_t slice_fwrite(ALLEGRO_FILE *f, const void *ptr, size_t size) { SLICE_DATA *slice = al_get_file_userdata(f); if (!(slice->mode & SLICE_WRITE)) { /* no write permissions */ return 0; } if (!(slice->mode & SLICE_EXPANDABLE) && slice->pos + size > slice->size) { /* don't write past the buffer size if not expandable */ size = slice->size - slice->pos; } if (!size) { return 0; } else { /* unbuffered, write directly to parent file */ size_t b = al_fwrite(slice->fp, ptr, size); slice->pos += b; if (slice->pos > slice->size) slice->size = slice->pos; return b; } }
static void slice_fclose(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); /* seek to end of slice */ al_fseek(slice->fp, slice->anchor + slice->size, ALLEGRO_SEEK_SET); al_free(slice); }
static bool curl_file_fclose(ALLEGRO_FILE *f) { CURL_FILE *cf = al_get_file_userdata(f); curl_multi_remove_handle(multi_handle, cf->curl); curl_easy_cleanup(cf->curl); if (cf->buffer) free(cf->buffer); free(cf); return true; }
static bool slice_fclose(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); bool ret; /* seek to end of slice */ ret = al_fseek(slice->fp, slice->anchor + slice->size, ALLEGRO_SEEK_SET); al_free(slice); return ret; }
static size_t curl_file_fread(ALLEGRO_FILE *f, void *ptr, size_t size) { CURL_FILE *cf = al_get_file_userdata(f); fill_buffer(cf, size); if (!cf->buffer_pos) return 0; if (cf->buffer_pos < size) size = cf->buffer_pos; memcpy(ptr, cf->buffer, size); use_buffer(cf, size); return size; }
static size_t memfile_fwrite(ALLEGRO_FILE *fp, const void *ptr, size_t size) { ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); size_t n; if (!mf->writable) { al_set_errno(EPERM); return 0; } if (mf->size - mf->pos < (int64_t)size) { /* partial write */ n = mf->size - mf->pos; mf->eof = true; } else { n = size; } memcpy(mf->mem + mf->pos, ptr, n); mf->pos += n; return n; }
static size_t memfile_fread(ALLEGRO_FILE *fp, void *ptr, size_t size) { ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); size_t n = 0; if (!mf->readable) { al_set_errno(EPERM); return 0; } if (mf->size - mf->pos < (int64_t)size) { /* partial read */ n = mf->size - mf->pos; mf->eof = true; } else { n = size; } memcpy(ptr, mf->mem + mf->pos, n); mf->pos += n; return n; }
static off_t slice_fsize(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); return slice->size; }
static void slice_fclearerr(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); al_fclearerr(slice->fp); }
static const char *slice_ferrmsg(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); return al_ferrmsg(slice->fp); }
static int slice_ferror(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); return al_ferror(slice->fp); }
static bool slice_feof(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); return slice->pos >= slice->size; }
static int64_t slice_ftell(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); return slice->pos; }
static bool slice_fflush(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); return al_fflush(slice->fp); }
static void memfile_fclose(ALLEGRO_FILE *fp) { al_free(al_get_file_userdata(fp)); }
static int64_t memfile_ftell(ALLEGRO_FILE *fp) { ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); return mf->pos; }
static ALLEGRO_FILE_PHYSFS *cast_stream(ALLEGRO_FILE *f) { return (ALLEGRO_FILE_PHYSFS *)al_get_file_userdata(f); }
static void memfile_fclearerr(ALLEGRO_FILE *fp) { ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); mf->eof = false; }
static off_t memfile_fsize(ALLEGRO_FILE *fp) { ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); return mf->size; }
static bool curl_file_feof(ALLEGRO_FILE *f) { CURL_FILE *cf = al_get_file_userdata(f); return (cf->buffer_pos == 0 && !cf->still_running); }
/* doesn't quite match up to stdio here, an feof after a seek will return false, even if it seeks past the end of the file */ static bool memfile_feof(ALLEGRO_FILE *fp) { ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); return mf->eof; }