Annotation of embedaddon/php/ext/zlib/zlib_fopen_wrapper.c, revision 1.1.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>