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

/includes/src/Zend_Search_Lucene_Storage_File_Memory.php

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