PageRenderTime 51ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/File.php

https://github.com/jeremyFreeAgent/File
PHP | 398 lines | 114 code | 68 blank | 216 comment | 10 complexity | c6bb1417acae625ef68d53bbda94077b MD5 | raw file
  1. <?php
  2. /**
  3. * Hoa
  4. *
  5. *
  6. * @license
  7. *
  8. * New BSD License
  9. *
  10. * Copyright © 2007-2013, Ivan Enderlin. All rights reserved.
  11. *
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that the following conditions are met:
  14. * * Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * * Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. * * Neither the name of the Hoa nor the names of its contributors may be
  20. * used to endorse or promote products derived from this software without
  21. * specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
  27. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  30. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  31. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. * POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. namespace {
  36. from('Hoa')
  37. /**
  38. * \Hoa\File\Exception
  39. */
  40. -> import('File.Exception.~')
  41. /**
  42. * \Hoa\File\Exception\FileDoesNotExist
  43. */
  44. -> import('File.Exception.FileDoesNotExist')
  45. /**
  46. * \Hoa\File\Generic
  47. */
  48. -> import('File.Generic')
  49. /**
  50. * \Hoa\Stream\IStream\Bufferable
  51. */
  52. -> import('Stream.I~.Bufferable')
  53. /**
  54. * \Hoa\Stream\IStream\Lockable
  55. */
  56. -> import('Stream.I~.Lockable')
  57. /**
  58. * \Hoa\Stream\IStream\Pointable
  59. */
  60. -> import('Stream.I~.Pointable');
  61. }
  62. namespace Hoa\File {
  63. /**
  64. * Class \Hoa\File.
  65. *
  66. * File handler.
  67. *
  68. * @author Ivan Enderlin <ivan.enderlin@hoa-project.net>
  69. * @copyright Copyright © 2007-2013 Ivan Enderlin.
  70. * @license New BSD License
  71. */
  72. abstract class File
  73. extends Generic
  74. implements \Hoa\Stream\IStream\Bufferable,
  75. \Hoa\Stream\IStream\Lockable,
  76. \Hoa\Stream\IStream\Pointable {
  77. /**
  78. * Open for reading only; place the file pointer at the beginning of the
  79. * file.
  80. *
  81. * @const string
  82. */
  83. const MODE_READ = 'rb';
  84. /**
  85. * Open for reading and writing; place the file pointer at the beginning of
  86. * the file.
  87. *
  88. * @const string
  89. */
  90. const MODE_READ_WRITE = 'r+b';
  91. /**
  92. * Open for writing only; place the file pointer at the beginning of the
  93. * file and truncate the file to zero length. If the file does not exist,
  94. * attempt to create it.
  95. *
  96. * @const string
  97. */
  98. const MODE_TRUNCATE_WRITE = 'wb';
  99. /**
  100. * Open for reading and writing; place the file pointer at the beginning of
  101. * the file and truncate the file to zero length. If the file does not
  102. * exist, attempt to create it.
  103. *
  104. * @const string
  105. */
  106. const MODE_TRUNCATE_READ_WRITE = 'w+b';
  107. /**
  108. * Open for writing only; place the file pointer at the end of the file. If
  109. * the file does not exist, attempt to create it.
  110. *
  111. * @const string
  112. */
  113. const MODE_APPEND_WRITE = 'ab';
  114. /**
  115. * Open for reading and writing; place the file pointer at the end of the
  116. * file. If the file does not exist, attempt to create it.
  117. *
  118. * @const string
  119. */
  120. const MODE_APPEND_READ_WRITE = 'a+b';
  121. /**
  122. * Create and open for writing only; place the file pointer at the beginning
  123. * of the file. If the file already exits, the fopen() call with fail by
  124. * returning false and generating an error of level E_WARNING. If the file
  125. * does not exist, attempt to create it. This is equivalent to specifying
  126. * O_EXCL | O_CREAT flags for the underlying open(2) system call.
  127. *
  128. * @const string
  129. */
  130. const MODE_CREATE_WRITE = 'xb';
  131. /**
  132. * Create and open for reading and writing; place the file pointer at the
  133. * beginning of the file. If the file already exists, the fopen() call with
  134. * fail by returning false and generating an error of level E_WARNING. If
  135. * the file does not exist, attempt to create it. This is equivalent to
  136. * specifying O_EXCL | O_CREAT flags for the underlying open(2) system call.
  137. *
  138. * @const string
  139. */
  140. const MODE_CREATE_READ_WRITE = 'x+b';
  141. /**
  142. * Open a file.
  143. *
  144. * @access public
  145. * @param string $streamName Stream name (or file descriptor).
  146. * @param string $mode Open mode, see the self::MODE_*
  147. * constants.
  148. * @param string $context Context ID (please, see the
  149. * \Hoa\Stream\Context class).
  150. * @param bool $wait Differ opening or not.
  151. * @return void
  152. * @throw \Hoa\File\Exception
  153. */
  154. public function __construct ( $streamName, $mode, $context = null,
  155. $wait = false ) {
  156. $this->setMode($mode);
  157. switch($streamName) {
  158. case '0':
  159. $streamName = 'php://stdin';
  160. break;
  161. case '1':
  162. $streamName = 'php://stdout';
  163. break;
  164. case '2':
  165. $streamName = 'php://stderr';
  166. break;
  167. default:
  168. if(true === ctype_digit($streamName))
  169. if(PHP_VERSION_ID >= 50306)
  170. $streamName = 'php://fd/' . $streamName;
  171. else
  172. throw new Exception(
  173. 'You need PHP5.3.6 to use a file descriptor ' .
  174. 'other than 0, 1 or 2 (tried %d with PHP%s).',
  175. 0, array($streamName, PHP_VERSION));
  176. }
  177. parent::__construct($streamName, $context, $wait);
  178. return;
  179. }
  180. /**
  181. * Open the stream and return the associated resource.
  182. *
  183. * @access protected
  184. * @param string $streamName Stream name (e.g. path or URL).
  185. * @param \Hoa\Stream\Context $context Context.
  186. * @return resource
  187. * @throw \Hoa\File\Exception\FileDoesNotExist
  188. * @throw \Hoa\File\Exception
  189. */
  190. protected function &_open ( $streamName, \Hoa\Stream\Context $context = null ) {
  191. if( substr($streamName, 0, 4) == 'file'
  192. && false === is_dir(dirname($streamName)))
  193. throw new Exception(
  194. 'Directory %s does not exist. Could not open file %s.',
  195. 0, array(dirname($streamName), basename($streamName)));
  196. if(null === $context) {
  197. if(false === $out = @fopen($streamName, $this->getMode(), true))
  198. throw new Exception(
  199. 'Failed to open stream %s.', 1, $streamName);
  200. return $out;
  201. }
  202. $out = @fopen(
  203. $streamName,
  204. $this->getMode(),
  205. true,
  206. $context->getContext()
  207. );
  208. if(false === $out)
  209. throw new Exception(
  210. 'Failed to open stream %s.', 2, $streamName);
  211. return $out;
  212. }
  213. /**
  214. * Close the current stream.
  215. *
  216. * @access protected
  217. * @return bool
  218. */
  219. protected function _close ( ) {
  220. return @fclose($this->getStream());
  221. }
  222. /**
  223. * Start a new buffer.
  224. * The callable acts like a light filter.
  225. *
  226. * @access public
  227. * @param mixed $callable Callable.
  228. * @param int $size Size.
  229. * @return int
  230. */
  231. public function newBuffer ( $callable = null, $size = null ) {
  232. $this->setStreamBuffer($size);
  233. //@TODO manage $callable as a filter?
  234. return 1;
  235. }
  236. /**
  237. * Flush the output to a stream.
  238. *
  239. * @access public
  240. * @return bool
  241. */
  242. public function flush ( ) {
  243. return fflush($this->getStream());
  244. }
  245. /**
  246. * Delete buffer.
  247. *
  248. * @access public
  249. * @return bool
  250. */
  251. public function deleteBuffer ( ) {
  252. return $this->disableStreamBuffer();
  253. }
  254. /**
  255. * Get bufffer level.
  256. *
  257. * @access public
  258. * @return int
  259. */
  260. public function getBufferLevel ( ) {
  261. return 1;
  262. }
  263. /**
  264. * Get buffer size.
  265. *
  266. * @access public
  267. * @return int
  268. */
  269. public function getBufferSize ( ) {
  270. return $this->getStreamBufferSize();
  271. }
  272. /**
  273. * Portable advisory locking.
  274. *
  275. * @access public
  276. * @param int $operation Operation, use the
  277. * \Hoa\Stream\IStream\Lockable::LOCK_* constants.
  278. * @return bool
  279. */
  280. public function lock ( $operation ) {
  281. return flock($this->getStream(), $operation);
  282. }
  283. /**
  284. * Rewind the position of a stream pointer.
  285. *
  286. * @access public
  287. * @return bool
  288. */
  289. public function rewind ( ) {
  290. return rewind($this->getStream());
  291. }
  292. /**
  293. * Seek on a stream pointer.
  294. *
  295. * @access public
  296. * @param int $offset Offset (negative value should be supported).
  297. * @param int $whence Whence, use the
  298. * \Hoa\Stream\IStream\Pointable::SEEK_* constants.
  299. * @return int
  300. */
  301. public function seek ( $offset, $whence = \Hoa\Stream\IStream\Pointable::SEEK_SET ) {
  302. return fseek($this->getStream(), $offset, $whence);
  303. }
  304. /**
  305. * Get the current position of the stream pointer.
  306. *
  307. * @access public
  308. * @return int
  309. */
  310. public function tell ( ) {
  311. $stream = $this->getStream();
  312. if(null === $stream)
  313. return 0;
  314. return ftell($stream);
  315. }
  316. /**
  317. * Create a file.
  318. *
  319. * @access public
  320. * @param string $name File name.
  321. * @param mixed $dummy To be compatible with childs.
  322. * @return bool
  323. */
  324. public static function create ( $name, $dummy ) {
  325. if(file_exists($name))
  326. return true;
  327. return touch($name);
  328. }
  329. }
  330. }