PageRenderTime 44ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

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

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