For God so loved the world, that He gave His only begotten Son, that all who believe in Him should not perish but have everlasting life
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

230 lines
7.3 KiB

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4 |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2002 The PHP Group |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license, |
  9. // | that is bundled with this package in the file LICENSE, and is |
  10. // | available at through the world-wide-web at |
  11. // | http://www.php.net/license/2_02.txt. |
  12. // | If you did not receive a copy of the PHP license and are unable to |
  13. // | obtain it through the world-wide-web, please send a note to |
  14. // | [email protected] so we can mail you a copy immediately. |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Xavier Noguer <[email protected]> |
  17. // | Based on OLE::Storage_Lite by Kawai, Takanori |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: PPS.php,v 1.7 2007/02/13 21:00:42 schmidt Exp $
  21. /**
  22. * Class for creating PPS's for OLE containers
  23. *
  24. * @author Xavier Noguer <xnoguer@php.net>
  25. * @category PHPExcel
  26. * @package PHPExcel_Shared_OLE
  27. */
  28. class PHPExcel_Shared_OLE_PPS
  29. {
  30. /**
  31. * The PPS index
  32. * @var integer
  33. */
  34. public $No;
  35. /**
  36. * The PPS name (in Unicode)
  37. * @var string
  38. */
  39. public $Name;
  40. /**
  41. * The PPS type. Dir, Root or File
  42. * @var integer
  43. */
  44. public $Type;
  45. /**
  46. * The index of the previous PPS
  47. * @var integer
  48. */
  49. public $PrevPps;
  50. /**
  51. * The index of the next PPS
  52. * @var integer
  53. */
  54. public $NextPps;
  55. /**
  56. * The index of it's first child if this is a Dir or Root PPS
  57. * @var integer
  58. */
  59. public $DirPps;
  60. /**
  61. * A timestamp
  62. * @var integer
  63. */
  64. public $Time1st;
  65. /**
  66. * A timestamp
  67. * @var integer
  68. */
  69. public $Time2nd;
  70. /**
  71. * Starting block (small or big) for this PPS's data inside the container
  72. * @var integer
  73. */
  74. public $_StartBlock;
  75. /**
  76. * The size of the PPS's data (in bytes)
  77. * @var integer
  78. */
  79. public $Size;
  80. /**
  81. * The PPS's data (only used if it's not using a temporary file)
  82. * @var string
  83. */
  84. public $_data;
  85. /**
  86. * Array of child PPS's (only used by Root and Dir PPS's)
  87. * @var array
  88. */
  89. public $children = array();
  90. /**
  91. * Pointer to OLE container
  92. * @var OLE
  93. */
  94. public $ole;
  95. /**
  96. * The constructor
  97. *
  98. * @access public
  99. * @param integer $No The PPS index
  100. * @param string $name The PPS name
  101. * @param integer $type The PPS type. Dir, Root or File
  102. * @param integer $prev The index of the previous PPS
  103. * @param integer $next The index of the next PPS
  104. * @param integer $dir The index of it's first child if this is a Dir or Root PPS
  105. * @param integer $time_1st A timestamp
  106. * @param integer $time_2nd A timestamp
  107. * @param string $data The (usually binary) source data of the PPS
  108. * @param array $children Array containing children PPS for this PPS
  109. */
  110. public function __construct($No, $name, $type, $prev, $next, $dir, $time_1st, $time_2nd, $data, $children)
  111. {
  112. $this->No = $No;
  113. $this->Name = $name;
  114. $this->Type = $type;
  115. $this->PrevPps = $prev;
  116. $this->NextPps = $next;
  117. $this->DirPps = $dir;
  118. $this->Time1st = $time_1st;
  119. $this->Time2nd = $time_2nd;
  120. $this->_data = $data;
  121. $this->children = $children;
  122. if ($data != '') {
  123. $this->Size = strlen($data);
  124. } else {
  125. $this->Size = 0;
  126. }
  127. }
  128. /**
  129. * Returns the amount of data saved for this PPS
  130. *
  131. * @access public
  132. * @return integer The amount of data (in bytes)
  133. */
  134. public function _DataLen()
  135. {
  136. if (!isset($this->_data)) {
  137. return 0;
  138. }
  139. //if (isset($this->_PPS_FILE)) {
  140. // fseek($this->_PPS_FILE, 0);
  141. // $stats = fstat($this->_PPS_FILE);
  142. // return $stats[7];
  143. //} else {
  144. return strlen($this->_data);
  145. //}
  146. }
  147. /**
  148. * Returns a string with the PPS's WK (What is a WK?)
  149. *
  150. * @access public
  151. * @return string The binary string
  152. */
  153. public function _getPpsWk()
  154. {
  155. $ret = str_pad($this->Name, 64, "\x00");
  156. $ret .= pack("v", strlen($this->Name) + 2) // 66
  157. . pack("c", $this->Type) // 67
  158. . pack("c", 0x00) //UK // 68
  159. . pack("V", $this->PrevPps) //Prev // 72
  160. . pack("V", $this->NextPps) //Next // 76
  161. . pack("V", $this->DirPps) //Dir // 80
  162. . "\x00\x09\x02\x00" // 84
  163. . "\x00\x00\x00\x00" // 88
  164. . "\xc0\x00\x00\x00" // 92
  165. . "\x00\x00\x00\x46" // 96 // Seems to be ok only for Root
  166. . "\x00\x00\x00\x00" // 100
  167. . PHPExcel_Shared_OLE::LocalDate2OLE($this->Time1st) // 108
  168. . PHPExcel_Shared_OLE::LocalDate2OLE($this->Time2nd) // 116
  169. . pack("V", isset($this->_StartBlock)?
  170. $this->_StartBlock:0) // 120
  171. . pack("V", $this->Size) // 124
  172. . pack("V", 0); // 128
  173. return $ret;
  174. }
  175. /**
  176. * Updates index and pointers to previous, next and children PPS's for this
  177. * PPS. I don't think it'll work with Dir PPS's.
  178. *
  179. * @access public
  180. * @param array &$raList Reference to the array of PPS's for the whole OLE
  181. * container
  182. * @return integer The index for this PPS
  183. */
  184. public static function _savePpsSetPnt(&$raList, $to_save, $depth = 0)
  185. {
  186. if (!is_array($to_save) || (empty($to_save))) {
  187. return 0xFFFFFFFF;
  188. } elseif (count($to_save) == 1) {
  189. $cnt = count($raList);
  190. // If the first entry, it's the root... Don't clone it!
  191. $raList[$cnt] = ( $depth == 0 ) ? $to_save[0] : clone $to_save[0];
  192. $raList[$cnt]->No = $cnt;
  193. $raList[$cnt]->PrevPps = 0xFFFFFFFF;
  194. $raList[$cnt]->NextPps = 0xFFFFFFFF;
  195. $raList[$cnt]->DirPps = self::_savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++);
  196. } else {
  197. $iPos = floor(count($to_save) / 2);
  198. $aPrev = array_slice($to_save, 0, $iPos);
  199. $aNext = array_slice($to_save, $iPos + 1);
  200. $cnt = count($raList);
  201. // If the first entry, it's the root... Don't clone it!
  202. $raList[$cnt] = ( $depth == 0 ) ? $to_save[$iPos] : clone $to_save[$iPos];
  203. $raList[$cnt]->No = $cnt;
  204. $raList[$cnt]->PrevPps = self::_savePpsSetPnt($raList, $aPrev, $depth++);
  205. $raList[$cnt]->NextPps = self::_savePpsSetPnt($raList, $aNext, $depth++);
  206. $raList[$cnt]->DirPps = self::_savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++);
  207. }
  208. return $cnt;
  209. }
  210. }