📄 jas_stream.c
字号:
assert(bufsize > 0);
bufptr = buf;
while (bufsize > 1) {
if ((c = jas_stream_getc(stream)) == EOF) {
break;
}
*bufptr++ = c;
--bufsize;
if (c == '\n') {
break;
}
}
*bufptr = '\0';
return buf;
}
int jas_stream_gobble(jas_stream_t *stream, int n)
{
int m;
m = n;
for (m = n; m > 0; --m) {
if (jas_stream_getc(stream) == EOF) {
return n - m;
}
}
return n;
}
int jas_stream_pad(jas_stream_t *stream, int n, int c)
{
int m;
m = n;
for (m = n; m > 0; --m) {
if (jas_stream_putc(stream, c) == EOF)
return n - m;
}
return n;
}
/******************************************************************************\
* Code for getting and setting the stream position.
\******************************************************************************/
int jas_stream_isseekable(jas_stream_t *stream)
{
if (stream->ops_ == &jas_stream_memops) {
return 1;
} else if (stream->ops_ == &jas_stream_fileops) {
if ((*stream->ops_->seek_)(stream->obj_, 0, SEEK_CUR) < 0) {
return 0;
}
return 1;
} else {
return 0;
}
}
int jas_stream_rewind(jas_stream_t *stream)
{
return jas_stream_seek(stream, 0, SEEK_SET);
}
long jas_stream_seek(jas_stream_t *stream, long offset, int origin)
{
long newpos;
/* The buffer cannot be in use for both reading and writing. */
assert(!((stream->bufmode_ & JAS_STREAM_RDBUF) && (stream->bufmode_ &
JAS_STREAM_WRBUF)));
/* Reset the EOF indicator (since we may not be at the EOF anymore). */
stream->flags_ &= ~JAS_STREAM_EOF;
if (stream->bufmode_ & JAS_STREAM_RDBUF) {
if (origin == SEEK_CUR) {
offset -= stream->cnt_;
}
} else if (stream->bufmode_ & JAS_STREAM_WRBUF) {
if (jas_stream_flush(stream)) {
return -1;
}
}
stream->cnt_ = 0;
stream->ptr_ = stream->bufstart_;
stream->bufmode_ &= ~(JAS_STREAM_RDBUF | JAS_STREAM_WRBUF);
if ((newpos = (*stream->ops_->seek_)(stream->obj_, offset, origin))
< 0) {
return -1;
}
return newpos;
}
long jas_stream_tell(jas_stream_t *stream)
{
int adjust;
int offset;
if (stream->bufmode_ & JAS_STREAM_RDBUF) {
adjust = -stream->cnt_;
} else if (stream->bufmode_ & JAS_STREAM_WRBUF) {
adjust = stream->ptr_ - stream->bufstart_;
} else {
adjust = 0;
}
if ((offset = (*stream->ops_->seek_)(stream->obj_, 0, SEEK_CUR)) < 0) {
return -1;
}
return offset + adjust;
}
/******************************************************************************\
* Buffer initialization code.
\******************************************************************************/
static void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf,
int bufsize)
{
/* If this function is being called, the buffer should not have been
initialized yet. */
assert(!stream->bufbase_);
if (bufmode != JAS_STREAM_UNBUF) {
/* The full- or line-buffered mode is being employed. */
if (!buf) {
/* The caller has not specified a buffer to employ, so allocate
one. */
if ((stream->bufbase_ = jas_malloc(JAS_STREAM_BUFSIZE +
JAS_STREAM_MAXPUTBACK))) {
stream->bufmode_ |= JAS_STREAM_FREEBUF;
stream->bufsize_ = JAS_STREAM_BUFSIZE;
} else {
/* The buffer allocation has failed. Resort to unbuffered
operation. */
stream->bufbase_ = stream->tinybuf_;
stream->bufsize_ = 1;
}
} else {
/* The caller has specified a buffer to employ. */
/* The buffer must be large enough to accommodate maximum
putback. */
assert(bufsize > JAS_STREAM_MAXPUTBACK);
stream->bufbase_ = JAS_CAST(uchar *, buf);
stream->bufsize_ = bufsize - JAS_STREAM_MAXPUTBACK;
}
} else {
/* The unbuffered mode is being employed. */
/* A buffer should not have been supplied by the caller. */
assert(!buf);
/* Use a trivial one-character buffer. */
stream->bufbase_ = stream->tinybuf_;
stream->bufsize_ = 1;
}
stream->bufstart_ = &stream->bufbase_[JAS_STREAM_MAXPUTBACK];
stream->ptr_ = stream->bufstart_;
stream->cnt_ = 0;
stream->bufmode_ |= bufmode & JAS_STREAM_BUFMODEMASK;
}
/******************************************************************************\
* Buffer filling and flushing code.
\******************************************************************************/
int jas_stream_flush(jas_stream_t *stream)
{
if (stream->bufmode_ & JAS_STREAM_RDBUF) {
return 0;
}
return jas_stream_flushbuf(stream, EOF);
}
int jas_stream_fillbuf(jas_stream_t *stream, int getflag)
{
int c;
/* The stream must not be in an error or EOF state. */
if ((stream->flags_ & (JAS_STREAM_ERRMASK)) != 0) {
return EOF;
}
/* The stream must be open for reading. */
if ((stream->openmode_ & JAS_STREAM_READ) == 0) {
return EOF;
}
/* Make a half-hearted attempt to confirm that the buffer is not
currently being used for writing. This check is not intended
to be foolproof! */
assert((stream->bufmode_ & JAS_STREAM_WRBUF) == 0);
assert(stream->ptr_ - stream->bufstart_ <= stream->bufsize_);
/* Mark the buffer as being used for reading. */
stream->bufmode_ |= JAS_STREAM_RDBUF;
/* Read new data into the buffer. */
stream->ptr_ = stream->bufstart_;
if ((stream->cnt_ = (*stream->ops_->read_)(stream->obj_,
(char *) stream->bufstart_, stream->bufsize_)) <= 0) {
if (stream->cnt_ < 0) {
stream->flags_ |= JAS_STREAM_ERR;
} else {
stream->flags_ |= JAS_STREAM_EOF;
}
stream->cnt_ = 0;
return EOF;
}
assert(stream->cnt_ > 0);
/* Get or peek at the first character in the buffer. */
c = (getflag) ? jas_stream_getc2(stream) : (*stream->ptr_);
return c;
}
int jas_stream_flushbuf(jas_stream_t *stream, int c)
{
int len;
int n;
/* The stream should not be in an error or EOF state. */
if ((stream->flags_ & (JAS_STREAM_ERRMASK)) != 0) {
return EOF;
}
/* The stream must be open for writing. */
if ((stream->openmode_ & (JAS_STREAM_WRITE | JAS_STREAM_APPEND)) == 0) {
return EOF;
}
/* The buffer should not currently be in use for reading. */
assert(!(stream->bufmode_ & JAS_STREAM_RDBUF));
/* Note: Do not use the quantity stream->cnt to determine the number
of characters in the buffer! Depending on how this function was
called, the stream->cnt value may be "off-by-one". */
len = stream->ptr_ - stream->bufstart_;
if (len > 0) {
n = (*stream->ops_->write_)(stream->obj_, (char *)
stream->bufstart_, len);
if (n != len) {
stream->flags_ |= JAS_STREAM_ERR;
return EOF;
}
}
stream->cnt_ = stream->bufsize_;
stream->ptr_ = stream->bufstart_;
stream->bufmode_ |= JAS_STREAM_WRBUF;
if (c != EOF) {
assert(stream->cnt_ > 0);
return jas_stream_putc2(stream, c);
}
return 0;
}
/******************************************************************************\
* Miscellaneous code.
\******************************************************************************/
static int jas_strtoopenmode(const char *s)
{
int openmode = 0;
while (*s != '\0') {
switch (*s) {
case 'r':
openmode |= JAS_STREAM_READ;
break;
case 'w':
openmode |= JAS_STREAM_WRITE | JAS_STREAM_CREATE;
break;
case 'b':
openmode |= JAS_STREAM_BINARY;
break;
case 'a':
openmode |= JAS_STREAM_APPEND;
break;
case '+':
openmode |= JAS_STREAM_READ | JAS_STREAM_WRITE;
break;
default:
break;
}
++s;
}
return openmode;
}
int jas_stream_copy(jas_stream_t *out, jas_stream_t *in, int n)
{
int all;
int c;
int m;
all = (n < 0) ? 1 : 0;
m = n;
while (all || m > 0) {
if ((c = jas_stream_getc_macro(in)) == EOF) {
/* The next character of input could not be read. */
/* Return with an error if an I/O error occured
(not including EOF) or if an explicit copy count
was specified. */
return (!all || jas_stream_error(in)) ? (-1) : 0;
}
if (jas_stream_putc_macro(out, c) == EOF) {
return -1;
}
--m;
}
return 0;
}
long jas_stream_setrwcount(jas_stream_t *stream, long rwcnt)
{
int old;
old = stream->rwcnt_;
stream->rwcnt_ = rwcnt;
return old;
}
int jas_stream_display(jas_stream_t *stream, FILE *fp, int n)
{
unsigned char buf[16];
int i;
int j;
int m;
int c;
int display;
int cnt;
cnt = n - (n % 16);
display = 1;
for (i = 0; i < n; i += 16) {
if (n > 16 && i > 0) {
display = (i >= cnt) ? 1 : 0;
}
if (display) {
fprintf(fp, "%08x:", i);
}
m = JAS_MIN(n - i, 16);
for (j = 0; j < m; ++j) {
if ((c = jas_stream_getc(stream)) == EOF) {
abort();
return -1;
}
buf[j] = c;
}
if (display) {
for (j = 0; j < m; ++j) {
fprintf(fp, " %02x", buf[j]);
}
fputc(' ', fp);
for (; j < 16; ++j) {
fprintf(fp, " ");
}
for (j = 0; j < m; ++j) {
if (isprint(buf[j])) {
fputc(buf[j], fp);
} else {
fputc(' ', fp);
}
}
fprintf(fp, "\n");
}
}
return 0;
}
long jas_stream_length(jas_stream_t *stream)
{
long oldpos;
long pos;
if ((oldpos = jas_stream_tell(stream)) < 0) {
return -1;
}
if (jas_stream_seek(stream, 0, SEEK_END) < 0) {
return -1;
}
if ((pos = jas_stream_tell(stream)) < 0) {
return -1;
}
if (jas_stream_seek(stream, oldpos, SEEK_SET) < 0) {
return -1;
}
return pos;
}
/******************************************************************************\
* Memory stream object.
\******************************************************************************/
static int mem_read(jas_stream_obj_t *obj, char *buf, int cnt)
{
int n;
jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj;
n = m->len_ - m->pos_;
cnt = JAS_MIN(n, cnt);
memcpy(buf, &m->buf_[m->pos_], cnt);
m->pos_ += cnt;
return cnt;
}
static int mem_resize(jas_stream_memobj_t *m, int bufsize)
{
unsigned char *buf;
assert(m->buf_);
if (!(buf = jas_realloc(m->buf_, bufsize * sizeof(unsigned char)))) {
return -1;
}
m->buf_ = buf;
m->bufsize_ = bufsize;
return 0;
}
static int mem_write(jas_stream_obj_t *obj, char *buf, int cnt)
{
int n;
int ret;
jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj;
long newbufsize;
long newpos;
newpos = m->pos_ + cnt;
if (newpos > m->bufsize_ && m->growable_) {
newbufsize = m->bufsize_;
while (newbufsize < newpos) {
newbufsize <<= 1;
assert(newbufsize >= 0);
}
if (mem_resize(m, newbufsize)) {
return -1;
}
}
if (m->pos_ > m->len_) {
/* The current position is beyond the end of the file, so
pad the file to the current position with zeros. */
n = JAS_MIN(m->pos_, m->bufsize_) - m->len_;
if (n > 0) {
memset(&m->buf_[m->len_], 0, n);
m->len_ += n;
}
if (m->pos_ != m->len_) {
/* The buffer is not big enough. */
return 0;
}
}
n = m->bufsize_ - m->pos_;
ret = JAS_MIN(n, cnt);
if (ret > 0) {
memcpy(&m->buf_[m->pos_], buf, ret);
m->pos_ += ret;
}
if (m->pos_ > m->len_) {
m->len_ = m->pos_;
}
assert(ret == cnt);
return ret;
}
static long mem_seek(jas_stream_obj_t *obj, long offset, int origin)
{
jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj;
long newpos;
switch (origin) {
case SEEK_SET:
newpos = offset;
break;
case SEEK_END:
newpos = m->len_ - offset;
break;
case SEEK_CUR:
newpos = m->pos_ + offset;
break;
default:
abort();
break;
}
if (newpos < 0) {
return -1;
}
m->pos_ = newpos;
return m->pos_;
}
static int mem_close(jas_stream_obj_t *obj)
{
jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj;
if (m->myalloc_ && m->buf_) {
jas_free(m->buf_);
m->buf_ = 0;
}
jas_free(obj);
return 0;
}
/******************************************************************************\
* File stream object.
\******************************************************************************/
static int file_read(jas_stream_obj_t *obj, char *buf, int cnt)
{
jas_stream_fileobj_t *fileobj = JAS_CAST(jas_stream_fileobj_t *, obj);
return read(fileobj->fd, buf, cnt);
}
static int file_write(jas_stream_obj_t *obj, char *buf, int cnt)
{
jas_stream_fileobj_t *fileobj = JAS_CAST(jas_stream_fileobj_t *, obj);
return write(fileobj->fd, buf, cnt);
}
static long file_seek(jas_stream_obj_t *obj, long offset, int origin)
{
jas_stream_fileobj_t *fileobj = JAS_CAST(jas_stream_fileobj_t *, obj);
return lseek(fileobj->fd, offset, origin);
}
static int file_close(jas_stream_obj_t *obj)
{
jas_stream_fileobj_t *fileobj = JAS_CAST(jas_stream_fileobj_t *, obj);
int ret;
ret = close(fileobj->fd);
if (fileobj->flags & JAS_STREAM_FILEOBJ_DELONCLOSE) {
unlink(fileobj->pathname);
}
jas_free(fileobj);
return ret;
}
/******************************************************************************\
* Stdio file stream object.
\******************************************************************************/
static int sfile_read(jas_stream_obj_t *obj, char *buf, int cnt)
{
FILE *fp;
fp = JAS_CAST(FILE *, obj);
return fread(buf, 1, cnt, fp);
}
static int sfile_write(jas_stream_obj_t *obj, char *buf, int cnt)
{
FILE *fp;
fp = JAS_CAST(FILE *, obj);
return fwrite(buf, 1, cnt, fp);
}
static long sfile_seek(jas_stream_obj_t *obj, long offset, int origin)
{
FILE *fp;
fp = JAS_CAST(FILE *, obj);
return fseek(fp, offset, origin);
}
static int sfile_close(jas_stream_obj_t *obj)
{
FILE *fp;
fp = JAS_CAST(FILE *, obj);
return fclose(fp);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -