Back to index

php5  5.3.10
zlib_fopen_wrapper.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Author: Wez Furlong <wez@thebrainroom.com>, based on work by:        |
00016    |         Hartmut Holzgraefe <hholzgra@php.net>                        |
00017    +----------------------------------------------------------------------+
00018  */
00019 
00020 /* $Id: zlib_fopen_wrapper.c 321634 2012-01-01 13:15:04Z felipe $ */
00021 
00022 #define _GNU_SOURCE
00023 
00024 #include "php.h"
00025 #include "php_zlib.h"
00026 #include "fopen_wrappers.h"
00027 
00028 struct php_gz_stream_data_t {
00029        gzFile gz_file;
00030        php_stream *stream;
00031 };
00032 
00033 static size_t php_gziop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
00034 {
00035        struct php_gz_stream_data_t *self = (struct php_gz_stream_data_t *) stream->abstract;
00036        int read;
00037        
00038        read = gzread(self->gz_file, buf, count);
00039        
00040        if (gzeof(self->gz_file)) {
00041               stream->eof = 1;
00042        }
00043               
00044        return (read < 0) ? 0 : read;
00045 }
00046 
00047 static size_t php_gziop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
00048 {
00049        struct php_gz_stream_data_t *self = (struct php_gz_stream_data_t *) stream->abstract;
00050        int wrote;
00051 
00052        wrote = gzwrite(self->gz_file, (char *) buf, count);
00053 
00054        return (wrote < 0) ? 0 : wrote;
00055 }
00056 
00057 static int php_gziop_seek(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC)
00058 {
00059        struct php_gz_stream_data_t *self = (struct php_gz_stream_data_t *) stream->abstract;
00060 
00061        assert(self != NULL);
00062 
00063        if (whence == SEEK_END) {
00064               php_error_docref(NULL TSRMLS_CC, E_WARNING, "SEEK_END is not supported");
00065               return -1;
00066        }
00067        *newoffs = gzseek(self->gz_file, offset, whence);
00068 
00069        return (*newoffs < 0) ? -1 : 0;
00070 }
00071 
00072 static int php_gziop_close(php_stream *stream, int close_handle TSRMLS_DC)
00073 {
00074        struct php_gz_stream_data_t *self = (struct php_gz_stream_data_t *) stream->abstract;
00075        int ret = EOF;
00076        
00077        if (close_handle) {
00078               if (self->gz_file) {
00079                      ret = gzclose(self->gz_file);
00080                      self->gz_file = NULL;
00081               }
00082               if (self->stream) {
00083                      php_stream_close(self->stream);
00084                      self->stream = NULL;
00085               }
00086        }
00087        efree(self);
00088 
00089        return ret;
00090 }
00091 
00092 static int php_gziop_flush(php_stream *stream TSRMLS_DC)
00093 {
00094        struct php_gz_stream_data_t *self = (struct php_gz_stream_data_t *) stream->abstract;
00095 
00096        return gzflush(self->gz_file, Z_SYNC_FLUSH);
00097 }
00098 
00099 static php_stream_ops php_stream_gzio_ops = {
00100        php_gziop_write, php_gziop_read,
00101        php_gziop_close, php_gziop_flush,
00102        "ZLIB",
00103        php_gziop_seek, 
00104        NULL, /* cast */
00105        NULL, /* stat */
00106        NULL  /* set_option */
00107 };
00108 
00109 php_stream *php_stream_gzopen(php_stream_wrapper *wrapper, char *path, char *mode, int options, 
00110                                                    char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)
00111 {
00112        struct php_gz_stream_data_t *self = {0};
00113        php_stream *stream = NULL, *innerstream = NULL;
00114 
00115        /* sanity check the stream: it can be either read-only or write-only */
00116        if (strchr(mode, '+')) {
00117               if (options & REPORT_ERRORS) {
00118                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot open a zlib stream for reading and writing at the same time!");
00119               }
00120               return NULL;
00121        }
00122        
00123        self = emalloc(sizeof(*self));
00124 
00125        if (strncasecmp("compress.zlib://", path, 16) == 0) {
00126               path += 16;
00127        } else if (strncasecmp("zlib:", path, 5) == 0) {
00128               path += 5;
00129        }
00130        
00131        innerstream = php_stream_open_wrapper_ex(path, mode, STREAM_MUST_SEEK | options | STREAM_WILL_CAST, opened_path, context);
00132        
00133        if (innerstream) {
00134               int fd;
00135 
00136               if (SUCCESS == php_stream_cast(innerstream, PHP_STREAM_AS_FD, (void **) &fd, REPORT_ERRORS)) {
00137                      self->gz_file = gzdopen(dup(fd), mode);
00138                      self->stream = innerstream;
00139                      if (self->gz_file)   {
00140                             stream = php_stream_alloc_rel(&php_stream_gzio_ops, self, 0, mode);
00141                             if (stream) {
00142                                    stream->flags |= PHP_STREAM_FLAG_NO_BUFFER;
00143                                    return stream;
00144                             }
00145                             gzclose(self->gz_file);
00146                      }
00147                      if (options & REPORT_ERRORS) {
00148                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "gzopen failed");
00149                      }
00150               } else if (innerstream) {
00151                      php_stream_close(innerstream);
00152               }
00153        }
00154 
00155        if (stream) {
00156               php_stream_close(stream);
00157        }
00158        
00159        if (self) {
00160               efree(self);
00161        }
00162        
00163        return NULL;
00164 }
00165 
00166 static php_stream_wrapper_ops gzip_stream_wops = {
00167        php_stream_gzopen,
00168        NULL, /* close */
00169        NULL, /* stat */
00170        NULL, /* stat_url */
00171        NULL, /* opendir */
00172        "ZLIB",
00173        NULL, /* unlink */
00174        NULL, /* rename */
00175        NULL, /* mkdir */
00176        NULL  /* rmdir */
00177 };
00178 
00179 php_stream_wrapper php_stream_gzip_wrapper =     {
00180        &gzip_stream_wops,
00181        NULL,
00182        0, /* is_url */
00183 };
00184 
00185 /*
00186  * Local variables:
00187  * tab-width: 4
00188  * c-basic-offset: 4
00189  * End:
00190  * vim600: noet sw=4 ts=4 fdm=marker
00191  * vim<600: noet sw=4 ts=4
00192  */