diff --git a/cucul/cucul.h b/cucul/cucul.h index e8378b8..3e24c4b 100644 --- a/cucul/cucul.h +++ b/cucul/cucul.h @@ -278,6 +278,19 @@ __extern int cucul_canvas_set_figfont(cucul_canvas_t *, char const *); __extern int cucul_put_figchar(cucul_canvas_t *, uint32_t); /* @} */ +/** \defgroup cucul_file libcucul file IO + * + * These functions allow to read and write files in a platform-independent + * way. + * @{ */ +__extern cucul_file_t *cucul_file_open(char const *, const char *); +__extern int cucul_file_close(cucul_file_t *); +__extern size_t cucul_file_read(cucul_file_t *, void *, size_t); +__extern size_t cucul_file_write(cucul_file_t *, const void *, size_t); +__extern char * cucul_file_gets(cucul_file_t *, char *, int); +__extern int cucul_file_eof(cucul_file_t *); +/* @} */ + /** \defgroup cucul_importexport libcucul importers/exporters from/to various * formats * diff --git a/cucul/cucul_internals.h b/cucul/cucul_internals.h index cd34214..da7a0c2 100644 --- a/cucul/cucul_internals.h +++ b/cucul/cucul_internals.h @@ -77,10 +77,4 @@ extern uint32_t _cucul_attr_to_rgb24bg(uint32_t); extern void _cucul_save_frame_info(cucul_canvas_t *); extern void _cucul_load_frame_info(cucul_canvas_t *); -/* File functions */ -extern cucul_file_t *_cucul_file_open(const char *, const char *); -extern int _cucul_file_close(cucul_file_t *); -extern int _cucul_file_eof(cucul_file_t *); -extern char *_cucul_file_gets(char *, int, cucul_file_t *); - #endif /* __CUCUL_INTERNALS_H__ */ diff --git a/cucul/figfont.c b/cucul/figfont.c index 81873a7..64d216f 100644 --- a/cucul/figfont.c +++ b/cucul/figfont.c @@ -301,7 +301,7 @@ cucul_figfont_t * open_figfont(char const *path) } /* Open font: if not found, try .tlf, then .flf */ - f = _cucul_file_open(path, "r"); + f = cucul_file_open(path, "r"); #if !defined __KERNEL__ && defined HAVE_SNPRINTF #if (! defined(snprintf)) && ( defined(_WIN32) || defined(WIN32) ) && (! defined(__CYGWIN__)) @@ -312,13 +312,13 @@ cucul_figfont_t * open_figfont(char const *path) { snprintf(altpath, 2047, "%s.tlf", path); altpath[2047] = '\0'; - f = _cucul_file_open(altpath, "r"); + f = cucul_file_open(altpath, "r"); } if(!f) { snprintf(altpath, 2047, "%s.flf", path); altpath[2047] = '\0'; - f = _cucul_file_open(altpath, "r"); + f = cucul_file_open(altpath, "r"); } #endif if(!f) @@ -332,14 +332,14 @@ cucul_figfont_t * open_figfont(char const *path) ff->print_direction = 0; ff->full_layout = 0; ff->codetag_count = 0; - _cucul_file_gets(buf, 2048, f); + cucul_file_gets(f, buf, 2048); if(sscanf(buf, "%*[ft]lf2a%6s %u %u %u %i %u %u %u %u\n", hardblank, &ff->height, &ff->baseline, &ff->max_length, &ff->old_layout, &comment_lines, &ff->print_direction, &ff->full_layout, &ff->codetag_count) < 6) { debug("figfont error: `%s' has invalid header: %s", path, buf); - _cucul_file_close(f); + cucul_file_close(f); free(ff); seterrno(EINVAL); return NULL; @@ -351,7 +351,7 @@ cucul_figfont_t * open_figfont(char const *path) { debug("figfont error: `%s' has invalid layout %i/%u", path, ff->old_layout, ff->full_layout); - _cucul_file_close(f); + cucul_file_close(f); free(ff); seterrno(EINVAL); return NULL; @@ -361,14 +361,14 @@ cucul_figfont_t * open_figfont(char const *path) /* Skip comment lines */ for(i = 0; i < comment_lines; i++) - _cucul_file_gets(buf, 2048, f); + cucul_file_gets(f, buf, 2048); /* Read mandatory characters (32-127, 196, 214, 220, 228, 246, 252, 223) * then read additional characters. */ ff->glyphs = 0; ff->lookup = NULL; - for(i = 0, size = 0; !_cucul_file_eof(f); ff->glyphs++) + for(i = 0, size = 0; !cucul_file_eof(f); ff->glyphs++) { if((ff->glyphs % 2048) == 0) ff->lookup = realloc(ff->lookup, @@ -385,7 +385,7 @@ cucul_figfont_t * open_figfont(char const *path) } else { - if(_cucul_file_gets(buf, 2048, f) == NULL) + if(cucul_file_gets(f, buf, 2048) == NULL) break; /* Ignore blank lines, as in jacky.flf */ @@ -396,7 +396,7 @@ cucul_figfont_t * open_figfont(char const *path) if(buf[0] == '-') { for(j = 0; j < ff->height; j++) - _cucul_file_gets(buf, 2048, f); + cucul_file_gets(f, buf, 2048); continue; } @@ -423,12 +423,12 @@ cucul_figfont_t * open_figfont(char const *path) if(i + 2048 >= size) data = realloc(data, size += 2048); - _cucul_file_gets(data + i, 2048, f); + cucul_file_gets(f, data + i, 2048); i = (uintptr_t)strchr(data + i, 0) - (uintptr_t)data; } } - _cucul_file_close(f); + cucul_file_close(f); if(ff->glyphs < EXT_GLYPHS) { diff --git a/cucul/file.c b/cucul/file.c index 8553e40..b6f1ab1 100644 --- a/cucul/file.c +++ b/cucul/file.c @@ -46,21 +46,24 @@ struct cucul_file int eof, zip; # endif FILE *f; + int readonly; }; #endif -cucul_file_t *_cucul_file_open(char const *path, const char *mode) +cucul_file_t *cucul_file_open(char const *path, const char *mode) { #if defined __KERNEL__ return NULL; #else cucul_file_t *fp = malloc(sizeof(*fp)); + fp->readonly = !strchr(mode, 'r'); + # if defined HAVE_ZLIB_H uint8_t buf[4]; unsigned int skip_size = 0; - fp->gz = gzopen(path, "rb"); + fp->gz = gzopen(path, fp->readonly ? "rb" : "wb"); if(!fp->gz) { free(fp); @@ -70,41 +73,44 @@ cucul_file_t *_cucul_file_open(char const *path, const char *mode) fp->eof = 0; fp->zip = 0; - /* Parse ZIP file and go to start of first file */ - gzread(fp->gz, buf, 4); - if(memcmp(buf, "PK\3\4", 4)) + if(fp->readonly) { - gzseek(fp->gz, 0, SEEK_SET); - return fp; - } + /* Parse ZIP file and go to start of first file */ + gzread(fp->gz, buf, 4); + if(memcmp(buf, "PK\3\4", 4)) + { + gzseek(fp->gz, 0, SEEK_SET); + return fp; + } - fp->zip = 1; + fp->zip = 1; - gzseek(fp->gz, 22, SEEK_CUR); + gzseek(fp->gz, 22, SEEK_CUR); - gzread(fp->gz, buf, 2); /* Filename size */ - skip_size += (uint16_t)buf[0] | ((uint16_t)buf[1] << 8); - gzread(fp->gz, buf, 2); /* Extra field size */ - skip_size += (uint16_t)buf[0] | ((uint16_t)buf[1] << 8); + gzread(fp->gz, buf, 2); /* Filename size */ + skip_size += (uint16_t)buf[0] | ((uint16_t)buf[1] << 8); + gzread(fp->gz, buf, 2); /* Extra field size */ + skip_size += (uint16_t)buf[0] | ((uint16_t)buf[1] << 8); - gzseek(fp->gz, skip_size, SEEK_CUR); + gzseek(fp->gz, skip_size, SEEK_CUR); - /* Initialise inflate stream */ - fp->stream.total_out = 0; - fp->stream.zalloc = NULL; - fp->stream.zfree = NULL; - fp->stream.opaque = NULL; - fp->stream.next_in = NULL; - fp->stream.avail_in = 0; + /* Initialise inflate stream */ + fp->stream.total_out = 0; + fp->stream.zalloc = NULL; + fp->stream.zfree = NULL; + fp->stream.opaque = NULL; + fp->stream.next_in = NULL; + fp->stream.avail_in = 0; - if(inflateInit2(&fp->stream, -MAX_WBITS)) - { - free(fp); - gzclose(fp->gz); - return NULL; + if(inflateInit2(&fp->stream, -MAX_WBITS)) + { + free(fp); + gzclose(fp->gz); + return NULL; + } } # else - fp->f = fopen(path, mode); + fp->f = fopen(path, fmode); if(!fp->f) { @@ -117,7 +123,7 @@ cucul_file_t *_cucul_file_open(char const *path, const char *mode) #endif } -int _cucul_file_close(cucul_file_t *fp) +int cucul_file_close(cucul_file_t *fp) { #if defined __KERNEL__ return 0; @@ -134,18 +140,34 @@ int _cucul_file_close(cucul_file_t *fp) #endif } -int _cucul_file_eof(cucul_file_t *fp) +size_t cucul_file_read(cucul_file_t *fp, void *ptr, size_t size) { #if defined __KERNEL__ - return 1; + return 0; #elif defined HAVE_ZLIB_H - return fp->zip ? fp->eof : gzeof(fp->gz); + if(fp->zip) + return zipread(fp, ptr, size); + return gzread(fp->gz, ptr, size); #else - return feof(fp->f); + return fread(ptr, 1, size, fp->f); +#endif +} + +size_t cucul_file_write(cucul_file_t *fp, const void *ptr, size_t size) +{ + if(fp->readonly) + return 0; + +#if defined __KERNEL__ + return 0; +#elif defined HAVE_ZLIB_H + return gzwrite(fp->gz, ptr, size); +#else + return fwrite(ptr, 1, size, fp->f); #endif } -char *_cucul_file_gets(char *s, int size, cucul_file_t *fp) +char *cucul_file_gets(cucul_file_t *fp, char *s, int size) { #if defined __KERNEL__ return NULL; @@ -178,6 +200,17 @@ char *_cucul_file_gets(char *s, int size, cucul_file_t *fp) #endif } +int cucul_file_eof(cucul_file_t *fp) +{ +#if defined __KERNEL__ + return 1; +#elif defined HAVE_ZLIB_H + return fp->zip ? fp->eof : gzeof(fp->gz); +#else + return feof(fp->f); +#endif +} + #if !defined __KERNEL__ && defined HAVE_ZLIB_H static int zipread(cucul_file_t *fp, void *buf, unsigned int len) {