/Workshop3/OpenIdWithTorrents/lib/PHPTracker/File/File.php

https://github.com/oskarp/4ME102 · PHP · 195 lines · 93 code · 24 blank · 78 comment · 8 complexity · 3f0027818d22cc07b8678722999ab913 MD5 · raw file

  1. <?php
  2. /**
  3. * Object providing operations to a physical file on the disk.
  4. *
  5. * @package PHPTracker
  6. * @subpackage File
  7. */
  8. class PHPTracker_File_File
  9. {
  10. /**
  11. * Full path of the file ont eh disk.
  12. *
  13. * @var string
  14. */
  15. protected $path;
  16. /**
  17. * If the file os opened for reading, this contains its read handle.
  18. *
  19. * @var resource
  20. */
  21. protected $read_handle;
  22. /**
  23. * Initializing the object with the file full path.
  24. *
  25. * @throws PHPTracker_File_Error_NotExits If the file does not exists.
  26. * @param string $path
  27. */
  28. public function __construct( $path )
  29. {
  30. $this->path = $path;
  31. $this->shouldExist();
  32. $this->path = realpath( $this->path );
  33. }
  34. /**
  35. * Returnt eh file full path is the object is used as string.
  36. *
  37. * @return string
  38. */
  39. public function __toString()
  40. {
  41. return $this->path;
  42. }
  43. /**
  44. * If the file is open for reading, it's properly closed while destructing.
  45. */
  46. public function __destruct()
  47. {
  48. if ( isset( $this->read_handle ) )
  49. {
  50. fclose( $this->read_handle );
  51. }
  52. }
  53. /**
  54. * Tells if the file exists on the disk.
  55. *
  56. * @return boolean
  57. */
  58. protected function exists()
  59. {
  60. return file_exists( $this->path );
  61. }
  62. /**
  63. * Tells the size of the file in bytes.
  64. *
  65. * @return integer
  66. */
  67. public function size()
  68. {
  69. if ( false === ( $size = @filesize( $this->path ) ) )
  70. {
  71. throw new PHPTracker_File_Error_Unreadable( "File $this is unreadable." );
  72. }
  73. return $size;
  74. }
  75. /**
  76. * Returns the basename of the file.
  77. *
  78. * @return string
  79. */
  80. public function basename()
  81. {
  82. return basename( $this->path );
  83. }
  84. /**
  85. * Generates SHA1 hashes of each piece of the file.
  86. *
  87. * @param integer $size_piece Size of one piece of a file on bytes.
  88. * @return string Byte string of the concatenated SHA1 hashes of each pieces.
  89. */
  90. public function getHashesForPieces( $size_piece )
  91. {
  92. $size_piece = intval( $size_piece );
  93. if ( $size_piece <= 0 )
  94. {
  95. // TODO: Throwing exception?
  96. return null;
  97. }
  98. $c_pieces = ceil( $this->size() / $size_piece );
  99. $hashes = '';
  100. for ( $n_piece = 0; $n_piece < $c_pieces; ++$n_piece )
  101. {
  102. $hashes .= $this->hashPiece( $n_piece, $size_piece );
  103. }
  104. return $hashes;
  105. }
  106. /**
  107. * Reads one arbitrary length chunk of a file beginning from a byte index.
  108. *
  109. * @param integer $begin Where to start reading (bytes).
  110. * @param integer $length How many bytes to read.
  111. * @return string Binary string with the read data.
  112. */
  113. public function readBlock( $begin, $length )
  114. {
  115. $file_handle = $this->getReadHandle();
  116. fseek( $file_handle, $begin );
  117. if ( false === $buffer = @fread( $file_handle , $length ) )
  118. {
  119. throw new PHPTracker_File_Error_Unreadable( "File $this is unreadable." );
  120. }
  121. return $buffer;
  122. }
  123. /**
  124. * Lazy-opens a file for reading and returns its resource.
  125. *
  126. * @throws PHPTracker_File_Error_Unreadable If the file can't be read.
  127. * @return resource
  128. */
  129. protected function getReadHandle()
  130. {
  131. if ( !isset( $this->read_handle ) )
  132. {
  133. $this->read_handle = @fopen( $this->path, 'rb' );
  134. if ( false === $this->read_handle )
  135. {
  136. unset( $this->read_handle );
  137. throw new PHPTracker_File_Error_Unreadable( "File $this is unreadable." );
  138. }
  139. }
  140. return $this->read_handle;
  141. }
  142. /**
  143. * Gets SHA1 hash (binary) of a piece of a file.
  144. *
  145. * @param integer $n_piece 0 bases index of the current peice.
  146. * @param integer $size_piece Generic piece size of the file in bytes.
  147. * @return string Byte string of the SHA1 hash of this piece.
  148. */
  149. protected function hashPiece( $n_piece, $size_piece )
  150. {
  151. $file_handle = $this->getReadHandle();
  152. $hash_handle = hash_init( 'sha1' );
  153. fseek( $file_handle, $n_piece * $size_piece );
  154. hash_update_stream( $hash_handle, $file_handle, $size_piece );
  155. // Getting hash of the piece as raw binary.
  156. return hash_final( $hash_handle, true );
  157. }
  158. /**
  159. * Throws exception if the file does not exist.
  160. *
  161. * @throws PHPTracker_File_Error_NotExits
  162. */
  163. protected function shouldExist()
  164. {
  165. if ( !$this->exists() )
  166. {
  167. throw new PHPTracker_File_Error_NotExits( "File $this does not exist." );
  168. }
  169. }
  170. }
  171. ?>