PageRenderTime 25ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/protected/modules/zendsearch/vendors/Zend/Search/Lucene/Storage/File.php

https://gitlab.com/RonLab1987/YupePlusClear
PHP | 473 lines | 209 code | 46 blank | 218 comment | 40 complexity | 7a9c872aa37d5d71dcddea6abd1d57ad 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(
  155. chr($value >> 24 & 0xFF) .
  156. chr($value >> 16 & 0xFF) .
  157. chr($value >> 8 & 0xFF) .
  158. chr($value & 0xFF),
  159. 4
  160. );
  161. }
  162. /**
  163. * Returns a long integer from the current position in the file
  164. * and advances the file pointer.
  165. *
  166. * @return integer|float
  167. * @throws Zend_Search_Lucene_Exception
  168. */
  169. public function readLong()
  170. {
  171. /**
  172. * Check, that we work in 64-bit mode.
  173. * fseek() uses long for offset. Thus, largest index segment file size in 32bit mode is 2Gb
  174. */
  175. if (PHP_INT_SIZE > 4) {
  176. $str = $this->_fread(8);
  177. return ord($str[0]) << 56 |
  178. ord($str[1]) << 48 |
  179. ord($str[2]) << 40 |
  180. ord($str[3]) << 32 |
  181. ord($str[4]) << 24 |
  182. ord($str[5]) << 16 |
  183. ord($str[6]) << 8 |
  184. ord($str[7]);
  185. } else {
  186. return $this->readLong32Bit();
  187. }
  188. }
  189. /**
  190. * Writes long integer to the end of file
  191. *
  192. * @param integer $value
  193. * @throws Zend_Search_Lucene_Exception
  194. */
  195. public function writeLong($value)
  196. {
  197. /**
  198. * Check, that we work in 64-bit mode.
  199. * fseek() and ftell() use long for offset. Thus, largest index segment file size in 32bit mode is 2Gb
  200. */
  201. if (PHP_INT_SIZE > 4) {
  202. settype($value, 'integer');
  203. $this->_fwrite(
  204. chr($value >> 56 & 0xFF) .
  205. chr($value >> 48 & 0xFF) .
  206. chr($value >> 40 & 0xFF) .
  207. chr($value >> 32 & 0xFF) .
  208. chr($value >> 24 & 0xFF) .
  209. chr($value >> 16 & 0xFF) .
  210. chr($value >> 8 & 0xFF) .
  211. chr($value & 0xFF),
  212. 8
  213. );
  214. } else {
  215. $this->writeLong32Bit($value);
  216. }
  217. }
  218. /**
  219. * Returns a long integer from the current position in the file,
  220. * advances the file pointer and return it as float (for 32-bit platforms).
  221. *
  222. * @return integer|float
  223. * @throws Zend_Search_Lucene_Exception
  224. */
  225. public function readLong32Bit()
  226. {
  227. $wordHigh = $this->readInt();
  228. $wordLow = $this->readInt();
  229. if ($wordHigh & (int)0x80000000) {
  230. // It's a negative value since the highest bit is set
  231. if ($wordHigh == (int)0xFFFFFFFF && ($wordLow & (int)0x80000000)) {
  232. return $wordLow;
  233. } else {
  234. require_once 'Zend/Search/Lucene/Exception.php';
  235. throw new Zend_Search_Lucene_Exception('Long integers lower than -2147483648 (0x80000000) are not supported on 32-bit platforms.');
  236. }
  237. }
  238. if ($wordLow < 0) {
  239. // Value is large than 0x7FFF FFFF. Represent low word as float.
  240. $wordLow &= 0x7FFFFFFF;
  241. $wordLow += (float)0x80000000;
  242. }
  243. if ($wordHigh == 0) {
  244. // Return value as integer if possible
  245. return $wordLow;
  246. }
  247. return $wordHigh * (float)0x100000000 /* 0x00000001 00000000 */ + $wordLow;
  248. }
  249. /**
  250. * Writes long integer to the end of file (32-bit platforms implementation)
  251. *
  252. * @param integer|float $value
  253. * @throws Zend_Search_Lucene_Exception
  254. */
  255. public function writeLong32Bit($value)
  256. {
  257. if ($value < (int)0x80000000) {
  258. require_once 'Zend/Search/Lucene/Exception.php';
  259. throw new Zend_Search_Lucene_Exception('Long integers lower than -2147483648 (0x80000000) are not supported on 32-bit platforms.');
  260. }
  261. if ($value < 0) {
  262. $wordHigh = (int)0xFFFFFFFF;
  263. $wordLow = (int)$value;
  264. } else {
  265. $wordHigh = (int)($value / (float)0x100000000 /* 0x00000001 00000000 */);
  266. $wordLow = $value - $wordHigh * (float)0x100000000 /* 0x00000001 00000000 */
  267. ;
  268. if ($wordLow > 0x7FFFFFFF) {
  269. // Highest bit of low word is set. Translate it to the corresponding negative integer value
  270. $wordLow -= 0x80000000;
  271. $wordLow |= 0x80000000;
  272. }
  273. }
  274. $this->writeInt($wordHigh);
  275. $this->writeInt($wordLow);
  276. }
  277. /**
  278. * Returns a variable-length integer from the current
  279. * position in the file and advances the file pointer.
  280. *
  281. * @return integer
  282. */
  283. public function readVInt()
  284. {
  285. $nextByte = ord($this->_fread(1));
  286. $val = $nextByte & 0x7F;
  287. for ($shift = 7; ($nextByte & 0x80) != 0; $shift += 7) {
  288. $nextByte = ord($this->_fread(1));
  289. $val |= ($nextByte & 0x7F) << $shift;
  290. }
  291. return $val;
  292. }
  293. /**
  294. * Writes a variable-length integer to the end of file.
  295. *
  296. * @param integer $value
  297. */
  298. public function writeVInt($value)
  299. {
  300. settype($value, 'integer');
  301. while ($value > 0x7F) {
  302. $this->_fwrite(chr(($value & 0x7F) | 0x80));
  303. $value >>= 7;
  304. }
  305. $this->_fwrite(chr($value));
  306. }
  307. /**
  308. * Reads a string from the current position in the file
  309. * and advances the file pointer.
  310. *
  311. * @return string
  312. */
  313. public function readString()
  314. {
  315. $strlen = $this->readVInt();
  316. if ($strlen == 0) {
  317. return '';
  318. } else {
  319. /**
  320. * This implementation supports only Basic Multilingual Plane
  321. * (BMP) characters (from 0x0000 to 0xFFFF) and doesn't support
  322. * "supplementary characters" (characters whose code points are
  323. * greater than 0xFFFF)
  324. * Java 2 represents these characters as a pair of char (16-bit)
  325. * values, the first from the high-surrogates range (0xD800-0xDBFF),
  326. * the second from the low-surrogates range (0xDC00-0xDFFF). Then
  327. * they are encoded as usual UTF-8 characters in six bytes.
  328. * Standard UTF-8 representation uses four bytes for supplementary
  329. * characters.
  330. */
  331. $str_val = $this->_fread($strlen);
  332. for ($count = 0; $count < $strlen; $count++) {
  333. if ((ord($str_val[$count]) & 0xC0) == 0xC0) {
  334. $addBytes = 1;
  335. if (ord($str_val[$count]) & 0x20) {
  336. $addBytes++;
  337. // Never used. Java2 doesn't encode strings in four bytes
  338. if (ord($str_val[$count]) & 0x10) {
  339. $addBytes++;
  340. }
  341. }
  342. $str_val .= $this->_fread($addBytes);
  343. $strlen += $addBytes;
  344. // Check for null character. Java2 encodes null character
  345. // in two bytes.
  346. if (ord($str_val[$count]) == 0xC0 &&
  347. ord($str_val[$count + 1]) == 0x80
  348. ) {
  349. $str_val[$count] = 0;
  350. $str_val = substr($str_val, 0, $count + 1)
  351. . substr($str_val, $count + 2);
  352. }
  353. $count += $addBytes;
  354. }
  355. }
  356. return $str_val;
  357. }
  358. }
  359. /**
  360. * Writes a string to the end of file.
  361. *
  362. * @param string $str
  363. * @throws Zend_Search_Lucene_Exception
  364. */
  365. public function writeString($str)
  366. {
  367. /**
  368. * This implementation supports only Basic Multilingual Plane
  369. * (BMP) characters (from 0x0000 to 0xFFFF) and doesn't support
  370. * "supplementary characters" (characters whose code points are
  371. * greater than 0xFFFF)
  372. * Java 2 represents these characters as a pair of char (16-bit)
  373. * values, the first from the high-surrogates range (0xD800-0xDBFF),
  374. * the second from the low-surrogates range (0xDC00-0xDFFF). Then
  375. * they are encoded as usual UTF-8 characters in six bytes.
  376. * Standard UTF-8 representation uses four bytes for supplementary
  377. * characters.
  378. */
  379. // convert input to a string before iterating string characters
  380. settype($str, 'string');
  381. $chars = $strlen = strlen($str);
  382. $containNullChars = false;
  383. for ($count = 0; $count < $strlen; $count++) {
  384. /**
  385. * String is already in Java 2 representation.
  386. * We should only calculate actual string length and replace
  387. * \x00 by \xC0\x80
  388. */
  389. if ((ord($str[$count]) & 0xC0) == 0xC0) {
  390. $addBytes = 1;
  391. if (ord($str[$count]) & 0x20) {
  392. $addBytes++;
  393. // Never used. Java2 doesn't encode strings in four bytes
  394. // and we dont't support non-BMP characters
  395. if (ord($str[$count]) & 0x10) {
  396. $addBytes++;
  397. }
  398. }
  399. $chars -= $addBytes;
  400. if (ord($str[$count]) == 0) {
  401. $containNullChars = true;
  402. }
  403. $count += $addBytes;
  404. }
  405. }
  406. if ($chars < 0) {
  407. require_once 'Zend/Search/Lucene/Exception.php';
  408. throw new Zend_Search_Lucene_Exception('Invalid UTF-8 string');
  409. }
  410. $this->writeVInt($chars);
  411. if ($containNullChars) {
  412. $this->_fwrite(str_replace($str, "\x00", "\xC0\x80"));
  413. } else {
  414. $this->_fwrite($str);
  415. }
  416. }
  417. /**
  418. * Reads binary data from the current position in the file
  419. * and advances the file pointer.
  420. *
  421. * @return string
  422. */
  423. public function readBinary()
  424. {
  425. return $this->_fread($this->readVInt());
  426. }
  427. }