PageRenderTime 47ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/Search/Lucene/Storage/File.php

https://bitbucket.org/hjain/loudmusic
PHP | 473 lines | 201 code | 54 blank | 218 comment | 40 complexity | 843b506475be3fc57cd12af06f3718a7 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Search_Lucene
  17. * @subpackage Storage
  18. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id: File.php 24593 2012-01-05 20:35:02Z matthew $
  21. */
  22. /**
  23. * @category Zend
  24. * @package Zend_Search_Lucene
  25. * @subpackage Storage
  26. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  27. * @license http://framework.zend.com/license/new-bsd New BSD License
  28. */
  29. abstract class Zend_Search_Lucene_Storage_File
  30. {
  31. /**
  32. * Reads $length number of bytes at the current position in the
  33. * file and advances the file pointer.
  34. *
  35. * @param integer $length
  36. * @return string
  37. */
  38. abstract protected function _fread($length=1);
  39. /**
  40. * Sets the file position indicator and advances the file pointer.
  41. * The new position, measured in bytes from the beginning of the file,
  42. * is obtained by adding offset to the position specified by whence,
  43. * whose values are defined as follows:
  44. * SEEK_SET - Set position equal to offset bytes.
  45. * SEEK_CUR - Set position to current location plus offset.
  46. * SEEK_END - Set position to end-of-file plus offset. (To move to
  47. * a position before the end-of-file, you need to pass a negative value
  48. * in offset.)
  49. * Upon success, returns 0; otherwise, returns -1
  50. *
  51. * @param integer $offset
  52. * @param integer $whence
  53. * @return integer
  54. */
  55. abstract public function seek($offset, $whence=SEEK_SET);
  56. /**
  57. * Get file position.
  58. *
  59. * @return integer
  60. */
  61. abstract public function tell();
  62. /**
  63. * Flush output.
  64. *
  65. * Returns true on success or false on failure.
  66. *
  67. * @return boolean
  68. */
  69. abstract public function flush();
  70. /**
  71. * Writes $length number of bytes (all, if $length===null) to the end
  72. * of the file.
  73. *
  74. * @param string $data
  75. * @param integer $length
  76. */
  77. abstract protected function _fwrite($data, $length=null);
  78. /**
  79. * Lock file
  80. *
  81. * Lock type may be a LOCK_SH (shared lock) or a LOCK_EX (exclusive lock)
  82. *
  83. * @param integer $lockType
  84. * @return boolean
  85. */
  86. abstract public function lock($lockType, $nonBlockinLock = false);
  87. /**
  88. * Unlock file
  89. */
  90. abstract public function unlock();
  91. /**
  92. * Reads a byte from the current position in the file
  93. * and advances the file pointer.
  94. *
  95. * @return integer
  96. */
  97. public function readByte()
  98. {
  99. return ord($this->_fread(1));
  100. }
  101. /**
  102. * Writes a byte to the end of the file.
  103. *
  104. * @param integer $byte
  105. */
  106. public function writeByte($byte)
  107. {
  108. return $this->_fwrite(chr($byte), 1);
  109. }
  110. /**
  111. * Read num bytes from the current position in the file
  112. * and advances the file pointer.
  113. *
  114. * @param integer $num
  115. * @return string
  116. */
  117. public function readBytes($num)
  118. {
  119. return $this->_fread($num);
  120. }
  121. /**
  122. * Writes num bytes of data (all, if $num===null) to the end
  123. * of the string.
  124. *
  125. * @param string $data
  126. * @param integer $num
  127. */
  128. public function writeBytes($data, $num=null)
  129. {
  130. $this->_fwrite($data, $num);
  131. }
  132. /**
  133. * Reads an integer from the current position in the file
  134. * and advances the file pointer.
  135. *
  136. * @return integer
  137. */
  138. public function readInt()
  139. {
  140. $str = $this->_fread(4);
  141. return ord($str[0]) << 24 |
  142. ord($str[1]) << 16 |
  143. ord($str[2]) << 8 |
  144. ord($str[3]);
  145. }
  146. /**
  147. * Writes an integer to the end of file.
  148. *
  149. * @param integer $value
  150. */
  151. public function writeInt($value)
  152. {
  153. settype($value, 'integer');
  154. $this->_fwrite( chr($value>>24 & 0xFF) .
  155. chr($value>>16 & 0xFF) .
  156. chr($value>>8 & 0xFF) .
  157. chr($value & 0xFF), 4 );
  158. }
  159. /**
  160. * Returns a long integer from the current position in the file
  161. * and advances the file pointer.
  162. *
  163. * @return integer|float
  164. * @throws Zend_Search_Lucene_Exception
  165. */
  166. public function readLong()
  167. {
  168. /**
  169. * Check, that we work in 64-bit mode.
  170. * fseek() uses long for offset. Thus, largest index segment file size in 32bit mode is 2Gb
  171. */
  172. if (PHP_INT_SIZE > 4) {
  173. $str = $this->_fread(8);
  174. return ord($str[0]) << 56 |
  175. ord($str[1]) << 48 |
  176. ord($str[2]) << 40 |
  177. ord($str[3]) << 32 |
  178. ord($str[4]) << 24 |
  179. ord($str[5]) << 16 |
  180. ord($str[6]) << 8 |
  181. ord($str[7]);
  182. } else {
  183. return $this->readLong32Bit();
  184. }
  185. }
  186. /**
  187. * Writes long integer to the end of file
  188. *
  189. * @param integer $value
  190. * @throws Zend_Search_Lucene_Exception
  191. */
  192. public function writeLong($value)
  193. {
  194. /**
  195. * Check, that we work in 64-bit mode.
  196. * fseek() and ftell() use long for offset. Thus, largest index segment file size in 32bit mode is 2Gb
  197. */
  198. if (PHP_INT_SIZE > 4) {
  199. settype($value, 'integer');
  200. $this->_fwrite( chr($value>>56 & 0xFF) .
  201. chr($value>>48 & 0xFF) .
  202. chr($value>>40 & 0xFF) .
  203. chr($value>>32 & 0xFF) .
  204. chr($value>>24 & 0xFF) .
  205. chr($value>>16 & 0xFF) .
  206. chr($value>>8 & 0xFF) .
  207. chr($value & 0xFF), 8 );
  208. } else {
  209. $this->writeLong32Bit($value);
  210. }
  211. }
  212. /**
  213. * Returns a long integer from the current position in the file,
  214. * advances the file pointer and return it as float (for 32-bit platforms).
  215. *
  216. * @return integer|float
  217. * @throws Zend_Search_Lucene_Exception
  218. */
  219. public function readLong32Bit()
  220. {
  221. $wordHigh = $this->readInt();
  222. $wordLow = $this->readInt();
  223. if ($wordHigh & (int)0x80000000) {
  224. // It's a negative value since the highest bit is set
  225. if ($wordHigh == (int)0xFFFFFFFF && ($wordLow & (int)0x80000000)) {
  226. return $wordLow;
  227. } else {
  228. require_once 'Zend/Search/Lucene/Exception.php';
  229. throw new Zend_Search_Lucene_Exception('Long integers lower than -2147483648 (0x80000000) are not supported on 32-bit platforms.');
  230. }
  231. }
  232. if ($wordLow < 0) {
  233. // Value is large than 0x7FFF FFFF. Represent low word as float.
  234. $wordLow &= 0x7FFFFFFF;
  235. $wordLow += (float)0x80000000;
  236. }
  237. if ($wordHigh == 0) {
  238. // Return value as integer if possible
  239. return $wordLow;
  240. }
  241. return $wordHigh*(float)0x100000000/* 0x00000001 00000000 */ + $wordLow;
  242. }
  243. /**
  244. * Writes long integer to the end of file (32-bit platforms implementation)
  245. *
  246. * @param integer|float $value
  247. * @throws Zend_Search_Lucene_Exception
  248. */
  249. public function writeLong32Bit($value)
  250. {
  251. if ($value < (int)0x80000000) {
  252. require_once 'Zend/Search/Lucene/Exception.php';
  253. throw new Zend_Search_Lucene_Exception('Long integers lower than -2147483648 (0x80000000) are not supported on 32-bit platforms.');
  254. }
  255. if ($value < 0) {
  256. $wordHigh = (int)0xFFFFFFFF;
  257. $wordLow = (int)$value;
  258. } else {
  259. $wordHigh = (int)($value/(float)0x100000000/* 0x00000001 00000000 */);
  260. $wordLow = $value - $wordHigh*(float)0x100000000/* 0x00000001 00000000 */;
  261. if ($wordLow > 0x7FFFFFFF) {
  262. // Highest bit of low word is set. Translate it to the corresponding negative integer value
  263. $wordLow -= 0x80000000;
  264. $wordLow |= 0x80000000;
  265. }
  266. }
  267. $this->writeInt($wordHigh);
  268. $this->writeInt($wordLow);
  269. }
  270. /**
  271. * Returns a variable-length integer from the current
  272. * position in the file and advances the file pointer.
  273. *
  274. * @return integer
  275. */
  276. public function readVInt()
  277. {
  278. $nextByte = ord($this->_fread(1));
  279. $val = $nextByte & 0x7F;
  280. for ($shift=7; ($nextByte & 0x80) != 0; $shift += 7) {
  281. $nextByte = ord($this->_fread(1));
  282. $val |= ($nextByte & 0x7F) << $shift;
  283. }
  284. return $val;
  285. }
  286. /**
  287. * Writes a variable-length integer to the end of file.
  288. *
  289. * @param integer $value
  290. */
  291. public function writeVInt($value)
  292. {
  293. settype($value, 'integer');
  294. while ($value > 0x7F) {
  295. $this->_fwrite(chr( ($value & 0x7F)|0x80 ));
  296. $value >>= 7;
  297. }
  298. $this->_fwrite(chr($value));
  299. }
  300. /**
  301. * Reads a string from the current position in the file
  302. * and advances the file pointer.
  303. *
  304. * @return string
  305. */
  306. public function readString()
  307. {
  308. $strlen = $this->readVInt();
  309. if ($strlen == 0) {
  310. return '';
  311. } else {
  312. /**
  313. * This implementation supports only Basic Multilingual Plane
  314. * (BMP) characters (from 0x0000 to 0xFFFF) and doesn't support
  315. * "supplementary characters" (characters whose code points are
  316. * greater than 0xFFFF)
  317. * Java 2 represents these characters as a pair of char (16-bit)
  318. * values, the first from the high-surrogates range (0xD800-0xDBFF),
  319. * the second from the low-surrogates range (0xDC00-0xDFFF). Then
  320. * they are encoded as usual UTF-8 characters in six bytes.
  321. * Standard UTF-8 representation uses four bytes for supplementary
  322. * characters.
  323. */
  324. $str_val = $this->_fread($strlen);
  325. for ($count = 0; $count < $strlen; $count++ ) {
  326. if (( ord($str_val[$count]) & 0xC0 ) == 0xC0) {
  327. $addBytes = 1;
  328. if (ord($str_val[$count]) & 0x20 ) {
  329. $addBytes++;
  330. // Never used. Java2 doesn't encode strings in four bytes
  331. if (ord($str_val[$count]) & 0x10 ) {
  332. $addBytes++;
  333. }
  334. }
  335. $str_val .= $this->_fread($addBytes);
  336. $strlen += $addBytes;
  337. // Check for null character. Java2 encodes null character
  338. // in two bytes.
  339. if (ord($str_val[$count]) == 0xC0 &&
  340. ord($str_val[$count+1]) == 0x80 ) {
  341. $str_val[$count] = 0;
  342. $str_val = substr($str_val,0,$count+1)
  343. . substr($str_val,$count+2);
  344. }
  345. $count += $addBytes;
  346. }
  347. }
  348. return $str_val;
  349. }
  350. }
  351. /**
  352. * Writes a string to the end of file.
  353. *
  354. * @param string $str
  355. * @throws Zend_Search_Lucene_Exception
  356. */
  357. public function writeString($str)
  358. {
  359. /**
  360. * This implementation supports only Basic Multilingual Plane
  361. * (BMP) characters (from 0x0000 to 0xFFFF) and doesn't support
  362. * "supplementary characters" (characters whose code points are
  363. * greater than 0xFFFF)
  364. * Java 2 represents these characters as a pair of char (16-bit)
  365. * values, the first from the high-surrogates range (0xD800-0xDBFF),
  366. * the second from the low-surrogates range (0xDC00-0xDFFF). Then
  367. * they are encoded as usual UTF-8 characters in six bytes.
  368. * Standard UTF-8 representation uses four bytes for supplementary
  369. * characters.
  370. */
  371. // convert input to a string before iterating string characters
  372. settype($str, 'string');
  373. $chars = $strlen = strlen($str);
  374. $containNullChars = false;
  375. for ($count = 0; $count < $strlen; $count++ ) {
  376. /**
  377. * String is already in Java 2 representation.
  378. * We should only calculate actual string length and replace
  379. * \x00 by \xC0\x80
  380. */
  381. if ((ord($str[$count]) & 0xC0) == 0xC0) {
  382. $addBytes = 1;
  383. if (ord($str[$count]) & 0x20 ) {
  384. $addBytes++;
  385. // Never used. Java2 doesn't encode strings in four bytes
  386. // and we dont't support non-BMP characters
  387. if (ord($str[$count]) & 0x10 ) {
  388. $addBytes++;
  389. }
  390. }
  391. $chars -= $addBytes;
  392. if (ord($str[$count]) == 0 ) {
  393. $containNullChars = true;
  394. }
  395. $count += $addBytes;
  396. }
  397. }
  398. if ($chars < 0) {
  399. require_once 'Zend/Search/Lucene/Exception.php';
  400. throw new Zend_Search_Lucene_Exception('Invalid UTF-8 string');
  401. }
  402. $this->writeVInt($chars);
  403. if ($containNullChars) {
  404. $this->_fwrite(str_replace($str, "\x00", "\xC0\x80"));
  405. } else {
  406. $this->_fwrite($str);
  407. }
  408. }
  409. /**
  410. * Reads binary data from the current position in the file
  411. * and advances the file pointer.
  412. *
  413. * @return string
  414. */
  415. public function readBinary()
  416. {
  417. return $this->_fread($this->readVInt());
  418. }
  419. }