Created
October 11, 2011 23:12
-
-
Save chobie/1279760 to your computer and use it in GitHub Desktop.
php fwrite implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// from php 5.3.6 | |
PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC); | |
#define php_stream_write_string(stream, str) _php_stream_write(stream, str, strlen(str) TSRMLS_CC) | |
#define php_stream_write(stream, buf, count) _php_stream_write(stream, (buf), (count) TSRMLS_CC) | |
PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) | |
{ | |
if (buf == NULL || count == 0 || stream->ops->write == NULL) { | |
return 0; | |
} | |
if (stream->writefilters.head) { | |
return _php_stream_write_filtered(stream, buf, count, PSFS_FLAG_NORMAL TSRMLS_CC); | |
} else { | |
return _php_stream_write_buffer(stream, buf, count TSRMLS_CC); | |
} | |
} | |
/* Writes a buffer directly to a stream, using multiple of the chunk size */ | |
static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size_t count TSRMLS_DC) | |
{ | |
size_t didwrite = 0, towrite, justwrote; | |
/* if we have a seekable stream we need to ensure that data is written at the | |
* current stream->position. This means invalidating the read buffer and then | |
* performing a low-level seek */ | |
if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0 && stream->readpos != stream->writepos) { | |
stream->readpos = stream->writepos = 0; | |
stream->ops->seek(stream, stream->position, SEEK_SET, &stream->position TSRMLS_CC); | |
} | |
while (count > 0) { | |
towrite = count; | |
if (towrite > stream->chunk_size) | |
towrite = stream->chunk_size; | |
justwrote = stream->ops->write(stream, buf, towrite TSRMLS_CC); | |
/* convert justwrote to an integer, since normally it is unsigned */ | |
if ((int)justwrote > 0) { | |
buf += justwrote; | |
count -= justwrote; | |
didwrite += justwrote; | |
/* Only screw with the buffer if we can seek, otherwise we lose data | |
* buffered from fifos and sockets */ | |
if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0) { | |
stream->position += justwrote; | |
} | |
} else { | |
break; | |
} | |
} | |
return didwrite; | |
} | |
/* {{{ proto int fwrite(resource fp, string str [, int length]) | |
Binary-safe file write */ | |
PHPAPI PHP_FUNCTION(fwrite) | |
{ | |
zval *arg1; | |
char *arg2; | |
int arg2len; | |
int ret; | |
int num_bytes; | |
long arg3 = 0; | |
char *buffer = NULL; | |
php_stream *stream; | |
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &arg1, &arg2, &arg2len, &arg3) == FAILURE) { | |
RETURN_FALSE; | |
} | |
if (ZEND_NUM_ARGS() == 2) { | |
num_bytes = arg2len; | |
} else { | |
num_bytes = MAX(0, MIN((int)arg3, arg2len)); | |
} | |
if (!num_bytes) { | |
RETURN_LONG(0); | |
} | |
PHP_STREAM_TO_ZVAL(stream, &arg1); | |
if (PG(magic_quotes_runtime)) { | |
buffer = estrndup(arg2, num_bytes); | |
php_stripslashes(buffer, &num_bytes TSRMLS_CC); | |
} | |
ret = php_stream_write(stream, buffer ? buffer : arg2, num_bytes); | |
if (buffer) { | |
efree(buffer); | |
} | |
RETURN_LONG(ret); | |
} | |
/* }}} */ | |
/* | |
so... | |
fwrite returns `false` when passed invalid parameters only. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment