diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2023-06-28 17:29:32 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2023-06-28 17:29:32 +0000 |
commit | 23ce26f64c34e30951ad9ade2151552ed77e7357 (patch) | |
tree | d73b31a0c2f7c7be4a69f8a8e84e00dd39c432b5 /lib/pmfileio.c | |
parent | 1b6e51a266008348ad93ed8b6ac9ec91b5024fea (diff) | |
download | netpbm-mirror-23ce26f64c34e30951ad9ade2151552ed77e7357.tar.gz netpbm-mirror-23ce26f64c34e30951ad9ade2151552ed77e7357.tar.xz netpbm-mirror-23ce26f64c34e30951ad9ade2151552ed77e7357.zip |
promote Advanced to Stable
git-svn-id: http://svn.code.sf.net/p/netpbm/code/stable@4558 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'lib/pmfileio.c')
-rw-r--r-- | lib/pmfileio.c | 229 |
1 files changed, 168 insertions, 61 deletions
diff --git a/lib/pmfileio.c b/lib/pmfileio.c index bea01abe..5d6d9bc1 100644 --- a/lib/pmfileio.c +++ b/lib/pmfileio.c @@ -31,6 +31,7 @@ /* This makes the the x64() functions available on AIX */ #include "netpbm/pm_config.h" +#include <stdbool.h> #include <unistd.h> #include <assert.h> #include <stdio.h> @@ -451,27 +452,16 @@ pm_tmpfile_fd(void) { } - -FILE * -pm_openr_seekable(const char name[]) { +static bool +isSeekable(FILE * const fP) { /*---------------------------------------------------------------------------- - Open the file named by name[] such that it is seekable (i.e. it can be - rewound and read in multiple passes with fseek()). + The file is seekable -- we can set its read/write position to anything we + want. - If the file is actually seekable, this reduces to the same as - pm_openr(). If not, we copy the named file to a temporary file - and return that file's stream descriptor. - - We use a file that the operating system recognizes as temporary, so - it picks the filename and deletes the file when Caller closes it. + If we can't tell if it is seekable, we return false. -----------------------------------------------------------------------------*/ - int stat_rc; - int seekable; /* logical: file is seekable */ + int statRc; struct stat statbuf; - FILE * original_file; - FILE * seekable_file; - - original_file = pm_openr((char *) name); /* I would use fseek() to determine if the file is seekable and be a little more general than checking the type of file, but I @@ -485,41 +475,62 @@ pm_openr_seekable(const char name[]) { some other file is, it doesn't hurt much to assume it isn't. */ - stat_rc = fstat(fileno(original_file), &statbuf); - if (stat_rc == 0 && S_ISREG(statbuf.st_mode)) - seekable = TRUE; - else - seekable = FALSE; + statRc = fstat(fileno(fP), &statbuf); + + return statRc == 0 && S_ISREG(statbuf.st_mode); +} + + + +FILE * +pm_openr_seekable(const char name[]) { +/*---------------------------------------------------------------------------- + Open the file named by name[] such that it is seekable (i.e. it can be + rewound and read in multiple passes with fseek()). + + If the file is actually seekable, this reduces to the same as + pm_openr(). If not, we copy the named file to a temporary file + and return that file's stream descriptor. + + We use a file that the operating system recognizes as temporary, so + it picks the filename and deletes the file when Caller closes it. +-----------------------------------------------------------------------------*/ + FILE * originalFileP; + FILE * seekableFileP; + + originalFileP = pm_openr((char *) name); - if (seekable) { - seekable_file = original_file; + if (isSeekable(originalFileP)) { + seekableFileP = originalFileP; } else { - seekable_file = pm_tmpfile(); + seekableFileP = pm_tmpfile(); /* Copy the input into the temporary seekable file */ - while (!feof(original_file) && !ferror(original_file) - && !ferror(seekable_file)) { + while (!feof(originalFileP) && !ferror(originalFileP) + && !ferror(seekableFileP)) { char buffer[4096]; - int bytes_read; - bytes_read = fread(buffer, 1, sizeof(buffer), original_file); - fwrite(buffer, 1, bytes_read, seekable_file); + size_t nBytesRead; + + nBytesRead = fread(buffer, 1, sizeof(buffer), originalFileP); + fwrite(buffer, 1, nBytesRead, seekableFileP); } - if (ferror(original_file)) + if (ferror(originalFileP)) pm_error("Error reading input file into temporary file. " "Errno = %s (%d)", strerror(errno), errno); - if (ferror(seekable_file)) + if (ferror(seekableFileP)) pm_error("Error writing input into temporary file. " "Errno = %s (%d)", strerror(errno), errno); - pm_close(original_file); + pm_close(originalFileP); { - int seek_rc; - seek_rc = fseek(seekable_file, 0, SEEK_SET); - if (seek_rc != 0) + int seekRc; + + seekRc = fseek(seekableFileP, 0, SEEK_SET); + if (seekRc != 0) pm_error("fseek() failed to rewind temporary file. " "Errno = %s (%d)", strerror(errno), errno); } } - return seekable_file; + return seekableFileP; } @@ -799,48 +810,50 @@ pm_readmagicnumber(FILE * const ifP) { Oliver Trepte, oliver@fysik4.kth.se, 930613 */ -#define PM_BUF_SIZE 16384 /* First try this size of the buffer, then - double this until we reach PM_MAX_BUF_INC */ -#define PM_MAX_BUF_INC 65536 /* Don't allocate more memory in larger blocks - than this. */ +static size_t const initBufSz = 16384; + /* First try this size of the buffer, then + double this until we reach 'maxBufInc' */ +static size_t const maxBufInc = 65536; + /* Don't allocate more memory in larger blocks than this. */ char * -pm_read_unknown_size(FILE * const file, - long * const nread) { - long nalloc; +pm_read_unknown_size(FILE * const ifP, + long * const nReadP) { + size_t nAlloc; char * buf; + size_t nRead; bool eof; - *nread = 0; - nalloc = PM_BUF_SIZE; - MALLOCARRAY(buf, nalloc); + nAlloc = initBufSz; /* initial value */ - if (!buf) - pm_error("Failed to allocate %lu bytes for read buffer", - (unsigned long) nalloc); + MALLOCARRAY(buf, nAlloc); - eof = FALSE; /* initial value */ + if (!buf) + pm_error("Failed to allocate %lu bytes for read buffer", nAlloc); - while(!eof) { + for (eof = false, nRead = 0; !eof; ) { int val; - if (*nread >= nalloc) { /* We need a larger buffer */ - if (nalloc > PM_MAX_BUF_INC) - nalloc += PM_MAX_BUF_INC; + if (nRead >= nAlloc) { /* We need a larger buffer */ + if (nAlloc > maxBufInc) + nAlloc += maxBufInc; else - nalloc += nalloc; - REALLOCARRAY(buf, nalloc); + nAlloc += nAlloc; + REALLOCARRAY(buf, nAlloc); if (!buf) pm_error("Failed to allocate %lu bytes for read buffer", - (unsigned long) nalloc); + nAlloc); } - val = getc(file); + val = getc(ifP); if (val == EOF) - eof = TRUE; + eof = true; else - buf[(*nread)++] = val; + buf[nRead++] = val; } + + *nReadP = (long)nRead; + return buf; } @@ -926,6 +939,72 @@ pm_getline(FILE * const ifP, +void +pm_readfile(FILE * const fileP, + const unsigned char ** const bytesP, + size_t * const szP) { + + unsigned char * buf; + size_t allocatedSz; + size_t szSoFar; + size_t chunkSz; + bool eof; + + for (szSoFar = 0, buf = NULL, allocatedSz = 0, chunkSz = 4096, + eof = false; + !eof; ) { + + size_t bytesReadCt; + + if (szSoFar + chunkSz > allocatedSz) { + allocatedSz = szSoFar + chunkSz; + REALLOCARRAY(buf, allocatedSz); + + if (!buf) { + pm_error("Failed to get memory for %lu byte input buffer", + allocatedSz); + } + } + bytesReadCt = fread(buf + szSoFar, 1, chunkSz, fileP); + + if (ferror(fileP)) + pm_error("Failed to read input from file"); + + szSoFar += bytesReadCt; + + if (bytesReadCt < chunkSz) + eof = true; + else { + /* Double buffer and read size up to 1 MiB */ + if (szSoFar <= 1024*1024) + chunkSz = szSoFar; + } + } + + *bytesP = buf; + *szP = szSoFar; +} + + + +void +pm_writefile(FILE * const fileP, + const unsigned char * const bytes, + size_t const sz) { + + size_t bytesWrittenCt; + + bytesWrittenCt = fwrite(bytes, 1, sz, fileP); + + if (bytesWrittenCt != sz) { + pm_error("Failed to write %lu bytes to Standard Output. " + "%lu bytes successfully written", + sz, bytesWrittenCt); + } +} + + + union cheat { uint32_t l; short s; @@ -965,6 +1044,20 @@ pm_bs_long(long const l) { +int +pm_is_seekable(FILE * const fP) { + + return isSeekable(fP) ? 1 : 0; +} + + + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpragmas" +#pragma GCC diagnostic ignored "-Wduplicated-cond" + + + void pm_tell2(FILE * const fileP, void * const fileposP, @@ -1005,6 +1098,10 @@ pm_tell2(FILE * const fileP, +#pragma GCC diagnostic pop + + + unsigned int pm_tell(FILE * const fileP) { @@ -1017,6 +1114,12 @@ pm_tell(FILE * const fileP) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpragmas" +#pragma GCC diagnostic ignored "-Wduplicated-cond" + + + void pm_seek2(FILE * const fileP, const pm_filepos * const fileposP, @@ -1044,6 +1147,10 @@ pm_seek2(FILE * const fileP, +#pragma GCC diagnostic pop + + + void pm_seek(FILE * const fileP, unsigned long filepos) { /*---------------------------------------------------------------------------- |