PageRenderTime 45ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/xoops_trust_path/vendor/PEAR/File/Archive/Reader/Cache.php

https://github.com/nouphet/momoxo
PHP | 262 lines | 169 code | 15 blank | 78 comment | 33 complexity | 5e7fb61f4a91717f262ca4465b1322a6 MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-2.1
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * This reader caches the files of another reader
  5. * It allow fast access to files. This is usefull if the access to the reader
  6. * is slow (HTTP, FTP...), but will need more IO if the file is only extracted
  7. *
  8. * PHP versions 4 and 5
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation; either
  13. * version 2.1 of the License, or (at your option) any later version.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330,Boston,MA 02111-1307 USA
  23. *
  24. * @category File Formats
  25. * @package File_Archive
  26. * @author Vincent Lascaux <vincentlascaux@php.net>
  27. * @copyright 1997-2005 The PHP Group
  28. * @license http://www.gnu.org/copyleft/lesser.html LGPL
  29. * @version CVS: $Id$
  30. * @link http://pear.php.net/package/File_Archive
  31. */
  32. require_once "File/Archive/Reader.php";
  33. /**
  34. * This reader caches the files of another reader
  35. * It allow fast access to files. This is usefull if the access to the reader
  36. * is slow (HTTP, FTP...), but will need more IO if the file is only extracted
  37. */
  38. class File_Archive_Reader_Cache extends File_Archive_Reader
  39. {
  40. var $tmpFile;
  41. var $files = array();
  42. var $pos = 0;
  43. var $fromSource = true;
  44. var $endOfSource = false;
  45. var $source;
  46. /**
  47. * $source is the reader to filter
  48. */
  49. function File_Archive_Reader_Cache(&$source)
  50. {
  51. $this->source =& $source;
  52. $this->tmpFile = tmpfile();
  53. }
  54. function _writeEndOfFile()
  55. {
  56. $bufferSize = File_Archive::getOption('blockSize');
  57. while (($data = $this->source->getData($bufferSize))!=null) {
  58. fwrite($this->tmpFile, $data);
  59. }
  60. }
  61. /**
  62. * @see File_Archive_Reader::next()
  63. */
  64. function next()
  65. {
  66. //Write the end of the current file to the temp file
  67. if ($this->fromSource && !empty($this->files)) {
  68. $this->_writeEndOfFile();
  69. }
  70. if ($this->pos+1 < count($this->files) && !$this->fromSource) {
  71. $this->pos++;
  72. fseek($this->tmpFile, $this->files[$this->pos]['pos'], SEEK_SET);
  73. return true;
  74. } else {
  75. $this->fromSource = true;
  76. if ($this->endOfSource) {
  77. return false;
  78. }
  79. $ret = $this->source->next();
  80. if ($ret !== true) {
  81. $this->endOfSource = true;
  82. $this->source->close();
  83. return $ret;
  84. }
  85. $this->endOfSource = false;
  86. fseek($this->tmpFile, 0, SEEK_END);
  87. $this->files[] = array(
  88. 'name' => $this->source->getFilename(),
  89. 'stat' => $this->source->getStat(),
  90. 'mime' => $this->source->getMime(),
  91. 'pos' => ftell($this->tmpFile)
  92. );
  93. $this->pos = count($this->files)-1;
  94. return true;
  95. }
  96. }
  97. /**
  98. * @see File_Archive_Reader::getFilename()
  99. */
  100. function getFilename() { return $this->files[$this->pos]['name']; }
  101. /**
  102. * @see File_Archive_Reader::getStat()
  103. */
  104. function getStat() { return $this->files[$this->pos]['stat']; }
  105. /**
  106. * @see File_Archive_Reader::getMime()
  107. */
  108. function getMime() { return $this->files[$this->pos]['mime']; }
  109. /**
  110. * @see File_Archive_Reader::getDataFilename()
  111. */
  112. function getDataFilename() { return null; }
  113. /**
  114. * @see File_Archive_Reader::getData()
  115. */
  116. function getData($length = -1)
  117. {
  118. if ($this->fromSource) {
  119. $data = $this->source->getData($length);
  120. if (PEAR::isError($data)) {
  121. return $data;
  122. }
  123. fwrite($this->tmpFile, $data);
  124. return $data;
  125. } else {
  126. if ($length == 0) {
  127. return '';
  128. }
  129. if ($length > 0 && $this->pos+1 < count($this->files)) {
  130. $maxSize = $this->files[$this->pos+1]['pos'] - ftell($this->tmpFile);
  131. if ($maxSize == 0) {
  132. return null;
  133. }
  134. if ($length > $maxSize) {
  135. $length = $maxSize;
  136. }
  137. return fread($this->tmpFile, $length);
  138. } else {
  139. $contents = '';
  140. $blockSize = File_Archive::getOption('blockSize');
  141. while (!feof($this->tmpFile)) {
  142. $contents .= fread($this->tmpFile, $blockSize);
  143. }
  144. return $contents == '' ? null : $contents;
  145. }
  146. }
  147. }
  148. /**
  149. * @see File_Archive_Reader::skip()
  150. */
  151. function skip($length = -1)
  152. {
  153. if ($this->fromSource) {
  154. return strlen($this->getData($length));
  155. } else {
  156. if ($length >= 0 && $this->pos+1 < count($this->files)) {
  157. $maxSize = $this->files[$this->pos+1]['pos'] - ftell($this->tmpFile);
  158. if ($maxSize == 0) {
  159. return null;
  160. }
  161. if ($length > $maxSize) {
  162. $length = $maxSize;
  163. }
  164. fseek($this->tmpFile, $length, SEEK_CUR);
  165. return $length;
  166. } else {
  167. $before = ftell($this->tmpFile);
  168. fseek($this->tmpFile, 0, SEEK_SET);
  169. $after = fteel($this->tmpFile);
  170. return $after - $before;
  171. }
  172. }
  173. }
  174. /**
  175. * @see File_Archive_Reader::rewind()
  176. */
  177. function rewind($length = -1)
  178. {
  179. if ($this->fromSource) {
  180. $this->_writeEndOfFile();
  181. $this->fromSource = false;
  182. }
  183. $before = ftell($this->tmpFile);
  184. $pos = $this->files[$this->pos]['pos'];
  185. fseek($this->tmpFile, $pos, SEEK_SET);
  186. return $pos - $before;
  187. }
  188. /**
  189. * @see File_Archive_Reader::tell()
  190. */
  191. function tell()
  192. {
  193. return ftell($this->tmpFile) - $this->files[$this->pos]['pos'];
  194. }
  195. /**
  196. * @see File_Archive_Reader::close()
  197. */
  198. function close()
  199. {
  200. $this->fromSource = false;
  201. $this->pos = 0;
  202. fseek($this->tmpFile, 0, SEEK_SET);
  203. }
  204. function _closeAndReset()
  205. {
  206. $this->close();
  207. fclose($this->tmpFile);
  208. $this->tmpFile = tmpfile();
  209. $this->endOfSource = false;
  210. $this->files = array();
  211. $this->source->close();
  212. }
  213. /**
  214. * @see File_Archive_Reader::makeAppendWriter()
  215. */
  216. function makeAppendWriter()
  217. {
  218. $writer = $this->source->makeAppendWriter();
  219. if (!PEAR::isError($writer)) {
  220. $this->_closeAndReset();
  221. }
  222. return $writer;
  223. }
  224. /**
  225. * @see File_Archive_Reader::makeWriterRemoveFiles()
  226. */
  227. function makeWriterRemoveFiles($pred)
  228. {
  229. $writer = $this->source->makeWriterRemoveFiles($pred);
  230. if (!PEAR::isError($writer)) {
  231. $this->_closeAndReset();
  232. }
  233. return $writer;
  234. }
  235. /**
  236. * @see File_Archive_Reader::makeWriterRemoveBlocks()
  237. */
  238. function makeWriterRemoveBlocks($blocks, $seek = 0)
  239. {
  240. $writer = $this->source->makeWriterRemoveBlocks($blocks, $seek);
  241. if (!PEAR::isError($writer)) {
  242. $this->_closeAndReset();
  243. }
  244. return $writer;
  245. }
  246. }
  247. ?>