Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: *//*** Stream wrapper for reading data stored in an OLE file.** PHP versions 4 and 5** LICENSE: This source file is subject to version 3.0 of the PHP license* that is available through the world-wide-web at the following URI:* http://www.php.net/license/3_0.txt. If you did not receive a copy of* the PHP License and are unable to obtain it through the web, please* send a note to license@php.net so we can mail you a copy immediately.** @category Structures* @package OLE* @author Christian Schmidt <schmidt@php.net>* @license http://www.php.net/license/3_0.txt PHP License 3.0* @version CVS: $Id: ChainedBlockStream.php 322771 2012-01-26 01:24:20Z clockwerx $* @link http://pear.php.net/package/OLE* @since File available since Release 0.6.0*/require_once 'PEAR.php';require_once 'OLE.php';/*** Stream wrapper for reading data stored in an OLE file. Implements methods* for PHP's stream_wrapper_register(). For creating streams using this* wrapper, use OLE_PPS_File::getStream().** @category Structures* @package OLE* @author Christian Schmidt <schmidt@php.net>* @license http://www.php.net/license/3_0.txt PHP License 3.0* @version Release: @package_version@* @link http://pear.php.net/package/OLE* @since Class available since Release 0.6.0*/class OLE_ChainedBlockStream extends PEAR{/*** The OLE container of the file that is being read.* @var OLE*/var $ole;/*** Parameters specified by fopen().* @var array*/var $params;/*** The binary data of the file.* @var string*/var $data;/*** The file pointer.* @var int byte offset*/var $pos;/*** Implements support for fopen().* For creating streams using this wrapper, use OLE_PPS_File::getStream().* @param string resource name including scheme, e.g.* ole-chainedblockstream://oleInstanceId=1* @param string only "r" is supported* @param int mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH* @param string absolute path of the opened stream (out parameter)* @return bool true on success*/function stream_open($path, $mode, $options, &$openedPath){if ($mode != 'r') {if ($options & STREAM_REPORT_ERRORS) {trigger_error('Only reading is supported', E_USER_WARNING);}return false;}// 25 is length of "ole-chainedblockstream://"parse_str(substr($path, 25), $this->params);if (!isset($this->params['oleInstanceId'],$this->params['blockId'],$GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']])) {if ($options & STREAM_REPORT_ERRORS) {trigger_error('OLE stream not found', E_USER_WARNING);}return false;}$this->ole = $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']];$blockId = $this->params['blockId'];$this->data = '';if (isset($this->params['size']) &&$this->params['size'] < $this->ole->bigBlockThreshold &&$blockId != $this->ole->root->_StartBlock) {// Block id refers to small blocks$rootPos = $this->ole->_getBlockOffset($this->ole->root->_StartBlock);while ($blockId != -2) {$pos = $rootPos + $blockId * $this->ole->bigBlockSize;$blockId = $this->ole->sbat[$blockId];fseek($this->ole->_file_handle, $pos);$this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize);}} else {// Block id refers to big blockswhile ($blockId != -2) {$pos = $this->ole->_getBlockOffset($blockId);fseek($this->ole->_file_handle, $pos);$this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize);$blockId = $this->ole->bbat[$blockId];}}if (isset($this->params['size'])) {$this->data = substr($this->data, 0, $this->params['size']);}if ($options & STREAM_USE_PATH) {$openedPath = $path;}return true;}/*** Implements support for fclose().* @return string*/function stream_close(){$this->ole = null;unset($GLOBALS['_OLE_INSTANCES']);}/*** Implements support for fread(), fgets() etc.* @param int maximum number of bytes to read* @return string*/function stream_read($count){if ($this->stream_eof()) {return false;}$s = substr($this->data, $this->pos, $count);$this->pos += $count;return $s;}/*** Implements support for feof().* @return bool TRUE if the file pointer is at EOF; otherwise FALSE*/function stream_eof(){$eof = $this->pos >= strlen($this->data);// Workaround for bug in PHP 5.0.x: http://bugs.php.net/27508if (version_compare(PHP_VERSION, '5.0', '>=') &&version_compare(PHP_VERSION, '5.1', '<')) {$eof = !$eof;}return $eof;}/*** Returns the position of the file pointer, i.e. its offset into the file* stream. Implements support for ftell().* @return int*/function stream_tell(){return $this->pos;}/*** Implements support for fseek().* @param int byte offset* @param int SEEK_SET, SEEK_CUR or SEEK_END* @return bool*/function stream_seek($offset, $whence){if ($whence == SEEK_SET && $offset >= 0) {$this->pos = $offset;} elseif ($whence == SEEK_CUR && -$offset <= $this->pos) {$this->pos += $offset;} elseif ($whence == SEEK_END && -$offset <= sizeof($this->data)) {$this->pos = strlen($this->data) + $offset;} else {return false;}return true;}/*** Implements support for fstat(). Currently the only supported field is* "size".* @return array*/function stream_stat(){return array('size' => strlen($this->data),);}// Methods used by stream_wrapper_register() that are not implemented:// bool stream_flush ( void )// int stream_write ( string data )// bool rename ( string path_from, string path_to )// bool mkdir ( string path, int mode, int options )// bool rmdir ( string path, int options )// bool dir_opendir ( string path, int options )// array url_stat ( string path, int flags )// string dir_readdir ( void )// bool dir_rewinddir ( void )// bool dir_closedir ( void )}?>