PPS.php 7.0 KB

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