Annotation of embedaddon/php/ext/zlib/zlib_fopen_wrapper.c, revision 1.1.1.3
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.3 ! misho 5: | Copyright (c) 1997-2013 The PHP Group |
1.1 misho 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:
1.1.1.2 misho 20: /* $Id$ */
1.1 misho 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:
1.1.1.2 misho 99: php_stream_ops php_stream_gzio_ops = {
1.1 misho 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: {
1.1.1.2 misho 112: struct php_gz_stream_data_t *self;
1.1 misho 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: if (strncasecmp("compress.zlib://", path, 16) == 0) {
124: path += 16;
125: } else if (strncasecmp("zlib:", path, 5) == 0) {
126: path += 5;
127: }
128:
129: innerstream = php_stream_open_wrapper_ex(path, mode, STREAM_MUST_SEEK | options | STREAM_WILL_CAST, opened_path, context);
130:
131: if (innerstream) {
132: int fd;
133:
134: if (SUCCESS == php_stream_cast(innerstream, PHP_STREAM_AS_FD, (void **) &fd, REPORT_ERRORS)) {
1.1.1.2 misho 135: self = emalloc(sizeof(*self));
1.1 misho 136: self->stream = innerstream;
1.1.1.2 misho 137: self->gz_file = gzdopen(dup(fd), mode);
138:
139: if (self->gz_file) {
1.1 misho 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: }
1.1.1.2 misho 145:
1.1 misho 146: gzclose(self->gz_file);
147: }
1.1.1.2 misho 148:
149: efree(self);
1.1 misho 150: if (options & REPORT_ERRORS) {
151: php_error_docref(NULL TSRMLS_CC, E_WARNING, "gzopen failed");
152: }
153: }
154:
1.1.1.2 misho 155: php_stream_close(innerstream);
1.1 misho 156: }
1.1.1.2 misho 157:
1.1 misho 158: return NULL;
159: }
160:
161: static php_stream_wrapper_ops gzip_stream_wops = {
162: php_stream_gzopen,
163: NULL, /* close */
164: NULL, /* stat */
165: NULL, /* stat_url */
166: NULL, /* opendir */
167: "ZLIB",
168: NULL, /* unlink */
169: NULL, /* rename */
170: NULL, /* mkdir */
171: NULL /* rmdir */
172: };
173:
174: php_stream_wrapper php_stream_gzip_wrapper = {
175: &gzip_stream_wops,
176: NULL,
177: 0, /* is_url */
178: };
179:
180: /*
181: * Local variables:
182: * tab-width: 4
183: * c-basic-offset: 4
184: * End:
185: * vim600: noet sw=4 ts=4 fdm=marker
186: * vim<600: noet sw=4 ts=4
187: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>