Commit 8e199059 authored by Etienne CHAMPETIER's avatar Etienne CHAMPETIER

ZP-796 Reimplement/simplify StringStreamWrapper.

Released under the Affero GNU General Public License (AGPL) version 3.

Current implementation only works without filters,
ie if you only use it to store and retrieve string
(see https://3v4l.org/Du2cF or http://pastebin.com/NrK2efzv)

It can be replaced by "php://memory", available since php 5.1
(i'm pretty sure this code is way older than php 5.1)

This remove utf8 ftruncate support (68d180a5)
but ftruncate isn't used on StringStreamWrapper, and utf8 support must be in
the code handling the stream so we can use any type of stream
parent 77b78652
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
* File : stringstreamwrapper.php * File : stringstreamwrapper.php
* Project : Z-Push * Project : Z-Push
* Descr : Wraps a string as a standard php stream * Descr : Wraps a string as a standard php stream
* The used method names are predefined and can not be altered.
* *
* Created : 24.11.2011 * Created : 24.11.2011
* *
...@@ -43,151 +42,21 @@ ...@@ -43,151 +42,21 @@
************************************************/ ************************************************/
class StringStreamWrapper { class StringStreamWrapper {
const PROTOCOL = "stringstream";
private $stringstream;
private $position;
private $stringlength;
/**
* Opens the stream
* The string to be streamed is passed over the context
*
* @param string $path Specifies the URL that was passed to the original function
* @param string $mode The mode used to open the file, as detailed for fopen()
* @param int $options Holds additional flags set by the streams API
* @param string $opened_path If the path is opened successfully, and STREAM_USE_PATH is set in options,
* opened_path should be set to the full path of the file/resource that was actually opened.
*
* @access public
* @return boolean
*/
public function stream_open($path, $mode, $options, &$opened_path) {
$contextOptions = stream_context_get_options($this->context);
if (!isset($contextOptions[self::PROTOCOL]['string']))
return false;
$this->position = 0;
// this is our stream!
$this->stringstream = $contextOptions[self::PROTOCOL]['string'];
$this->stringlength = strlen($this->stringstream);
ZLog::Write(LOGLEVEL_DEBUG, sprintf("StringStreamWrapper::stream_open(): initialized stream length: %d", $this->stringlength));
return true;
}
/** /**
* Reads from stream * Wrap a string into a "php://memory" stream
*
* @param int $len amount of bytes to be read
* *
* @param string $string The string to be wrapped
* @access public * @access public
* @return string * @return stream
*/ */
public function stream_read($len) { public static function Open($string) {
$data = substr($this->stringstream, $this->position, $len); ZLog::Write(LOGLEVEL_DEBUG, "StringStreamWrapper::Open(): len = ".strlen($string));
$this->position += strlen($data); if (($stream = fopen('php://memory', 'r+')) === false)
return $data; throw new FatalException('StringStreamWrapper: fopen "php://memory" failed');
} if (fwrite($stream, $string) === false)
throw new FatalException('StringStreamWrapper: fwrite failed');
/** if (rewind($stream) === false)
* Writes data to the stream. throw new FatalException('StringStreamWrapper: rewind failed');
* return $stream;
* @param string $data
* @return int
*/
public function stream_write($data){
$l = strlen($data);
$this->stringstream = substr($this->stringstream, 0, $this->position) . $data . substr($this->stringstream, $this->position += $l);
$this->stringlength = strlen($this->stringstream);
return $l;
}
/**
* Stream "seek" functionality.
*
* @param int $offset
* @param int $whence
* @return boolean
*/
public function stream_seek($offset, $whence = SEEK_SET) {
if ($whence == SEEK_CUR) {
$this->position += $offset;
}
else if ($whence == SEEK_END) {
$this->position = $this->stringlength + $offset;
}
else {
$this->position = $offset;
}
return true;
}
/**
* Returns the current position on stream
*
* @access public
* @return int
*/
public function stream_tell() {
return $this->position;
}
/**
* Indicates if 'end of file' is reached
*
* @access public
* @return boolean
*/
public function stream_eof() {
return ($this->position >= $this->stringlength);
}
/**
* Truncates the stream to the new size.
*
* @param int $new_size
* @return boolean
*/
public function stream_truncate ($new_size) {
// cut the string!
$this->stringstream = Utils::Utf8_truncate($this->stringstream, $new_size);
$this->streamlength = strlen($this->stringstream);
if ($this->position > $this->streamlength) {
ZLog::Write(LOGLEVEL_WARN, sprintf("MAPIStreamWrapper->stream_truncate(): stream position (%d) ahead of new size of %d. Repositioning pointer to end of stream.", $this->position, $this->streamlength));
$this->position = $this->streamlength;
}
return true;
}
/**
* Retrieves information about a stream
*
* @access public
* @return array
*/
public function stream_stat() {
return array(
7 => $this->stringlength,
'size' => $this->stringlength,
);
}
/**
* Instantiates a StringStreamWrapper
*
* @param string $string The string to be wrapped
*
* @access public
* @return StringStreamWrapper
*/
static public function Open($string) {
$context = stream_context_create(array(self::PROTOCOL => array('string' => &$string)));
return fopen(self::PROTOCOL . "://",'r', false, $context);
} }
} }
stream_wrapper_register(StringStreamWrapper::PROTOCOL, "StringStreamWrapper");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment