2002-03-16 20:11:06 +00:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-01-08 08:18:22 +00:00
| PHP Version 5 |
2002-03-16 20:11:06 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2007-01-01 09:36:18 +00:00
| Copyright ( c ) 1997 - 2007 The PHP Group |
2002-03-16 20:11:06 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 12:51:34 +00:00
| This source file is subject to version 3.01 of the PHP license , |
2002-03-16 20:11:06 +00:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-10 20:04:29 +00:00
| available through the world - wide - web at the following url : |
2006-01-01 12:51:34 +00:00
| http : //www.php.net/license/3_01.txt |
2002-03-16 20:11:06 +00:00
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ php . net so we can mail you a copy immediately . |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2003-02-19 08:40:19 +00:00
| Author : Marcus Boerger < helly @ php . net > |
2002-03-16 20:11:06 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2003-02-19 08:40:19 +00:00
/* $Id$ */
2002-03-16 20:11:06 +00:00
# define _GNU_SOURCE
# include "php.h"
2002-03-18 04:57:06 +00:00
2006-05-14 01:42:03 +00:00
PHPAPI int php_url_decode ( char * str , int len ) ;
PHPAPI unsigned char * php_base64_decode ( const unsigned char * str , int length , int * ret_length ) ;
2002-03-18 04:57:06 +00:00
/* Memory streams use a dynamic memory buffer to emulate a stream.
* You can use php_stream_memory_open to create a readonly stream
* from an existing memory buffer .
*/
/* Temp streams are streams that uses memory streams as long their
* size is less than a given memory amount . When a write operation
* exceeds that limit the content is written to a temporary file .
*/
2002-03-16 20:11:06 +00:00
/* {{{ ------- MEMORY stream implementation -------*/
typedef struct {
2002-03-17 23:50:31 +00:00
char * data ;
size_t fpos ;
size_t fsize ;
size_t smax ;
int mode ;
2006-01-05 22:03:07 +00:00
php_stream * * owner_ptr ;
2002-03-18 04:57:06 +00:00
} php_stream_memory_data ;
2002-03-16 20:11:06 +00:00
2002-03-19 19:15:40 +00:00
/* {{{ */
static size_t php_stream_memory_write ( php_stream * stream , const char * buf , size_t count TSRMLS_DC )
{
2006-05-13 17:58:58 +00:00
php_stream_memory_data * ms = ( php_stream_memory_data * ) stream - > abstract ;
2002-03-16 20:11:06 +00:00
assert ( ms ! = NULL ) ;
2002-03-17 23:50:31 +00:00
2002-03-18 04:57:06 +00:00
if ( ms - > mode & TEMP_STREAM_READONLY ) {
2002-03-17 23:50:31 +00:00
return 0 ;
}
2002-03-18 04:57:06 +00:00
if ( ms - > fpos + count > ms - > fsize ) {
2002-03-16 20:11:06 +00:00
char * tmp ;
2002-03-18 04:57:06 +00:00
if ( ! ms - > data ) {
tmp = emalloc ( ms - > fpos + count ) ;
2002-03-16 20:11:06 +00:00
} else {
2002-03-18 04:57:06 +00:00
tmp = erealloc ( ms - > data , ms - > fpos + count ) ;
2002-03-16 20:11:06 +00:00
}
2002-03-18 04:57:06 +00:00
if ( ! tmp ) {
2002-03-16 20:11:06 +00:00
count = ms - > fsize - ms - > fpos + 1 ;
} else {
ms - > data = tmp ;
ms - > fsize = ms - > fpos + count ;
}
}
2002-03-18 04:57:06 +00:00
if ( ! ms - > data )
count = 0 ;
if ( count ) {
2002-03-16 20:11:06 +00:00
assert ( buf ! = NULL ) ;
2002-03-18 04:57:06 +00:00
memcpy ( ms - > data + ms - > fpos , ( char * ) buf , count ) ;
2002-03-16 20:11:06 +00:00
ms - > fpos + = count ;
}
return count ;
2002-03-19 19:15:40 +00:00
}
/* }}} */
2002-03-16 20:11:06 +00:00
2002-03-19 19:15:40 +00:00
/* {{{ */
static size_t php_stream_memory_read ( php_stream * stream , char * buf , size_t count TSRMLS_DC )
2002-03-21 20:37:04 +00:00
{
2006-05-13 17:58:58 +00:00
php_stream_memory_data * ms = ( php_stream_memory_data * ) stream - > abstract ;
2002-03-16 20:11:06 +00:00
assert ( ms ! = NULL ) ;
2006-05-23 22:31:25 +00:00
if ( ms - > fpos + count > = ms - > fsize ) {
2002-03-16 20:11:06 +00:00
count = ms - > fsize - ms - > fpos ;
2006-05-23 22:31:25 +00:00
stream - > eof = 1 ;
2002-03-16 20:11:06 +00:00
}
2002-03-18 04:57:06 +00:00
if ( count ) {
assert ( ms - > data ! = NULL ) ;
2002-03-16 20:11:06 +00:00
assert ( buf ! = NULL ) ;
2002-03-18 04:57:06 +00:00
memcpy ( buf , ms - > data + ms - > fpos , count ) ;
2002-03-16 20:11:06 +00:00
ms - > fpos + = count ;
}
return count ;
2002-03-19 19:15:40 +00:00
}
/* }}} */
2002-03-16 20:11:06 +00:00
2002-03-19 19:15:40 +00:00
/* {{{ */
static int php_stream_memory_close ( php_stream * stream , int close_handle TSRMLS_DC )
2002-03-21 20:37:04 +00:00
{
2006-05-13 17:58:58 +00:00
php_stream_memory_data * ms = ( php_stream_memory_data * ) stream - > abstract ;
2002-03-16 20:11:06 +00:00
assert ( ms ! = NULL ) ;
2002-03-17 23:50:31 +00:00
2002-04-02 16:46:33 +00:00
if ( ms - > data & & close_handle & & ms - > mode ! = TEMP_STREAM_READONLY ) {
2002-03-16 20:11:06 +00:00
efree ( ms - > data ) ;
}
2006-01-05 22:03:07 +00:00
if ( ms - > owner_ptr ) {
* ms - > owner_ptr = NULL ;
}
2002-03-21 20:37:04 +00:00
efree ( ms ) ;
2002-03-17 23:50:31 +00:00
return 0 ;
2002-03-19 19:15:40 +00:00
}
/* }}} */
2002-03-16 20:11:06 +00:00
2002-03-19 19:15:40 +00:00
/* {{{ */
2002-10-20 23:05:34 +00:00
static int php_stream_memory_flush ( php_stream * stream TSRMLS_DC )
{
2002-03-18 04:57:06 +00:00
/* nothing to do here */
2002-03-16 20:11:06 +00:00
return 0 ;
2002-03-19 19:15:40 +00:00
}
/* }}} */
2002-03-16 20:11:06 +00:00
2002-03-19 19:15:40 +00:00
/* {{{ */
2002-09-23 01:47:04 +00:00
static int php_stream_memory_seek ( php_stream * stream , off_t offset , int whence , off_t * newoffs TSRMLS_DC )
2002-03-19 19:15:40 +00:00
{
2006-05-13 17:58:58 +00:00
php_stream_memory_data * ms = ( php_stream_memory_data * ) stream - > abstract ;
2002-03-16 20:11:06 +00:00
assert ( ms ! = NULL ) ;
2002-03-17 23:50:31 +00:00
2002-03-18 04:57:06 +00:00
switch ( whence ) {
2002-03-16 20:11:06 +00:00
case SEEK_CUR :
2002-03-18 04:57:06 +00:00
if ( offset < 0 ) {
2002-03-20 19:13:03 +00:00
if ( ms - > fpos < ( size_t ) ( - offset ) ) {
2002-03-16 20:11:06 +00:00
ms - > fpos = 0 ;
2006-01-05 22:03:07 +00:00
* newoffs = - 1 ;
return - 1 ;
2002-03-16 20:11:06 +00:00
} else {
ms - > fpos = ms - > fpos + offset ;
2006-01-05 22:03:07 +00:00
* newoffs = ms - > fpos ;
2006-05-23 22:31:25 +00:00
stream - > eof = 0 ;
2006-01-05 22:03:07 +00:00
return 0 ;
2002-03-16 20:11:06 +00:00
}
} else {
2006-03-18 19:57:00 +00:00
if ( ms - > fpos + ( size_t ) ( offset ) > ms - > fsize ) {
2002-03-16 20:11:06 +00:00
ms - > fpos = ms - > fsize ;
2006-01-05 22:03:07 +00:00
* newoffs = - 1 ;
return - 1 ;
2002-03-16 20:11:06 +00:00
} else {
ms - > fpos = ms - > fpos + offset ;
2006-01-05 22:03:07 +00:00
* newoffs = ms - > fpos ;
2006-05-23 22:31:25 +00:00
stream - > eof = 0 ;
2006-01-05 22:03:07 +00:00
return 0 ;
2002-03-16 20:11:06 +00:00
}
}
case SEEK_SET :
2002-03-20 19:13:03 +00:00
if ( ms - > fsize < ( size_t ) ( offset ) ) {
2002-03-16 20:11:06 +00:00
ms - > fpos = ms - > fsize ;
2006-01-05 22:03:07 +00:00
* newoffs = - 1 ;
return - 1 ;
2002-03-16 20:11:06 +00:00
} else {
ms - > fpos = offset ;
2006-01-05 22:03:07 +00:00
* newoffs = ms - > fpos ;
2006-05-23 22:31:25 +00:00
stream - > eof = 0 ;
2006-01-05 22:03:07 +00:00
return 0 ;
2002-03-16 20:11:06 +00:00
}
case SEEK_END :
2002-03-18 04:57:06 +00:00
if ( offset > 0 ) {
2002-03-16 20:11:06 +00:00
ms - > fpos = ms - > fsize ;
2006-01-05 22:03:07 +00:00
* newoffs = - 1 ;
return - 1 ;
} else if ( ms - > fsize < ( size_t ) ( - offset ) ) {
2002-03-16 20:11:06 +00:00
ms - > fpos = 0 ;
2006-01-05 22:03:07 +00:00
* newoffs = - 1 ;
return - 1 ;
2002-03-16 20:11:06 +00:00
} else {
ms - > fpos = ms - > fsize + offset ;
2006-01-05 22:03:07 +00:00
* newoffs = ms - > fpos ;
2006-05-23 22:31:25 +00:00
stream - > eof = 0 ;
2006-01-05 22:03:07 +00:00
return 0 ;
2002-03-16 20:11:06 +00:00
}
default :
2006-01-05 22:03:07 +00:00
* newoffs = ms - > fpos ;
return - 1 ;
2002-03-17 23:50:31 +00:00
}
2002-03-19 19:15:40 +00:00
}
/* }}} */
2002-03-17 23:50:31 +00:00
2002-03-19 19:15:40 +00:00
/* {{{ */
static int php_stream_memory_cast ( php_stream * stream , int castas , void * * ret TSRMLS_DC )
2002-03-21 20:37:04 +00:00
{
2002-03-17 23:50:31 +00:00
return FAILURE ;
2002-03-19 19:15:40 +00:00
}
/* }}} */
2006-05-13 17:58:58 +00:00
static int php_stream_memory_stat ( php_stream * stream , php_stream_statbuf * ssb TSRMLS_DC ) /* { { { */
{
time_t timestamp = 0 ;
php_stream_memory_data * ms = ( php_stream_memory_data * ) stream - > abstract ;
assert ( ms ! = NULL ) ;
memset ( ssb , 0 , sizeof ( php_stream_statbuf ) ) ;
/* read-only across the board */
ssb - > sb . st_mode = ms - > mode & TEMP_STREAM_READONLY ? 0444 : 0666 ;
ssb - > sb . st_size = ms - > fsize ;
ssb - > sb . st_mode | = S_IFREG ; /* regular file */
# ifdef NETWARE
ssb - > sb . st_mtime . tv_sec = timestamp ;
ssb - > sb . st_atime . tv_sec = timestamp ;
ssb - > sb . st_ctime . tv_sec = timestamp ;
# else
ssb - > sb . st_mtime = timestamp ;
ssb - > sb . st_atime = timestamp ;
ssb - > sb . st_ctime = timestamp ;
# endif
ssb - > sb . st_nlink = 1 ;
ssb - > sb . st_rdev = - 1 ;
/* this is only for APC, so use /dev/null device - no chance of conflict there! */
ssb - > sb . st_dev = 0xC ;
/* generate unique inode number for alias/filename, so no phars will conflict */
ssb - > sb . st_ino = 0 ;
# ifndef PHP_WIN32
ssb - > sb . st_blksize = - 1 ;
ssb - > sb . st_blocks = - 1 ;
# endif
return 0 ;
}
/* }}} */
2002-03-16 20:11:06 +00:00
php_stream_ops php_stream_memory_ops = {
2002-03-17 23:50:31 +00:00
php_stream_memory_write , php_stream_memory_read ,
php_stream_memory_close , php_stream_memory_flush ,
2002-03-28 00:49:00 +00:00
" MEMORY " ,
2002-03-17 23:50:31 +00:00
php_stream_memory_seek ,
php_stream_memory_cast ,
2006-05-13 17:58:58 +00:00
php_stream_memory_stat ,
2002-09-23 01:47:04 +00:00
NULL /* set_option */
2002-03-16 20:11:06 +00:00
} ;
2002-03-19 19:15:40 +00:00
/* {{{ */
PHPAPI php_stream * _php_stream_memory_create ( int mode STREAMS_DC TSRMLS_DC )
{
2002-03-18 04:57:06 +00:00
php_stream_memory_data * self ;
2002-09-23 13:22:10 +00:00
php_stream * stream ;
2002-03-16 20:11:06 +00:00
self = emalloc ( sizeof ( * self ) ) ;
self - > data = NULL ;
self - > fpos = 0 ;
self - > fsize = 0 ;
2006-05-13 17:58:58 +00:00
self - > smax = ~ 0u ;
2002-03-17 23:50:31 +00:00
self - > mode = mode ;
2006-01-05 22:03:07 +00:00
self - > owner_ptr = NULL ;
2002-09-23 13:22:10 +00:00
2005-12-14 00:06:09 +00:00
stream = php_stream_alloc ( & php_stream_memory_ops , self , 0 , mode & TEMP_STREAM_READONLY ? " r+b " : " w+b " ) ;
2002-09-23 13:22:10 +00:00
stream - > flags | = PHP_STREAM_FLAG_NO_BUFFER ;
return stream ;
2002-03-19 19:15:40 +00:00
}
/* }}} */
2002-03-17 23:50:31 +00:00
2002-03-19 19:15:40 +00:00
/* {{{ */
PHPAPI php_stream * _php_stream_memory_open ( int mode , char * buf , size_t length STREAMS_DC TSRMLS_DC )
2002-10-20 23:05:34 +00:00
{
php_stream * stream ;
2002-03-18 04:57:06 +00:00
php_stream_memory_data * ms ;
2002-03-17 23:50:31 +00:00
2002-04-02 16:46:33 +00:00
if ( ( stream = php_stream_memory_create_rel ( mode ) ) ! = NULL ) {
2006-05-13 17:58:58 +00:00
ms = ( php_stream_memory_data * ) stream - > abstract ;
2002-04-02 16:46:33 +00:00
2005-02-06 21:41:36 +00:00
if ( mode = = TEMP_STREAM_READONLY | | mode = = TEMP_STREAM_TAKE_BUFFER ) {
2002-04-02 16:46:33 +00:00
/* use the buffer directly */
ms - > data = buf ;
ms - > fsize = length ;
} else {
if ( length ) {
assert ( buf ! = NULL ) ;
php_stream_write ( stream , buf , length ) ;
}
}
2002-03-17 23:50:31 +00:00
}
return stream ;
2002-03-19 19:15:40 +00:00
}
/* }}} */
2002-03-17 23:50:31 +00:00
2002-03-19 19:15:40 +00:00
/* {{{ */
PHPAPI char * _php_stream_memory_get_buffer ( php_stream * stream , size_t * length STREAMS_DC TSRMLS_DC )
2002-03-21 20:37:04 +00:00
{
2006-05-13 17:58:58 +00:00
php_stream_memory_data * ms = ( php_stream_memory_data * ) stream - > abstract ;
2002-03-17 23:50:31 +00:00
assert ( ms ! = NULL ) ;
assert ( length ! = 0 ) ;
* length = ms - > fsize ;
return ms - > data ;
2002-03-19 19:15:40 +00:00
}
2002-03-18 04:57:06 +00:00
/* }}} */
2002-03-19 23:29:37 +00:00
/* }}} */
2002-03-19 19:15:40 +00:00
2002-03-17 23:50:31 +00:00
/* {{{ ------- TEMP stream implementation -------*/
2002-03-18 04:57:06 +00:00
typedef struct {
php_stream * innerstream ;
size_t smax ;
int mode ;
2006-05-13 17:58:58 +00:00
zval * meta ;
2002-03-18 04:57:06 +00:00
} php_stream_temp_data ;
2002-03-17 23:50:31 +00:00
2002-03-19 19:15:40 +00:00
/* {{{ */
static size_t php_stream_temp_write ( php_stream * stream , const char * buf , size_t count TSRMLS_DC )
2002-03-21 20:37:04 +00:00
{
2006-05-13 17:58:58 +00:00
php_stream_temp_data * ts = ( php_stream_temp_data * ) stream - > abstract ;
2002-03-18 04:57:06 +00:00
assert ( ts ! = NULL ) ;
2006-01-05 22:03:07 +00:00
if ( ! ts - > innerstream ) {
return - 1 ;
}
2002-03-18 04:57:06 +00:00
if ( php_stream_is ( ts - > innerstream , PHP_STREAM_IS_MEMORY ) ) {
size_t memsize ;
2002-03-18 11:18:07 +00:00
char * membuf = php_stream_memory_get_buffer ( ts - > innerstream , & memsize ) ;
2002-03-18 04:57:06 +00:00
if ( memsize + count > = ts - > smax ) {
php_stream * file = php_stream_fopen_tmpfile ( ) ;
php_stream_write ( file , membuf , memsize ) ;
2002-03-21 12:55:37 +00:00
php_stream_close ( ts - > innerstream ) ;
2002-03-18 04:57:06 +00:00
ts - > innerstream = file ;
2002-03-17 23:50:31 +00:00
}
}
2002-03-18 04:57:06 +00:00
return php_stream_write ( ts - > innerstream , buf , count ) ;
2002-03-19 19:15:40 +00:00
}
/* }}} */
2002-03-17 23:50:31 +00:00
2002-03-19 19:15:40 +00:00
/* {{{ */
static size_t php_stream_temp_read ( php_stream * stream , char * buf , size_t count TSRMLS_DC )
2002-03-21 20:37:04 +00:00
{
2006-05-13 17:58:58 +00:00
php_stream_temp_data * ts = ( php_stream_temp_data * ) stream - > abstract ;
2005-10-07 07:38:59 +00:00
size_t got ;
2002-03-17 23:50:31 +00:00
2002-03-18 04:57:06 +00:00
assert ( ts ! = NULL ) ;
2002-03-17 23:50:31 +00:00
2006-01-05 22:03:07 +00:00
if ( ! ts - > innerstream ) {
return - 1 ;
}
2005-10-07 07:38:59 +00:00
got = php_stream_read ( ts - > innerstream , buf , count ) ;
2005-10-06 21:31:25 +00:00
2006-05-23 22:31:25 +00:00
stream - > eof = ts - > innerstream - > eof ;
2005-10-06 21:31:25 +00:00
return got ;
2002-03-19 19:15:40 +00:00
}
/* }}} */
2002-03-17 23:50:31 +00:00
2002-03-19 19:15:40 +00:00
/* {{{ */
static int php_stream_temp_close ( php_stream * stream , int close_handle TSRMLS_DC )
{
2006-05-13 17:58:58 +00:00
php_stream_temp_data * ts = ( php_stream_temp_data * ) stream - > abstract ;
2002-03-19 23:29:37 +00:00
int ret ;
2002-03-17 23:50:31 +00:00
2002-03-18 04:57:06 +00:00
assert ( ts ! = NULL ) ;
2002-03-17 23:50:31 +00:00
2006-01-05 22:03:07 +00:00
if ( ts - > innerstream ) {
ret = php_stream_free ( ts - > innerstream , PHP_STREAM_FREE_CLOSE | ( close_handle ? 0 : PHP_STREAM_FREE_PRESERVE_HANDLE ) ) ;
} else {
ret = 0 ;
}
2006-05-13 17:58:58 +00:00
if ( ts - > meta ) {
zval_ptr_dtor ( & ts - > meta ) ;
}
2002-03-19 23:29:37 +00:00
efree ( ts ) ;
2002-03-21 20:37:04 +00:00
2002-03-19 23:29:37 +00:00
return ret ;
2002-03-19 19:15:40 +00:00
}
/* }}} */
2002-03-17 23:50:31 +00:00
2002-03-19 19:15:40 +00:00
/* {{{ */
static int php_stream_temp_flush ( php_stream * stream TSRMLS_DC )
2002-03-21 20:37:04 +00:00
{
2006-05-13 17:58:58 +00:00
php_stream_temp_data * ts = ( php_stream_temp_data * ) stream - > abstract ;
2002-03-18 04:57:06 +00:00
assert ( ts ! = NULL ) ;
2002-03-17 23:50:31 +00:00
2006-01-05 22:03:07 +00:00
return ts - > innerstream ? php_stream_flush ( ts - > innerstream ) : - 1 ;
2002-03-19 19:15:40 +00:00
}
/* }}} */
2002-03-17 23:50:31 +00:00
2002-03-19 19:15:40 +00:00
/* {{{ */
2002-09-23 01:47:04 +00:00
static int php_stream_temp_seek ( php_stream * stream , off_t offset , int whence , off_t * newoffs TSRMLS_DC )
2002-03-21 20:37:04 +00:00
{
2006-05-13 17:58:58 +00:00
php_stream_temp_data * ts = ( php_stream_temp_data * ) stream - > abstract ;
2002-09-23 01:47:04 +00:00
int ret ;
2002-03-17 23:50:31 +00:00
2002-03-18 04:57:06 +00:00
assert ( ts ! = NULL ) ;
2002-03-17 23:50:31 +00:00
2006-01-05 22:03:07 +00:00
if ( ! ts - > innerstream ) {
* newoffs = - 1 ;
return - 1 ;
}
2002-09-23 01:47:04 +00:00
ret = php_stream_seek ( ts - > innerstream , offset , whence ) ;
* newoffs = php_stream_tell ( ts - > innerstream ) ;
2006-05-23 22:31:25 +00:00
stream - > eof = ts - > innerstream - > eof ;
2002-09-23 01:47:04 +00:00
return ret ;
2002-03-19 19:15:40 +00:00
}
/* }}} */
2002-03-17 23:50:31 +00:00
2002-03-19 19:15:40 +00:00
/* {{{ */
static int php_stream_temp_cast ( php_stream * stream , int castas , void * * ret TSRMLS_DC )
2002-03-21 20:37:04 +00:00
{
2006-05-13 17:58:58 +00:00
php_stream_temp_data * ts = ( php_stream_temp_data * ) stream - > abstract ;
2002-03-19 23:29:37 +00:00
php_stream * file ;
size_t memsize ;
char * membuf ;
off_t pos ;
2002-03-17 23:50:31 +00:00
2002-03-18 04:57:06 +00:00
assert ( ts ! = NULL ) ;
2002-03-17 23:50:31 +00:00
2006-01-05 22:03:07 +00:00
if ( ! ts - > innerstream ) {
return FAILURE ;
}
2002-03-19 23:29:37 +00:00
if ( php_stream_is ( ts - > innerstream , PHP_STREAM_IS_STDIO ) ) {
return php_stream_cast ( ts - > innerstream , castas , ret , 0 ) ;
}
/* we are still using a memory based backing. If they are if we can be
* a FILE * , say yes because we can perform the conversion .
* If they actually want to perform the conversion , we need to switch
* the memory stream to a tmpfile stream */
if ( ret = = NULL & & castas = = PHP_STREAM_AS_STDIO ) {
return SUCCESS ;
}
/* say "no" to other stream forms */
if ( ret = = NULL ) {
return FAILURE ;
}
2002-03-21 20:37:04 +00:00
2002-03-19 23:29:37 +00:00
/* perform the conversion and then pass the request on to the innerstream */
membuf = php_stream_memory_get_buffer ( ts - > innerstream , & memsize ) ;
file = php_stream_fopen_tmpfile ( ) ;
php_stream_write ( file , membuf , memsize ) ;
pos = php_stream_tell ( ts - > innerstream ) ;
2002-03-21 20:37:04 +00:00
2002-03-19 23:29:37 +00:00
php_stream_close ( ts - > innerstream ) ;
ts - > innerstream = file ;
php_stream_seek ( ts - > innerstream , pos , SEEK_SET ) ;
2002-03-21 20:37:04 +00:00
2002-03-19 23:29:37 +00:00
return php_stream_cast ( ts - > innerstream , castas , ret , 1 ) ;
2002-03-19 19:15:40 +00:00
}
/* }}} */
2002-03-17 23:50:31 +00:00
2006-05-13 17:58:58 +00:00
static int php_stream_temp_stat ( php_stream * stream , php_stream_statbuf * ssb TSRMLS_DC ) /* { { { */
{
php_stream_temp_data * ts = ( php_stream_temp_data * ) stream - > abstract ;
if ( ! ts | | ! ts - > innerstream ) {
return - 1 ;
}
return php_stream_stat ( ts - > innerstream , ssb ) ;
}
/* }}} */
static int php_stream_temp_set_option ( php_stream * stream , int option , int value , void * ptrparam TSRMLS_DC ) /* { { { */
{
php_stream_temp_data * ts = ( php_stream_temp_data * ) stream - > abstract ;
switch ( option ) {
case PHP_STREAM_OPTION_META_DATA_API :
if ( ts - > meta ) {
zend_hash_copy ( Z_ARRVAL_P ( ( zval * ) ptrparam ) , Z_ARRVAL_P ( ts - > meta ) , ( copy_ctor_func_t ) zval_add_ref , NULL , sizeof ( zval * ) ) ;
}
return PHP_STREAM_OPTION_RETURN_OK ;
default :
return PHP_STREAM_OPTION_RETURN_NOTIMPL ;
}
}
/* }}} */
2002-03-17 23:50:31 +00:00
php_stream_ops php_stream_temp_ops = {
php_stream_temp_write , php_stream_temp_read ,
php_stream_temp_close , php_stream_temp_flush ,
2002-03-28 00:49:00 +00:00
" TEMP " ,
2002-03-17 23:50:31 +00:00
php_stream_temp_seek ,
php_stream_temp_cast ,
2006-05-13 17:58:58 +00:00
php_stream_temp_stat ,
php_stream_temp_set_option
2002-03-17 23:50:31 +00:00
} ;
2003-03-01 15:20:42 +00:00
/* }}} */
2002-03-19 19:15:40 +00:00
2003-03-01 15:20:42 +00:00
/* {{{ _php_stream_temp_create */
2002-03-19 19:15:40 +00:00
PHPAPI php_stream * _php_stream_temp_create ( int mode , size_t max_memory_usage STREAMS_DC TSRMLS_DC )
2002-03-21 20:37:04 +00:00
{
2002-03-17 23:50:31 +00:00
php_stream_temp_data * self ;
php_stream * stream ;
2002-03-19 23:29:37 +00:00
self = ecalloc ( 1 , sizeof ( * self ) ) ;
2002-03-17 23:50:31 +00:00
self - > smax = max_memory_usage ;
self - > mode = mode ;
2006-05-13 17:58:58 +00:00
self - > meta = NULL ;
2005-12-14 00:06:09 +00:00
stream = php_stream_alloc ( & php_stream_temp_ops , self , 0 , mode & TEMP_STREAM_READONLY ? " r+b " : " w+b " ) ;
2002-09-23 13:22:10 +00:00
stream - > flags | = PHP_STREAM_FLAG_NO_BUFFER ;
2002-03-18 04:57:06 +00:00
self - > innerstream = php_stream_memory_create ( mode ) ;
2006-01-05 22:03:07 +00:00
( ( php_stream_memory_data * ) self - > innerstream - > abstract ) - > owner_ptr = & self - > innerstream ;
2002-09-23 13:22:10 +00:00
2002-03-17 23:50:31 +00:00
return stream ;
2002-03-19 19:15:40 +00:00
}
/* }}} */
2002-03-17 23:50:31 +00:00
2002-03-19 19:15:40 +00:00
2003-03-01 15:20:42 +00:00
/* {{{ _php_stream_temp_open */
2002-03-19 19:15:40 +00:00
PHPAPI php_stream * _php_stream_temp_open ( int mode , size_t max_memory_usage , char * buf , size_t length STREAMS_DC TSRMLS_DC )
2002-03-21 20:37:04 +00:00
{
2002-03-17 23:50:31 +00:00
php_stream * stream ;
2006-05-13 17:58:58 +00:00
php_stream_temp_data * ts ;
off_t newoffs ;
2002-03-17 23:50:31 +00:00
2005-12-14 00:06:09 +00:00
if ( ( stream = php_stream_temp_create_rel ( mode , max_memory_usage ) ) ! = NULL ) {
2002-03-18 04:57:06 +00:00
if ( length ) {
2002-03-17 23:50:31 +00:00
assert ( buf ! = NULL ) ;
2002-03-18 18:54:32 +00:00
php_stream_temp_write ( stream , buf , length TSRMLS_CC ) ;
2006-05-13 17:58:58 +00:00
php_stream_temp_seek ( stream , 0 , SEEK_SET , & newoffs TSRMLS_CC ) ;
2002-03-17 23:50:31 +00:00
}
2006-05-13 17:58:58 +00:00
ts = ( php_stream_temp_data * ) stream - > abstract ;
assert ( ts ! = NULL ) ;
ts - > mode = mode ;
2002-03-17 23:50:31 +00:00
}
return stream ;
2002-03-19 19:15:40 +00:00
}
/* }}} */
2002-03-17 23:50:31 +00:00
2006-05-13 17:58:58 +00:00
php_stream_ops php_stream_rfc2397_ops = {
php_stream_temp_write , php_stream_temp_read ,
php_stream_temp_close , php_stream_temp_flush ,
" RFC2397 " ,
php_stream_temp_seek ,
php_stream_temp_cast ,
php_stream_temp_stat ,
php_stream_temp_set_option
} ;
static php_stream * php_stream_url_wrap_rfc2397 ( php_stream_wrapper * wrapper , char * path , char * mode , int options , char * * opened_path , php_stream_context * context STREAMS_DC TSRMLS_DC ) /* { { { */
{
php_stream * stream ;
php_stream_temp_data * ts ;
2006-05-14 01:06:09 +00:00
char * comma , * semi , * sep , * key ;
size_t mlen , dlen , plen , vlen ;
2006-05-13 17:58:58 +00:00
off_t newoffs ;
2006-05-14 01:06:09 +00:00
zval * meta = NULL ;
2006-05-14 01:42:03 +00:00
int base64 = 0 , ilen ;
2006-05-13 17:58:58 +00:00
if ( memcmp ( path , " data: " , 5 ) ) {
return NULL ;
}
path + = 5 ;
dlen = strlen ( path ) ;
if ( dlen > = 2 & & path [ 0 ] = = ' / ' & & path [ 1 ] = = ' / ' ) {
dlen - = 2 ;
path + = 2 ;
}
if ( ( comma = memchr ( path , ' , ' , dlen ) ) = = NULL ) {
2006-06-29 14:40:49 +00:00
php_stream_wrapper_log_error ( wrapper , options TSRMLS_CC , " rfc2397: no comma in URL " ) ;
2006-05-13 17:58:58 +00:00
return NULL ;
}
2006-05-14 01:06:09 +00:00
if ( comma ! = path ) {
/* meta info */
mlen = comma - path ;
dlen - = mlen ;
semi = memchr ( path , ' ; ' , mlen ) ;
sep = memchr ( path , ' / ' , mlen ) ;
if ( ! semi & & ! sep ) {
php_stream_wrapper_log_error ( wrapper , options TSRMLS_CC , " rfc2397: illegal media type " ) ;
return NULL ;
}
MAKE_STD_ZVAL ( meta ) ;
array_init ( meta ) ;
if ( ! semi ) { /* there is only a mime type */
add_assoc_stringl ( meta , " mediatype " , path , mlen , 1 ) ;
mlen = 0 ;
} else if ( sep & & sep < semi ) { /* there is a mime type */
plen = semi - path ;
add_assoc_stringl ( meta , " mediatype " , path , plen , 1 ) ;
mlen - = plen ;
path + = plen ;
} else if ( semi ! = path | | mlen ! = sizeof ( " ;base64 " ) - 1 | | memcmp ( path , " ;base64 " , sizeof ( " ;base64 " ) - 1 ) ) { /* must be error since parameters are only allowed after mediatype */
zval_ptr_dtor ( & meta ) ;
php_stream_wrapper_log_error ( wrapper , options TSRMLS_CC , " rfc2397: illegal media type " ) ;
return NULL ;
}
/* get parameters and potentially ';base64' */
while ( semi & & ( semi = = path ) ) {
path + + ;
mlen - - ;
sep = memchr ( path , ' = ' , mlen ) ;
2006-05-13 17:58:58 +00:00
semi = memchr ( path , ' ; ' , mlen ) ;
2006-05-14 01:06:09 +00:00
if ( ! sep | | ( semi & & semi < sep ) ) { /* must be ';base64' or failure */
if ( mlen ! = sizeof ( " base64 " ) - 1 | | memcmp ( path , " base64 " , sizeof ( " base64 " ) - 1 ) ) {
/* must be error since parameters are only allowed after mediatype and we have no '=' sign */
zval_ptr_dtor ( & meta ) ;
php_stream_wrapper_log_error ( wrapper , options TSRMLS_CC , " rfc2397: illegal parameter " ) ;
return NULL ;
}
base64 = 1 ;
mlen - = sizeof ( " base64 " ) - 1 ;
path + = sizeof ( " base64 " ) - 1 ;
break ;
}
/* found parameter ... the heart of cs ppl lies in +1/-1 or was it +2 this time? */
plen = sep - path ;
vlen = ( semi ? semi - sep : mlen - plen ) - 1 /* '=' */ ;
key = estrndup ( path , plen ) ;
add_assoc_stringl_ex ( meta , key , plen + 1 , sep + 1 , vlen , 1 ) ;
efree ( key ) ;
plen + = vlen + 1 ;
mlen - = plen ;
path + = plen ;
2006-05-13 17:58:58 +00:00
}
2006-05-14 01:06:09 +00:00
if ( mlen ) {
zval_ptr_dtor ( & meta ) ;
2006-06-29 14:40:49 +00:00
php_stream_wrapper_log_error ( wrapper , options TSRMLS_CC , " rfc2397: illegal URL " ) ;
2006-05-14 01:06:09 +00:00
return NULL ;
}
} else {
MAKE_STD_ZVAL ( meta ) ;
array_init ( meta ) ;
}
add_assoc_bool ( meta , " base64 " , base64 ) ;
2006-05-21 13:37:19 +00:00
/* skip ',' */
comma + + ;
dlen - - ;
if ( base64 ) {
comma = ( char * ) php_base64_decode ( ( const unsigned char * ) comma , dlen , & ilen ) ;
if ( ! comma ) {
2006-06-06 14:09:12 +00:00
zval_ptr_dtor ( & meta ) ;
2006-05-21 13:37:19 +00:00
php_stream_wrapper_log_error ( wrapper , options TSRMLS_CC , " rfc2397: unable to decode " ) ;
return NULL ;
}
} else {
comma = estrndup ( comma , dlen ) ;
ilen = dlen = php_url_decode ( comma , dlen ) ;
}
2006-05-14 01:06:09 +00:00
if ( ( stream = php_stream_temp_create_rel ( 0 , ~ 0u ) ) ! = NULL ) {
2006-05-13 17:58:58 +00:00
/* store data */
2006-05-21 13:37:19 +00:00
php_stream_temp_write ( stream , comma , ilen TSRMLS_CC ) ;
2006-05-13 17:58:58 +00:00
php_stream_temp_seek ( stream , 0 , SEEK_SET , & newoffs TSRMLS_CC ) ;
2006-05-14 01:06:09 +00:00
/* set special stream stuff (enforce exact mode) */
vlen = strlen ( mode ) ;
if ( vlen > = sizeof ( stream - > mode ) ) {
vlen = sizeof ( stream - > mode ) - 1 ;
}
memcpy ( stream - > mode , mode , vlen ) ;
stream - > mode [ vlen ] = ' \0 ' ;
stream - > ops = & php_stream_rfc2397_ops ;
2006-05-13 17:58:58 +00:00
ts = ( php_stream_temp_data * ) stream - > abstract ;
assert ( ts ! = NULL ) ;
ts - > mode = mode & & mode [ 0 ] = = ' r ' ? TEMP_STREAM_READONLY : 0 ;
2006-05-14 01:06:09 +00:00
ts - > meta = meta ;
2006-05-13 17:58:58 +00:00
}
2006-12-21 00:47:02 +00:00
efree ( comma ) ;
2006-05-13 17:58:58 +00:00
return stream ;
}
static php_stream_wrapper_ops php_stream_rfc2397_wops = {
php_stream_url_wrap_rfc2397 ,
NULL , /* close */
NULL , /* fstat */
NULL , /* stat */
NULL , /* opendir */
" RFC2397 " ,
NULL , /* unlink */
NULL , /* rename */
NULL , /* mkdir */
NULL /* rmdir */
} ;
php_stream_wrapper php_stream_rfc2397_wrapper = {
& php_stream_rfc2397_wops ,
NULL ,
2006-11-04 20:43:28 +00:00
1 , /* is_url */
2006-05-13 17:58:58 +00:00
} ;
2003-03-01 15:20:42 +00:00
2002-03-16 20:11:06 +00:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
* vim600 : noet sw = 4 ts = 4 fdm = marker
* vim < 600 : noet sw = 4 ts = 4
*/