/**
* File write
*
* Whilst this function accepts a reference, the underlying fwrite
* will do a copy! This will roughly double the memory allocation for
* any write you do. Specifying chunked will get around this by only
* writing in specific chunk sizes. This defaults to 8192 which is a
* sane number to use most of the time (change the default with
* JStream::set('chunksize', newsize);)
* Note: This doesn't support gzip/bzip2 writing like reading does
*
* @param string $string Reference to the string to write.
* @param integer $length Length of the string to write.
* @param integer $chunk Size of chunks to write in.
*
* @return boolean
*
* @link https://www.php.net/manual/en/function.fwrite.php
* @since 1.7.0
*/
public function write(&$string, $length = 0, $chunk = 0)
{
if (!$this->fh) {
$this->setError(Text::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN'));
return false;
}
// If the length isn't set, set it to the length of the string.
if (!$length) {
$length = \strlen($string);
}
// If the chunk isn't set, set it to the default.
if (!$chunk) {
$chunk = $this->chunksize;
}
$retval = true;
// Capture PHP errors
$php_errormsg = '';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
$remaining = $length;
$start = 0;
do {
// If the amount remaining is greater than the chunk size, then use the chunk
$amount = $remaining > $chunk ? $chunk : $remaining;
$res = fwrite($this->fh, substr($string, $start), $amount);
// Returns false on error or the number of bytes written
if ($res === false) {
// Returned error
$this->setError($php_errormsg);
$retval = false;
$remaining = 0;
} elseif ($res === 0) {
// Wrote nothing?
$remaining = 0;
$this->setError(Text::_('JLIB_FILESYSTEM_ERROR_NO_DATA_WRITTEN'));
} else {
// Wrote something
$start += $amount;
$remaining -= $res;
}
} while ($remaining);
// Restore error tracking to what it was before.
ini_set('track_errors', $track_errors);
// Return the result
return $retval;
}