212 lines
4.5 KiB
PHP
212 lines
4.5 KiB
PHP
<?php
|
|
/**
|
|
* Copyright 2007-2017 Horde LLC (http://www.horde.org/)
|
|
*
|
|
* See the enclosed file COPYING for license information (BSD). If you
|
|
* did not receive this file, see http://www.horde.org/licenses/bsd.
|
|
*
|
|
* @category Horde
|
|
* @copyright 2007-2017 Horde LLC
|
|
* @license http://www.horde.org/licenses/bsd BSD
|
|
* @package Stream_Wrapper
|
|
*/
|
|
|
|
/**
|
|
* A stream wrapper that will treat a native PHP string as a stream.
|
|
*
|
|
* @author Chuck Hagenbuch <chuck@horde.org>
|
|
* @author Michael Slusarz <slusarz@horde.org>
|
|
* @category Horde
|
|
* @copyright 2007-2017 Horde LLC
|
|
* @license http://www.horde.org/licenses/bsd BSD
|
|
* @package Stream_Wrapper
|
|
*/
|
|
class Horde_Stream_Wrapper_String
|
|
{
|
|
/**/
|
|
const WRAPPER_NAME = 'horde-stream-wrapper-string';
|
|
|
|
/**
|
|
* The current context.
|
|
*
|
|
* @var resource
|
|
*/
|
|
public $context;
|
|
|
|
/**
|
|
* String position.
|
|
*
|
|
* @var integer
|
|
*/
|
|
protected $_pos;
|
|
|
|
/**
|
|
* The string.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $_string;
|
|
|
|
/**
|
|
* Unique ID tracker for the streams.
|
|
*
|
|
* @var integer
|
|
*/
|
|
private static $_id = 0;
|
|
|
|
/**
|
|
* Create a stream from a PHP string.
|
|
*
|
|
* @since 2.1.0
|
|
*
|
|
* @param string &$string A PHP string variable.
|
|
*
|
|
* @return resource A PHP stream pointing to the variable.
|
|
*/
|
|
public static function getStream(&$string)
|
|
{
|
|
if (!self::$_id) {
|
|
stream_wrapper_register(self::WRAPPER_NAME, __CLASS__);
|
|
}
|
|
|
|
/* Needed to keep reference. */
|
|
$ob = new stdClass;
|
|
$ob->string = &$string;
|
|
|
|
return fopen(
|
|
self::WRAPPER_NAME . '://' . ++self::$_id,
|
|
'wb',
|
|
false,
|
|
stream_context_create(array(
|
|
self::WRAPPER_NAME => array(
|
|
'string' => $ob
|
|
)
|
|
))
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @see streamWrapper::stream_open()
|
|
*/
|
|
public function stream_open($path, $mode, $options, &$opened_path)
|
|
{
|
|
$opts = stream_context_get_options($this->context);
|
|
|
|
if (isset($opts[self::WRAPPER_NAME]['string'])) {
|
|
$this->_string =& $opts[self::WRAPPER_NAME]['string']->string;
|
|
} elseif (isset($opts['horde-string']['string'])) {
|
|
// @deprecated
|
|
$this->_string =& $opts['horde-string']['string']->getString();
|
|
} else {
|
|
throw new Exception('Use ' . __CLASS__ . '::getStream() to initialize the stream.');
|
|
}
|
|
|
|
if (is_null($this->_string)) {
|
|
return false;
|
|
}
|
|
|
|
$this->_pos = 0;
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @see streamWrapper::stream_close()
|
|
*/
|
|
public function stream_close()
|
|
{
|
|
$this->_string = '';
|
|
$this->_pos = 0;
|
|
}
|
|
|
|
/**
|
|
* @see streamWrapper::stream_read()
|
|
*/
|
|
public function stream_read($count)
|
|
{
|
|
$curr = $this->_pos;
|
|
$this->_pos += $count;
|
|
return substr($this->_string, $curr, $count);
|
|
}
|
|
|
|
/**
|
|
* @see streamWrapper::stream_write()
|
|
*/
|
|
public function stream_write($data)
|
|
{
|
|
$len = strlen($data);
|
|
|
|
$this->_string = substr_replace($this->_string, $data, $this->_pos, $len);
|
|
$this->_pos += $len;
|
|
|
|
return $len;
|
|
}
|
|
|
|
/**
|
|
* @see streamWrapper::stream_tell()
|
|
*/
|
|
public function stream_tell()
|
|
{
|
|
return $this->_pos;
|
|
}
|
|
|
|
/**
|
|
* @see streamWrapper::stream_eof()
|
|
*/
|
|
public function stream_eof()
|
|
{
|
|
return ($this->_pos > strlen($this->_string));
|
|
}
|
|
|
|
/**
|
|
* @see streamWrapper::stream_stat()
|
|
*/
|
|
public function stream_stat()
|
|
{
|
|
return array(
|
|
'dev' => 0,
|
|
'ino' => 0,
|
|
'mode' => 0,
|
|
'nlink' => 0,
|
|
'uid' => 0,
|
|
'gid' => 0,
|
|
'rdev' => 0,
|
|
'size' => strlen($this->_string),
|
|
'atime' => 0,
|
|
'mtime' => 0,
|
|
'ctime' => 0,
|
|
'blksize' => 0,
|
|
'blocks' => 0
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @see streamWrapper::stream_seek()
|
|
*/
|
|
public function stream_seek($offset, $whence)
|
|
{
|
|
switch ($whence) {
|
|
case SEEK_SET:
|
|
$pos = $offset;
|
|
break;
|
|
|
|
case SEEK_CUR:
|
|
$pos = $this->_pos + $offset;
|
|
break;
|
|
|
|
case SEEK_END:
|
|
$pos = strlen($this->_string) + $offset;
|
|
break;
|
|
}
|
|
|
|
if (($pos < 0) || ($pos > strlen($this->_string))) {
|
|
return false;
|
|
}
|
|
|
|
$this->_pos = $pos;
|
|
|
|
return true;
|
|
}
|
|
|
|
}
|