diff options
author | Guillermo S. Romero <gsr.b3d@infernal-iceberg.com> | 2009-09-24 01:26:24 +0400 |
---|---|---|
committer | Guillermo S. Romero <gsr.b3d@infernal-iceberg.com> | 2009-09-24 01:26:24 +0400 |
commit | 6c79d757acf4bccf3dc5b53f1916826bdb99cc8b (patch) | |
tree | 08e23173ab2330bbf79c3eefdf0c927dc7f782f1 /source | |
parent | 6e941a728a2e491f67832504550bb269655b6022 (diff) |
Initial sketch of file access wrappers.
It compiles but does nothing useful yet. The "//" comments are notes to
remember what to do in each block.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenlib/BLI_bfile.h | 138 | ||||
-rw-r--r-- | source/blender/blenlib/intern/BLI_bfile.c | 231 |
2 files changed, 369 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_bfile.h b/source/blender/blenlib/BLI_bfile.h new file mode 100644 index 00000000000..92543558a19 --- /dev/null +++ b/source/blender/blenlib/BLI_bfile.h @@ -0,0 +1,138 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 by Stichting Blender Foundation. + * All rights reserved. + * + * ***** END GPL LICENSE BLOCK ***** + * BFILE* based abstraction of file access. + */ + +#ifndef BLI_BFILE_H +#define BLI_BFILE_H + +/* For fopen's FILE */ +#include <stdio.h> + +/** + Defines for the bflags param. + */ +/* Special handling: */ +/* For "symmetry" of flags */ +#define BFILE_NORMAL (0) +/* No supervision, just translate // if needed, RISKY */ +#define BFILE_RAW (1<<0) +/* Path is relative to config dirs */ +#define BFILE_CONFIG (1<<1) +/* Path is for current session temp file */ +#define BFILE_TEMP (1<<2) + +/* Config handling, special cases: */ +#define BFILE_USERONLY (1<<3) +#define BFILE_SYSONLY (1<<4) + +/* Compression to apply on close: */ +#define BFILE_GZIP (1<<5) + +/** + File descriptor for Blender abstracted file access. + */ +typedef struct { + FILE *stream; + int fd; + + /* Anything below should not be touched directly */ + int uflags; /* Special options requested by upper level, copy of bflags */ + char *fpath; /* Final/requested path name */ + char *tpath; /* Temp path name if applicable */ + int type; /* Own flags, common classification of open and fopen */ + int error; /* An op caused an error, unsafe to replace older files */ +} BFILE; + +/** + Open a BFILE* with fopen()-like syntax. + */ +BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags); + +/** + Open a BFILE* with open()-like syntax. + */ +BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags); + +/** + Get the FILE* associated with the BFILE*. + */ +FILE *BLI_bfile_file_from_bfile(BFILE *bfile); + +/** + Get the fd associated with the BFILE*. + */ +int BLI_bfile_fd_from_bfile(BFILE *bfile); + +/** + write()-like using BFILE*. + */ +ssize_t BLI_bfile_write(BFILE *f, const void *buf, size_t count); + +/** + read()-like using BFILE*. + */ +ssize_t BLI_bfile_read(BFILE *f, void *buf, size_t count); + +/** + fwrite()-like using BFILE*. + */ +size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb, BFILE *f); + +/** + fread()-like using BFILE*. + */ +size_t BLI_bfile_fread(void *ptr, size_t size, size_t nmemb, BFILE *f); + +/** + Close a BFILE, to match close() and fclose(). + */ +void BLI_bfile_close(BFILE *bfile); + +/** + Clear error status. + Call it only if the error has been really handled. + */ +void BLI_bfile_clear_error(BFILE *bfile); + +/** + Set the error status. + Call it to mark writing by a 3rd party failed (libjpeg reported error, ie). + */ +void BLI_bfile_set_error(BFILE *bfile, int error); + +/* +TODO +Maybe also provide more OS/libc things like: +fflush +fprintf and related +fscanf +fgetc/fputc and related +fseek and related + +Probably good to do: +readdir (compacted list showing all files for a "directory" (user versions on top of system's)) +*/ + +#endif /* ifndef BLI_BFILE_H */ diff --git a/source/blender/blenlib/intern/BLI_bfile.c b/source/blender/blenlib/intern/BLI_bfile.c new file mode 100644 index 00000000000..06e75a9a3ca --- /dev/null +++ b/source/blender/blenlib/intern/BLI_bfile.c @@ -0,0 +1,231 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 by Stichting Blender Foundation. + * All rights reserved. + * + * ***** END GPL LICENSE BLOCK ***** + * BFILE* based abstraction for file access. + */ + +#include <string.h> + +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_bfile.h" + +// This would provide config paths and their oldest viable version +// so if there is an uncompatible change, user's old versions are not loaded +//#include "bfile_tables.h" + +/* Internal bfile type flags */ +#define BTF_OPEN (0) +#define BTF_FOPEN (1<<0) +#define BTF_READ (1<<1) +#define BTF_WRITE (1<<2) +#define BTF_AT_END (1<<3) +#define BTF_DISCARD (1<<4) + + +void fill_paths(BFILE *bfile, const char *path) { + char* source_path = NULL; + int bflags = bfile->uflags; + + if(bflags & BFILE_NORMAL || bflags & BFILE_RAW) { +// bfile->fpath is path with // replaced + } + if(bflags & BFILE_TEMP) { +// bfile->fpath is tempdir+path + } + if(bflags & BFILE_CONFIG) { +// bfile->fpath is userdir+version+path +// source_path is first hit in (if using fallback to older versions) +// userdir+curversion+path (... userdir+limitversion+path) sysdir+path +// (limitversion is based in path, using some kind of regex or "tables") + } + + if(bfile->type & BTF_WRITE && !(bflags & BFILE_RAW)) { + /* Generate temp path */ + // bfile->tpath is fpath+randstring + if(!(bfile->type & BTF_DISCARD)) { + /* Copy data to tpath */ + if(source_path) { + // copy it from older version or sys version + } + } + } else { + bfile->tpath = bfile->fpath; + } +} + +BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags) { + BFILE *bfile; + + bfile = MEM_mallocN(sizeof(BFILE), "bfile-fopen"); + bfile->type = BTF_FOPEN; + bfile->uflags = bflags; + + /* From fopen() doc, we can guess some logic: + r BTF_READ + r+ BTF_READ | BTF_WRITE + w BTF_DISCARD | BTF_WRITE + w+ BTF_DISCARD | BTF_WRITE | BTF_READ + a BTF_AT_END | BTF_WRITE + a+ BTF_AT_END | BTF_WRITE | BTF_READ + */ + if(strchr(mode, 'r')) + bfile->type |= BTF_READ; + if(strchr(mode, 'w')) + bfile->type |= (BTF_DISCARD | BTF_WRITE); + if(strchr(mode, 'a')) + bfile->type |= (BTF_AT_END | BTF_WRITE); + if(strchr(mode, '+')) + bfile->type |= (BTF_READ | BTF_WRITE); + + fill_paths(bfile, path); + + bfile->stream = fopen(bfile->tpath, mode); + // detect failed fopen + bfile->fd = fileno(bfile->stream); + return bfile; +} + + +BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags) { + BFILE *bfile; + + bfile = MEM_mallocN(sizeof(BFILE), "bfile-open"); + bfile->type = BTF_OPEN; + bfile->uflags = bflags; + + /* Easy mapping for open() */ + if(flags & O_RDONLY) + bfile->type |= BTF_READ; + if(flags & O_WRONLY) + bfile->type |= BTF_WRITE; + if(flags & O_RDWR) + bfile->type |= (BTF_READ | BTF_WRITE); + if(flags & O_APPEND) + bfile->type |= BTF_AT_END; + if(flags & O_TRUNC) + bfile->type |= BTF_DISCARD; + + fill_paths(bfile, pathname); + + bfile->fd = open(bfile->tpath, flags); + // detect failed open +// bfile->stream = fdopen(bfile->fd, XXX); /* MSWindows _fdopen? */ + return bfile; +} + + +FILE *BLI_bfile_file_from_bfile(BFILE *bfile) { + return bfile->stream; +} + + +int BLI_bfile_fd_from_bfile(BFILE *bfile) { + return bfile->fd; +} + + +ssize_t BLI_bfile_write(BFILE *f, const void *buf, size_t count) { + ssize_t ret; + + ret = write((f->fd), buf, count); + if (ret == -1) { + f->error = 1; + } + + return ret; +} + + +ssize_t BLI_bfile_read(BFILE *f, void *buf, size_t count) { + ssize_t ret; + + ret = read((f->fd), buf, count); + if (ret == -1) { + f->error = 1; + } + + return ret; +} + + +size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb, BFILE *f) { + size_t ret; + + ret = fwrite(ptr, size, nmemb, f->stream); + if (ret < 0) { + f->error = 1; + } + + return ret; +} + + +size_t BLI_bfile_fread(void *ptr, size_t size, size_t nmemb, BFILE *f) { + size_t ret; + + ret = fread(ptr, size, nmemb, f->stream); + if ((ret < 0) && ferror(f->stream)) { + f->error = 1; + } + + return ret; +} + + +void BLI_bfile_close(BFILE *bfile) { + if((bfile->type | BTF_WRITE) && + !(bfile->uflags | BFILE_RAW)) { + /* Make sure data is on disk */ + /* Move to final name if no errors */ + } + + /* Normal close */ + + /* Cleanup */ + if(bfile->fpath) { + MEM_freeN(bfile->fpath); + } + if(bfile->tpath) { + MEM_freeN(bfile->tpath); + } +} + + +void BLI_bfile_clear_error(BFILE *bfile) { + bfile->error = 0; +} + + +void BLI_bfile_set_error(BFILE *bfile, int error) { + /* No cheating, use clear_error() for 0 */ + if (error) { + bfile->error = error; + } +} |