📄 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 + -