jas_stream.c

来自「JPEG2000的压缩和解压程序 C语言实现的jasper源程序」· C语言 代码 · 共 1,203 行 · 第 1/3 页

C
1,203
字号
	}	/* A temporary file stream is always opened for both reading and	writing in binary mode. */	stream->openmode_ = JAS_STREAM_READ | JAS_STREAM_WRITE | JAS_STREAM_BINARY;	/* Allocate memory for the underlying temporary file object. */	if (!(obj = jas_malloc(sizeof(jas_stream_fileobj_t)))) {		jas_stream_destroy(stream);		return 0;	}	obj->fd = -1;	obj->flags = 0;	obj->pathname[0] = '\0';	stream->obj_ = obj;	/* Choose a file name. */	tmpnam(obj->pathname);	/* Open the underlying file. */	if ((obj->fd = open(obj->pathname, O_CREAT | O_EXCL | O_RDWR | O_TRUNC | O_BINARY,	  JAS_STREAM_PERMS)) < 0) {		jas_stream_destroy(stream);		return 0;	}	/* Unlink the file so that it will disappear if the program	terminates abnormally. */	/* Under UNIX, one can unlink an open file and continue to do I/O	on it.  Not all operating systems support this functionality, however.	For example, under Microsoft Windows the unlink operation will fail,	since the file is open. */	if (unlink(obj->pathname)) {		/* We will try unlinking the file again after it is closed. */		obj->flags |= JAS_STREAM_FILEOBJ_DELONCLOSE;	}	/* Use full buffering. */	jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0);	stream->ops_ = &jas_stream_fileops;	return stream;}jas_stream_t *jas_stream_fdopen(int fd, const char *mode){	jas_stream_t *stream;	jas_stream_fileobj_t *obj;	/* Allocate a stream object. */	if (!(stream = jas_stream_create())) {		return 0;	}	/* Parse the mode string. */	stream->openmode_ = jas_strtoopenmode(mode);#if defined(WIN32)	/* Argh!!!  Someone ought to banish text mode (i.e., O_TEXT) to the	  greatest depths of purgatory! */	/* Ensure that the file descriptor is in binary mode, if the caller	  has specified the binary mode flag.  Arguably, the caller ought to	  take care of this, but text mode is a ugly wart anyways, so we save	  the caller some grief by handling this within the stream library. */	/* This ugliness is mainly for the benefit of those who run the	  JasPer software under Windows from shells that insist on opening	  files in text mode.  For example, in the Cygwin environment,	  shells often open files in text mode when I/O redirection is	  used.  Grr... */	if (stream->openmode_ & JAS_STREAM_BINARY) {		setmode(fd, O_BINARY);	}#endif	/* Allocate space for the underlying file stream object. */	if (!(obj = jas_malloc(sizeof(jas_stream_fileobj_t)))) {		jas_stream_destroy(stream);		return 0;	}	obj->fd = fd;	obj->flags = 0;	obj->pathname[0] = '\0';	stream->obj_ = (void *) obj;	/* Do not close the underlying file descriptor when the stream is	closed. */	obj->flags |= JAS_STREAM_FILEOBJ_NOCLOSE;	/* By default, use full buffering for this type of stream. */	jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0);	/* Select the operations for a file stream object. */	stream->ops_ = &jas_stream_fileops;	return stream;}static void jas_stream_destroy(jas_stream_t *stream){	/* If the memory for the buffer was allocated with malloc, free	this memory. */	if ((stream->bufmode_ & JAS_STREAM_FREEBUF) && stream->bufbase_) {		jas_free(stream->bufbase_);		stream->bufbase_ = 0;	}	jas_free(stream);}int jas_stream_close(jas_stream_t *stream){	/* Flush buffer if necessary. */	jas_stream_flush(stream);	/* Close the underlying stream object. */	(*stream->ops_->close_)(stream->obj_);	jas_stream_destroy(stream);	return 0;}/******************************************************************************\* Code for reading and writing streams.\******************************************************************************/int jas_stream_getc_func(jas_stream_t *stream){	assert(stream->ptr_ - stream->bufbase_ <= stream->bufsize_ +	  JAS_STREAM_MAXPUTBACK);	return jas_stream_getc_macro(stream);}int jas_stream_putc_func(jas_stream_t *stream, int c){	assert(stream->ptr_ - stream->bufstart_ <= stream->bufsize_);	return jas_stream_putc_macro(stream, c);}int jas_stream_ungetc(jas_stream_t *stream, int c){	if (!stream->ptr_ || stream->ptr_ == stream->bufbase_) {		return -1;	}	/* Reset the EOF indicator (since we now have at least one character	  to read). */	stream->flags_ &= ~JAS_STREAM_EOF;	--stream->rwcnt_;	--stream->ptr_;	++stream->cnt_;	*stream->ptr_ = c;	return 0;}int jas_stream_read(jas_stream_t *stream, void *buf, int cnt){	int n;	int c;	char *bufptr;	bufptr = buf;	n = 0;	while (n < cnt) {		if ((c = jas_stream_getc(stream)) == EOF) {			return n;		}		*bufptr++ = c;		++n;	}	return n;}int jas_stream_write(jas_stream_t *stream, const void *buf, int cnt){	int n;	const char *bufptr;	bufptr = buf;	n = 0;	while (n < cnt) {		if (jas_stream_putc(stream, *bufptr) == EOF) {			return n;		}		++bufptr;		++n;	}	return n;}/* Note: This function uses a fixed size buffer.  Therefore, it cannot  handle invocations that will produce more output than can be held  by the buffer. */int jas_stream_printf(jas_stream_t *stream, const char *fmt, ...){	va_list ap;	char buf[4096];	int ret;	va_start(ap, fmt);	ret = vsprintf(buf, fmt, ap);	jas_stream_puts(stream, buf);	va_end(ap);	return ret;}int jas_stream_puts(jas_stream_t *stream, const char *s){	while (*s != '\0') {		if (jas_stream_putc_macro(stream, *s) == EOF) {			return -1;		}		++s;	}	return 0;}char *jas_stream_gets(jas_stream_t *stream, char *buf, int bufsize){	int c;	char *bufptr;	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);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?