mirror of
https://github.com/reactos/reactos.git
synced 2024-09-10 21:04:26 +00:00
195 lines
3.7 KiB
C
195 lines
3.7 KiB
C
![]() |
/*
|
||
|
* Miscellaneous I/O functions
|
||
|
*/
|
||
|
|
||
|
#include "fitz-base.h"
|
||
|
#include "fitz-stream.h"
|
||
|
|
||
|
int fz_tell(fz_stream *stm)
|
||
|
{
|
||
|
if (stm->mode == FZ_SREAD)
|
||
|
return fz_rtell(stm);
|
||
|
return fz_wtell(stm);
|
||
|
}
|
||
|
|
||
|
int fz_seek(fz_stream *stm, int offset, int whence)
|
||
|
{
|
||
|
if (stm->mode == FZ_SREAD)
|
||
|
return fz_rseek(stm, offset, whence);
|
||
|
return fz_wseek(stm, offset, whence);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Read a line terminated by LF or CR or CRLF.
|
||
|
*/
|
||
|
|
||
|
int fz_readline(fz_stream *stm, char *mem, int n)
|
||
|
{
|
||
|
char *s = mem;
|
||
|
int c = EOF;
|
||
|
while (n > 1)
|
||
|
{
|
||
|
c = fz_readbyte(stm);
|
||
|
if (c == EOF)
|
||
|
break;
|
||
|
if (c == '\r') {
|
||
|
c = fz_peekbyte(stm);
|
||
|
if (c == '\n')
|
||
|
c = fz_readbyte(stm);
|
||
|
break;
|
||
|
}
|
||
|
if (c == '\n')
|
||
|
break;
|
||
|
*s++ = c;
|
||
|
n--;
|
||
|
}
|
||
|
if (n)
|
||
|
*s = '\0';
|
||
|
return s - mem;
|
||
|
}
|
||
|
|
||
|
struct fz_linkedbuf_s
|
||
|
{
|
||
|
int len;
|
||
|
struct fz_linkedbuf_s * next;
|
||
|
};
|
||
|
|
||
|
typedef struct fz_linkedbuf_s fz_linkedbuf;
|
||
|
|
||
|
fz_error *fz_newlinkedbuf(fz_linkedbuf **bufp, int len, unsigned char **data)
|
||
|
{
|
||
|
fz_linkedbuf *buf;
|
||
|
|
||
|
buf = *bufp = fz_malloc(sizeof(fz_linkedbuf) + len);
|
||
|
if (!buf) return fz_outofmem;
|
||
|
buf->next = nil;
|
||
|
buf->len = len;
|
||
|
*data = (unsigned char*)buf + sizeof(fz_linkedbuf);
|
||
|
return nil;
|
||
|
}
|
||
|
|
||
|
fz_error *fz_growlinkedbuf(fz_linkedbuf *buf, int len, unsigned char **data)
|
||
|
{
|
||
|
fz_linkedbuf *newbuf;
|
||
|
fz_error *error;
|
||
|
|
||
|
error = fz_newlinkedbuf(&newbuf, len, data);
|
||
|
if (error) return error;
|
||
|
while (buf->next)
|
||
|
buf = buf->next;
|
||
|
buf->next = newbuf;
|
||
|
return nil;
|
||
|
}
|
||
|
|
||
|
void fz_droplinkedbuf(fz_linkedbuf *buf)
|
||
|
{
|
||
|
fz_linkedbuf *next;
|
||
|
while (buf) {
|
||
|
next = buf->next;
|
||
|
fz_free(buf);
|
||
|
buf = next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int fz_linkedbuflen(fz_linkedbuf *buf)
|
||
|
{
|
||
|
int len = 0;
|
||
|
while (buf) {
|
||
|
len += buf->len;
|
||
|
buf = buf->next;
|
||
|
}
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
fz_error *fz_linearizelinkedbuf(fz_linkedbuf *buf, int len, unsigned char **datap)
|
||
|
{
|
||
|
unsigned char *data, *bufdata;
|
||
|
int tocopy;
|
||
|
int buflen = fz_linkedbuflen(buf);
|
||
|
assert(len <= buflen);
|
||
|
data = *datap = fz_malloc(len);
|
||
|
if (!data) return fz_outofmem;
|
||
|
|
||
|
while (len > 0)
|
||
|
{
|
||
|
bufdata = (unsigned char*)buf + sizeof(fz_linkedbuf);
|
||
|
tocopy = MIN(len, buf->len);
|
||
|
memmove(data, bufdata, tocopy);
|
||
|
buf = buf->next;
|
||
|
data += tocopy;
|
||
|
len -= tocopy;
|
||
|
}
|
||
|
return nil;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Utility function to consume all the contents of an input stream into
|
||
|
* a freshly allocated buffer; realloced and trimmed to size.
|
||
|
*/
|
||
|
|
||
|
enum { MINCHUNKSIZE = 1024 * 8 };
|
||
|
enum { MAXCHUNKSIZE = MINCHUNKSIZE * 10 };
|
||
|
|
||
|
int fz_readall(fz_buffer **bufp, fz_stream *stm)
|
||
|
{
|
||
|
fz_buffer *real;
|
||
|
fz_error *error;
|
||
|
fz_linkedbuf *buf;
|
||
|
unsigned char *data;
|
||
|
int totallen;
|
||
|
int n;
|
||
|
int chunksize = MINCHUNKSIZE;
|
||
|
|
||
|
*bufp = nil;
|
||
|
|
||
|
totallen = 0;
|
||
|
error = fz_newlinkedbuf(&buf, chunksize, &data);
|
||
|
if (error)
|
||
|
return -1;
|
||
|
|
||
|
while (1)
|
||
|
{
|
||
|
n = fz_read(stm, data, chunksize);
|
||
|
if (n < 0)
|
||
|
{
|
||
|
fz_free(buf);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
totallen += n;
|
||
|
if (n != chunksize)
|
||
|
break;
|
||
|
|
||
|
if (chunksize < MAXCHUNKSIZE)
|
||
|
chunksize = chunksize + MINCHUNKSIZE;
|
||
|
error = fz_growlinkedbuf(buf, chunksize, &data);
|
||
|
if (error)
|
||
|
{
|
||
|
fz_droplinkedbuf(buf);
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
error = fz_linearizelinkedbuf(buf, totallen, &data);
|
||
|
fz_droplinkedbuf(buf);
|
||
|
if (error)
|
||
|
return -1;
|
||
|
|
||
|
real = *bufp = fz_malloc(sizeof(fz_buffer));
|
||
|
if (!real)
|
||
|
{
|
||
|
fz_free(data);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
real->refs = 1;
|
||
|
real->ownsdata = 1;
|
||
|
real->bp = data;
|
||
|
real->rp = data;
|
||
|
real->wp = data + totallen;
|
||
|
real->ep = data + totallen;
|
||
|
real->eof = 1;
|
||
|
return totallen;
|
||
|
}
|
||
|
|