forked from KolibriOS/kolibrios
202 lines
2.9 KiB
C
202 lines
2.9 KiB
C
|
#include "fitz.h"
|
||
|
|
||
|
int
|
||
|
fz_read(fz_stream *stm, unsigned char *buf, int len)
|
||
|
{
|
||
|
int count, n;
|
||
|
|
||
|
count = MIN(len, stm->wp - stm->rp);
|
||
|
if (count)
|
||
|
{
|
||
|
memcpy(buf, stm->rp, count);
|
||
|
stm->rp += count;
|
||
|
}
|
||
|
|
||
|
if (count == len || stm->error || stm->eof)
|
||
|
return count;
|
||
|
|
||
|
assert(stm->rp == stm->wp);
|
||
|
|
||
|
if (len - count < stm->ep - stm->bp)
|
||
|
{
|
||
|
n = stm->read(stm, stm->bp, stm->ep - stm->bp);
|
||
|
if (n < 0)
|
||
|
{
|
||
|
stm->error = 1;
|
||
|
return fz_rethrow(n, "read error");
|
||
|
}
|
||
|
else if (n == 0)
|
||
|
{
|
||
|
stm->eof = 1;
|
||
|
}
|
||
|
else if (n > 0)
|
||
|
{
|
||
|
stm->rp = stm->bp;
|
||
|
stm->wp = stm->bp + n;
|
||
|
stm->pos += n;
|
||
|
}
|
||
|
|
||
|
n = MIN(len - count, stm->wp - stm->rp);
|
||
|
if (n)
|
||
|
{
|
||
|
memcpy(buf + count, stm->rp, n);
|
||
|
stm->rp += n;
|
||
|
count += n;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
n = stm->read(stm, buf + count, len - count);
|
||
|
if (n < 0)
|
||
|
{
|
||
|
stm->error = 1;
|
||
|
return fz_rethrow(n, "read error");
|
||
|
}
|
||
|
else if (n == 0)
|
||
|
{
|
||
|
stm->eof = 1;
|
||
|
}
|
||
|
else if (n > 0)
|
||
|
{
|
||
|
stm->pos += n;
|
||
|
count += n;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
fz_fill_buffer(fz_stream *stm)
|
||
|
{
|
||
|
int n;
|
||
|
|
||
|
assert(stm->rp == stm->wp);
|
||
|
|
||
|
if (stm->error || stm->eof)
|
||
|
return;
|
||
|
|
||
|
n = stm->read(stm, stm->bp, stm->ep - stm->bp);
|
||
|
if (n < 0)
|
||
|
{
|
||
|
stm->error = 1;
|
||
|
fz_catch(n, "read error; treating as end of file");
|
||
|
}
|
||
|
else if (n == 0)
|
||
|
{
|
||
|
stm->eof = 1;
|
||
|
}
|
||
|
else if (n > 0)
|
||
|
{
|
||
|
stm->rp = stm->bp;
|
||
|
stm->wp = stm->bp + n;
|
||
|
stm->pos += n;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fz_error
|
||
|
fz_read_all(fz_buffer **bufp, fz_stream *stm, int initial)
|
||
|
{
|
||
|
fz_buffer *buf;
|
||
|
int n;
|
||
|
|
||
|
if (initial < 1024)
|
||
|
initial = 1024;
|
||
|
|
||
|
buf = fz_new_buffer(initial);
|
||
|
|
||
|
while (1)
|
||
|
{
|
||
|
if (buf->len == buf->cap)
|
||
|
fz_grow_buffer(buf);
|
||
|
|
||
|
if (buf->len / 200 > initial)
|
||
|
{
|
||
|
fz_drop_buffer(buf);
|
||
|
return fz_throw("compression bomb detected");
|
||
|
}
|
||
|
|
||
|
n = fz_read(stm, buf->data + buf->len, buf->cap - buf->len);
|
||
|
if (n < 0)
|
||
|
{
|
||
|
fz_drop_buffer(buf);
|
||
|
return fz_rethrow(n, "read error");
|
||
|
}
|
||
|
if (n == 0)
|
||
|
break;
|
||
|
|
||
|
buf->len += n;
|
||
|
}
|
||
|
|
||
|
*bufp = buf;
|
||
|
return fz_okay;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
fz_read_line(fz_stream *stm, char *mem, int n)
|
||
|
{
|
||
|
char *s = mem;
|
||
|
int c = EOF;
|
||
|
while (n > 1)
|
||
|
{
|
||
|
c = fz_read_byte(stm);
|
||
|
if (c == EOF)
|
||
|
break;
|
||
|
if (c == '\r') {
|
||
|
c = fz_peek_byte(stm);
|
||
|
if (c == '\n')
|
||
|
fz_read_byte(stm);
|
||
|
break;
|
||
|
}
|
||
|
if (c == '\n')
|
||
|
break;
|
||
|
*s++ = c;
|
||
|
n--;
|
||
|
}
|
||
|
if (n)
|
||
|
*s = '\0';
|
||
|
}
|
||
|
|
||
|
int
|
||
|
fz_tell(fz_stream *stm)
|
||
|
{
|
||
|
return stm->pos - (stm->wp - stm->rp);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
fz_seek(fz_stream *stm, int offset, int whence)
|
||
|
{
|
||
|
if (stm->seek)
|
||
|
{
|
||
|
if (whence == 1)
|
||
|
{
|
||
|
offset = fz_tell(stm) + offset;
|
||
|
whence = 0;
|
||
|
}
|
||
|
if (whence == 0)
|
||
|
{
|
||
|
unsigned char *p = stm->wp - (stm->pos - offset);
|
||
|
if (p >= stm->bp && p <= stm->wp)
|
||
|
{
|
||
|
stm->rp = p;
|
||
|
stm->eof = 0;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
stm->seek(stm, offset, whence);
|
||
|
stm->eof = 0;
|
||
|
}
|
||
|
else if (whence != 2)
|
||
|
{
|
||
|
if (whence == 0)
|
||
|
offset -= fz_tell(stm);
|
||
|
if (offset < 0)
|
||
|
fz_warn("cannot seek backwards");
|
||
|
/* dog slow, but rare enough */
|
||
|
while (offset-- > 0)
|
||
|
fz_read_byte(stm);
|
||
|
}
|
||
|
else
|
||
|
fz_warn("cannot seek");
|
||
|
}
|