Annotation of embedaddon/php/ext/zlib/zlib_fopen_wrapper.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2012 The PHP Group |
! 6: +----------------------------------------------------------------------+
! 7: | This source file is subject to version 3.01 of the PHP license, |
! 8: | that is bundled with this package in the file LICENSE, and is |
! 9: | available through the world-wide-web at the following url: |
! 10: | http://www.php.net/license/3_01.txt |
! 11: | If you did not receive a copy of the PHP license and are unable to |
! 12: | obtain it through the world-wide-web, please send a note to |
! 13: | license@php.net so we can mail you a copy immediately. |
! 14: +----------------------------------------------------------------------+
! 15: | Author: Wez Furlong <wez@thebrainroom.com>, based on work by: |
! 16: | Hartmut Holzgraefe <hholzgra@php.net> |
! 17: +----------------------------------------------------------------------+
! 18: */
! 19:
! 20: /* $Id: zlib_fopen_wrapper.c 321634 2012-01-01 13:15:04Z felipe $ */
! 21:
! 22: #define _GNU_SOURCE
! 23:
! 24: #include "php.h"
! 25: #include "php_zlib.h"
! 26: #include "fopen_wrappers.h"
! 27:
! 28: struct php_gz_stream_data_t {
! 29: gzFile gz_file;
! 30: php_stream *stream;
! 31: };
! 32:
! 33: static size_t php_gziop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
! 34: {
! 35: struct php_gz_stream_data_t *self = (struct php_gz_stream_data_t *) stream->abstract;
! 36: int read;
! 37:
! 38: read = gzread(self->gz_file, buf, count);
! 39:
! 40: if (gzeof(self->gz_file)) {
! 41: stream->eof = 1;
! 42: }
! 43:
! 44: return (read < 0) ? 0 : read;
! 45: }
! 46:
! 47: static size_t php_gziop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
! 48: {
! 49: struct php_gz_stream_data_t *self = (struct php_gz_stream_data_t *) stream->abstract;
! 50: int wrote;
! 51:
! 52: wrote = gzwrite(self->gz_file, (char *) buf, count);
! 53:
! 54: return (wrote < 0) ? 0 : wrote;
! 55: }
! 56:
! 57: static int php_gziop_seek(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC)
! 58: {
! 59: struct php_gz_stream_data_t *self = (struct php_gz_stream_data_t *) stream->abstract;
! 60:
! 61: assert(self != NULL);
! 62:
! 63: if (whence == SEEK_END) {
! 64: php_error_docref(NULL TSRMLS_CC, E_WARNING, "SEEK_END is not supported");
! 65: return -1;
! 66: }
! 67: *newoffs = gzseek(self->gz_file, offset, whence);
! 68:
! 69: return (*newoffs < 0) ? -1 : 0;
! 70: }
! 71:
! 72: static int php_gziop_close(php_stream *stream, int close_handle TSRMLS_DC)
! 73: {
! 74: struct php_gz_stream_data_t *self = (struct php_gz_stream_data_t *) stream->abstract;
! 75: int ret = EOF;
! 76:
! 77: if (close_handle) {
! 78: if (self->gz_file) {
! 79: ret = gzclose(self->gz_file);
! 80: self->gz_file = NULL;
! 81: }
! 82: if (self->stream) {
! 83: php_stream_close(self->stream);
! 84: self->stream = NULL;
! 85: }
! 86: }
! 87: efree(self);
! 88:
! 89: return ret;
! 90: }
! 91:
! 92: static int php_gziop_flush(php_stream *stream TSRMLS_DC)
! 93: {
! 94: struct php_gz_stream_data_t *self = (struct php_gz_stream_data_t *) stream->abstract;
! 95:
! 96: return gzflush(self->gz_file, Z_SYNC_FLUSH);
! 97: }
! 98:
! 99: static php_stream_ops php_stream_gzio_ops = {
! 100: php_gziop_write, php_gziop_read,
! 101: php_gziop_close, php_gziop_flush,
! 102: "ZLIB",
! 103: php_gziop_seek,
! 104: NULL, /* cast */
! 105: NULL, /* stat */
! 106: NULL /* set_option */
! 107: };
! 108:
! 109: php_stream *php_stream_gzopen(php_stream_wrapper *wrapper, char *path, char *mode, int options,
! 110: char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)
! 111: {
! 112: struct php_gz_stream_data_t *self = {0};
! 113: php_stream *stream = NULL, *innerstream = NULL;
! 114:
! 115: /* sanity check the stream: it can be either read-only or write-only */
! 116: if (strchr(mode, '+')) {
! 117: if (options & REPORT_ERRORS) {
! 118: php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot open a zlib stream for reading and writing at the same time!");
! 119: }
! 120: return NULL;
! 121: }
! 122:
! 123: self = emalloc(sizeof(*self));
! 124:
! 125: if (strncasecmp("compress.zlib://", path, 16) == 0) {
! 126: path += 16;
! 127: } else if (strncasecmp("zlib:", path, 5) == 0) {
! 128: path += 5;
! 129: }
! 130:
! 131: innerstream = php_stream_open_wrapper_ex(path, mode, STREAM_MUST_SEEK | options | STREAM_WILL_CAST, opened_path, context);
! 132:
! 133: if (innerstream) {
! 134: int fd;
! 135:
! 136: if (SUCCESS == php_stream_cast(innerstream, PHP_STREAM_AS_FD, (void **) &fd, REPORT_ERRORS)) {
! 137: self->gz_file = gzdopen(dup(fd), mode);
! 138: self->stream = innerstream;
! 139: if (self->gz_file) {
! 140: stream = php_stream_alloc_rel(&php_stream_gzio_ops, self, 0, mode);
! 141: if (stream) {
! 142: stream->flags |= PHP_STREAM_FLAG_NO_BUFFER;
! 143: return stream;
! 144: }
! 145: gzclose(self->gz_file);
! 146: }
! 147: if (options & REPORT_ERRORS) {
! 148: php_error_docref(NULL TSRMLS_CC, E_WARNING, "gzopen failed");
! 149: }
! 150: } else if (innerstream) {
! 151: php_stream_close(innerstream);
! 152: }
! 153: }
! 154:
! 155: if (stream) {
! 156: php_stream_close(stream);
! 157: }
! 158:
! 159: if (self) {
! 160: efree(self);
! 161: }
! 162:
! 163: return NULL;
! 164: }
! 165:
! 166: static php_stream_wrapper_ops gzip_stream_wops = {
! 167: php_stream_gzopen,
! 168: NULL, /* close */
! 169: NULL, /* stat */
! 170: NULL, /* stat_url */
! 171: NULL, /* opendir */
! 172: "ZLIB",
! 173: NULL, /* unlink */
! 174: NULL, /* rename */
! 175: NULL, /* mkdir */
! 176: NULL /* rmdir */
! 177: };
! 178:
! 179: php_stream_wrapper php_stream_gzip_wrapper = {
! 180: &gzip_stream_wops,
! 181: NULL,
! 182: 0, /* is_url */
! 183: };
! 184:
! 185: /*
! 186: * Local variables:
! 187: * tab-width: 4
! 188: * c-basic-offset: 4
! 189: * End:
! 190: * vim600: noet sw=4 ts=4 fdm=marker
! 191: * vim<600: noet sw=4 ts=4
! 192: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>