[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Copyright 2009-2014 Horde LLC (http://www.horde.org/) 4 * 5 * See the enclosed file COPYING for license information (BSD). If you 6 * did not receive this file, see http://www.horde.org/licenses/bsd. 7 * 8 * @category Horde 9 * @copyright 2009-2014 Horde LLC 10 * @license http://www.horde.org/licenses/bsd BSD 11 * @package Stream_Wrapper 12 */ 13 14 /** 15 * A stream wrapper that will combine multiple strings/streams into a single 16 * stream. 17 * 18 * @author Michael Slusarz <slusarz@horde.org> 19 * @category Horde 20 * @copyright 2009-2014 Horde LLC 21 * @license http://www.horde.org/licenses/bsd BSD 22 * @package Stream_Wrapper 23 */ 24 class Horde_Stream_Wrapper_Combine 25 { 26 /**/ 27 const WRAPPER_NAME = 'horde-stream-wrapper-combine'; 28 29 /** 30 * Context. 31 * 32 * @var resource 33 */ 34 public $context; 35 36 /** 37 * Array that holds the various streams. 38 * 39 * @var array 40 */ 41 protected $_data = array(); 42 43 /** 44 * The combined length of the stream. 45 * 46 * @var integer 47 */ 48 protected $_length = 0; 49 50 /** 51 * The current position in the string. 52 * 53 * @var integer 54 */ 55 protected $_position = 0; 56 57 /** 58 * The current position in the data array. 59 * 60 * @var integer 61 */ 62 protected $_datapos = 0; 63 64 /** 65 * Have we reached EOF? 66 * 67 * @var boolean 68 */ 69 protected $_ateof = false; 70 71 /** 72 * Unique ID tracker for the streams. 73 * 74 * @var integer 75 */ 76 static private $_id = 0; 77 78 /** 79 * Create a stream from multiple data sources. 80 * 81 * @since 2.1.0 82 * 83 * @param array $data An array of strings and/or streams to combine into 84 * a single stream. 85 * 86 * @return resource A PHP stream. 87 */ 88 static public function getStream($data) 89 { 90 if (!self::$_id) { 91 stream_wrapper_register(self::WRAPPER_NAME, __CLASS__); 92 } 93 94 return fopen( 95 self::WRAPPER_NAME . '://' . ++self::$_id, 96 'wb', 97 false, 98 stream_context_create(array( 99 self::WRAPPER_NAME => array( 100 'data' => $data 101 ) 102 )) 103 ); 104 } 105 /** 106 * @see streamWrapper::stream_open() 107 * 108 * @param string $path 109 * @param string $mode 110 * @param integer $options 111 * @param string &$opened_path 112 * 113 * @throws Exception 114 */ 115 public function stream_open($path, $mode, $options, &$opened_path) 116 { 117 $opts = stream_context_get_options($this->context); 118 119 if (isset($opts[self::WRAPPER_NAME]['data'])) { 120 $data = $opts[self::WRAPPER_NAME]['data']; 121 } elseif (isset($opts['horde-combine']['data'])) { 122 // @deprecated 123 $data = $opts['horde-combine']['data']->getData(); 124 } else { 125 throw new Exception('Use ' . __CLASS__ . '::getStream() to initialize the stream.'); 126 } 127 128 reset($data); 129 while (list(,$val) = each($data)) { 130 if (is_string($val)) { 131 $fp = fopen('php://temp', 'r+'); 132 fwrite($fp, $val); 133 } else { 134 $fp = $val; 135 } 136 137 fseek($fp, 0, SEEK_END); 138 $length = ftell($fp); 139 rewind($fp); 140 141 $this->_data[] = array( 142 'fp' => $fp, 143 'l' => $length, 144 'p' => 0 145 ); 146 147 $this->_length += $length; 148 } 149 150 return true; 151 } 152 153 /** 154 * @see streamWrapper::stream_read() 155 * 156 * @param integer $count 157 * 158 * @return mixed 159 */ 160 public function stream_read($count) 161 { 162 if ($this->stream_eof()) { 163 return false; 164 } 165 166 $out = ''; 167 168 while ($count) { 169 $tmp = &$this->_data[$this->_datapos]; 170 $curr_read = min($count, $tmp['l'] - $tmp['p']); 171 $out .= fread($tmp['fp'], $curr_read); 172 $count -= $curr_read; 173 $this->_position += $curr_read; 174 175 if ($this->_position == $this->_length) { 176 if ($count) { 177 $this->_ateof = true; 178 break; 179 } else { 180 $tmp['p'] += $curr_read; 181 } 182 } elseif ($count) { 183 $tmp = &$this->_data[++$this->_datapos]; 184 rewind($tmp['fp']); 185 $tmp['p'] = 0; 186 } else { 187 $tmp['p'] += $curr_read; 188 } 189 } 190 191 return $out; 192 } 193 194 /** 195 * @see streamWrapper::stream_write() 196 * 197 * @param string $data 198 * 199 * @return integer 200 */ 201 public function stream_write($data) 202 { 203 $tmp = &$this->_data[$this->_datapos]; 204 205 $oldlen = $tmp['l']; 206 $res = fwrite($tmp['fp'], $data); 207 if ($res === false) { 208 return false; 209 } 210 211 $tmp['p'] = ftell($tmp['fp']); 212 if ($tmp['p'] > $oldlen) { 213 $tmp['l'] = $tmp['p']; 214 $this->_length += ($tmp['l'] - $oldlen); 215 } 216 217 return $res; 218 } 219 220 /** 221 * @see streamWrapper::stream_tell() 222 * 223 * @return integer 224 */ 225 public function stream_tell() 226 { 227 return $this->_position; 228 } 229 230 /** 231 * @see streamWrapper::stream_eof() 232 * 233 * @return boolean 234 */ 235 public function stream_eof() 236 { 237 return $this->_ateof; 238 } 239 240 /** 241 * @see streamWrapper::stream_stat() 242 * 243 * @return array 244 */ 245 public function stream_stat() 246 { 247 return array( 248 'dev' => 0, 249 'ino' => 0, 250 'mode' => 0, 251 'nlink' => 0, 252 'uid' => 0, 253 'gid' => 0, 254 'rdev' => 0, 255 'size' => $this->_length, 256 'atime' => 0, 257 'mtime' => 0, 258 'ctime' => 0, 259 'blksize' => 0, 260 'blocks' => 0 261 ); 262 } 263 264 /** 265 * @see streamWrapper::stream_seek() 266 * 267 * @param integer $offset 268 * @param integer $whence SEEK_SET, SEEK_CUR, or SEEK_END 269 * 270 * @return boolean 271 */ 272 public function stream_seek($offset, $whence) 273 { 274 $oldpos = $this->_position; 275 $this->_ateof = false; 276 277 switch ($whence) { 278 case SEEK_SET: 279 $offset = $offset; 280 break; 281 282 case SEEK_CUR: 283 $offset = $this->_position + $offset; 284 break; 285 286 case SEEK_END: 287 $offset = $this->_length + $offset; 288 break; 289 290 default: 291 return false; 292 } 293 294 $count = $this->_position = min($this->_length, $offset); 295 296 foreach ($this->_data as $key => $val) { 297 if ($count < $val['l']) { 298 $this->_datapos = $key; 299 $val['p'] = $count; 300 fseek($val['fp'], $count, SEEK_SET); 301 break; 302 } 303 $count -= $val['l']; 304 } 305 306 return ($oldpos != $this->_position); 307 } 308 309 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |