From f4de82bcdafba51e4eed9cae6b2d3e5375ffd115 Mon Sep 17 00:00:00 2001 From: xue <> Date: Tue, 9 May 2006 12:11:38 +0000 Subject: --- .../index/Zend/Search/Lucene/Storage/Directory.php | 118 +++++++ .../Search/Lucene/Storage/Directory/Filesystem.php | 269 +++++++++++++++ .../index/Zend/Search/Lucene/Storage/File.php | 376 +++++++++++++++++++++ .../Zend/Search/Lucene/Storage/File/Filesystem.php | 170 ++++++++++ 4 files changed, 933 insertions(+) create mode 100644 demos/quickstart/protected/index/Zend/Search/Lucene/Storage/Directory.php create mode 100644 demos/quickstart/protected/index/Zend/Search/Lucene/Storage/Directory/Filesystem.php create mode 100644 demos/quickstart/protected/index/Zend/Search/Lucene/Storage/File.php create mode 100644 demos/quickstart/protected/index/Zend/Search/Lucene/Storage/File/Filesystem.php (limited to 'demos/quickstart/protected/index/Zend/Search/Lucene/Storage') diff --git a/demos/quickstart/protected/index/Zend/Search/Lucene/Storage/Directory.php b/demos/quickstart/protected/index/Zend/Search/Lucene/Storage/Directory.php new file mode 100644 index 00000000..48114a76 --- /dev/null +++ b/demos/quickstart/protected/index/Zend/Search/Lucene/Storage/Directory.php @@ -0,0 +1,118 @@ + Zend_Search_Lucene_Storage_File object + * + * @var array + * @throws Zend_Search_Lucene_Exception + */ + private $_fileHandlers; + + + /** + * Utility function to recursive directory creation + * + * @param string $dir + * @param integer $mode + * @param boolean $recursive + * @return boolean + */ + + static public function mkdirs($dir, $mode = 0777, $recursive = true) + { + if (is_null($dir) || $dir === '') { + return false; + } + if (is_dir($dir) || $dir === '/') { + return true; + } + if (self::mkdirs(dirname($dir), $mode, $recursive)) { + return mkdir($dir, $mode); + } + return false; + } + + + /** + * Object constructor + * Checks if $path is a directory or tries to create it. + * + * @param string $path + * @throws Zend_Search_Lucene_Exception + */ + public function __construct($path) + { + if (!is_dir($path)) { + if (file_exists($path)) { + throw new Zend_Search_Lucene_Exception('Path exists, but it\'s not a directory'); + } else { + if (!self::mkdirs($path)) { + throw new Zend_Search_Lucene_Exception("Can't create directory '$path'."); + } + } + } + $this->_dirPath = $path; + $this->_fileHandlers = array(); + } + + + /** + * Closes the store. + * + * @return void + */ + public function close() + { + foreach ($this->_fileHandlers as $fileObject) { + $fileObject->close(); + } + + unset($this->_fileHandlers); + } + + + /** + * Returns an array of strings, one for each file in the directory. + * + * @return array + */ + public function fileList() + { + $result = array(); + + $dirContent = opendir( $this->_dirPath ); + while ($file = readdir($dirContent)) { + if (($file == '..')||($file == '.')) continue; + + $fullName = $this->_dirPath . '/' . $file; + + if( !is_dir($this->_dirPath . '/' . $file) ) { + $result[] = $file; + } + } + + return $result; + } + + /** + * Creates a new, empty file in the directory with the given $filename. + * + * @param string $filename + * @return Zend_Search_Lucene_Storage_File + */ + public function createFile($filename) + { + if (isset($this->_fileHandlers[$filename])) { + $this->_fileHandlers[$filename]->close(); + } + unset($this->_fileHandlers[$filename]); + $this->_fileHandlers[$filename] = new Zend_Search_Lucene_Storage_File_Filesystem($this->_dirPath . '/' . $filename, 'w+b'); + return $this->_fileHandlers[$filename]; + } + + + /** + * Removes an existing $filename in the directory. + * + * @param string $filename + * @return void + */ + public function deleteFile($filename) + { + if (isset($this->_fileHandlers[$filename])) { + $this->_fileHandlers[$filename]->close(); + } + unset($this->_fileHandlers[$filename]); + unlink($this->_dirPath .'/'. $filename); + } + + + /** + * Returns true if a file with the given $filename exists. + * + * @param string $filename + * @return boolean + */ + public function fileExists($filename) + { + return file_exists($this->_dirPath .'/'. $filename); + } + + + /** + * Returns the length of a $filename in the directory. + * + * @param string $filename + * @return integer + */ + public function fileLength($filename) + { + if (isset( $this->_fileHandlers[$filename] )) { + return $this->_fileHandlers[$filename]->size(); + } + return filesize($this->_dirPath .'/'. $filename); + } + + + /** + * Returns the UNIX timestamp $filename was last modified. + * + * @param string $filename + * @return integer + */ + public function fileModified($filename) + { + return filemtime($this->_dirPath .'/'. $filename); + } + + + /** + * Renames an existing file in the directory. + * + * @param string $from + * @param string $to + * @return void + */ + public function renameFile($from, $to) + { + if ($this->_fileHandlers[$from] !== null) { + $this->_fileHandlers[$from]->close(); + } + unset($this->_fileHandlers[$from]); + + if ($this->_fileHandlers[$to] !== null) { + $this->_fileHandlers[$to]->close(); + } + unset($this->_fileHandlers[$to]); + + if (file_exists($this->_dirPath . '/' . $to)) { + unlink($this->_dirPath . '/' . $to); + } + + return @rename($this->_dirPath . '/' . $from, $this->_dirPath . '/' . $to); + } + + + /** + * Sets the modified time of $filename to now. + * + * @param string $filename + * @return void + */ + public function touchFile($filename) + { + return touch($this->_dirPath .'/'. $filename); + } + + + /** + * Returns a Zend_Search_Lucene_Storage_File object for a given $filename in the directory. + * + * @param string $filename + * @return Zend_Search_Lucene_Storage_File + */ + public function getFileObject($filename) + { + if (isset( $this->_fileHandlers[$filename] )) { + $this->_fileHandlers[$filename]->seek(0); + return $this->_fileHandlers[$filename]; + } + + $this->_fileHandlers[$filename] = new Zend_Search_Lucene_Storage_File_Filesystem($this->_dirPath . '/' . $filename, 'rb'); + return $this->_fileHandlers[$filename]; + } +} + diff --git a/demos/quickstart/protected/index/Zend/Search/Lucene/Storage/File.php b/demos/quickstart/protected/index/Zend/Search/Lucene/Storage/File.php new file mode 100644 index 00000000..f62af33a --- /dev/null +++ b/demos/quickstart/protected/index/Zend/Search/Lucene/Storage/File.php @@ -0,0 +1,376 @@ +_fread(1)); + } + + /** + * Writes a byte to the end of the file. + * + * @param integer $byte + */ + public function writeByte($byte) + { + return $this->_fwrite(chr($byte), 1); + } + + /** + * Read num bytes from the current position in the file + * and advances the file pointer. + * + * @param integer $num + * @return string + */ + public function readBytes($num) + { + return $this->_fread($num); + } + + /** + * Writes num bytes of data (all, if $num===null) to the end + * of the file. + * + * @param string $data + * @param integer $num + */ + public function writeBytes($data, $num=null) + { + $this->_fwrite($data, $num); + } + + + /** + * Reads an integer from the current position in the file + * and advances the file pointer. + * + * @return integer + */ + public function readInt() + { + $str = $this->_fread(4); + + return ord($str{0}) << 24 | + ord($str{1}) << 16 | + ord($str{2}) << 8 | + ord($str{3}); + } + + + /** + * Writes an integer to the end of file. + * + * @param integer $value + */ + public function writeInt($value) + { + settype($value, 'integer'); + $this->_fwrite( chr($value>>24 & 0xFF) . + chr($value>>16 & 0xFF) . + chr($value>>8 & 0xFF) . + chr($value & 0xFF), 4 ); + } + + + /** + * Returns a long integer from the current position in the file + * and advances the file pointer. + * + * @return integer + */ + public function readLong() + { + $str = $this->_fread(8); + + /** + * PHP uses long as largest integer. fseek() uses long for offset. + * long has 4 bytes in a lot of systems. 4 bytes are discarded to prevent + * conversion to float. + * So, largest index segment file is 2Gb + */ + return /* ord($str{0}) << 56 | */ + /* ord($str{1}) << 48 | */ + /* ord($str{2}) << 40 | */ + /* ord($str{3}) << 32 | */ + ord($str{4}) << 24 | + ord($str{5}) << 16 | + ord($str{6}) << 8 | + ord($str{7}); + } + + /** + * Writes long integer to the end of file + * + * @param integer $value + */ + public function writeLong($value) + { + /** + * PHP uses long as largest integer. fseek() uses long for offset. + * long has 4 bytes in a lot of systems. 4 bytes are discarded to prevent + * conversion to float. + * So, largest index segment file is 2Gb + */ + settype($value, 'integer'); + $this->_fwrite( "\x00\x00\x00\x00" . + chr($value>>24 & 0xFF) . + chr($value>>16 & 0xFF) . + chr($value>>8 & 0xFF) . + chr($value & 0xFF), 8 ); + } + + + + /** + * Returns a variable-length integer from the current + * position in the file and advances the file pointer. + * + * @return integer + */ + public function readVInt() + { + $nextByte = ord($this->_fread(1)); + $val = $nextByte & 0x7F; + + for ($shift=7; ($nextByte & 0x80) != 0; $shift += 7) { + $nextByte = ord($this->_fread(1)); + $val |= ($nextByte & 0x7F) << $shift; + } + return $val; + } + + /** + * Writes a variable-length integer to the end of file. + * + * @param integer $value + */ + public function writeVInt($value) + { + settype($value, 'integer'); + while ($value > 0x7F) { + $this->_fwrite(chr( ($value & 0x7F)|0x80 )); + $value >>= 7; + } + $this->_fwrite(chr($value)); + } + + + /** + * Reads a string from the current position in the file + * and advances the file pointer. + * + * @return string + */ + public function readString() + { + $strlen = $this->readVInt(); + if ($strlen == 0) { + return ''; + } else { + /** + * This implementation supports only Basic Multilingual Plane + * (BMP) characters (from 0x0000 to 0xFFFF) and doesn't support + * "supplementary characters" (characters whose code points are + * greater than 0xFFFF) + * Java 2 represents these characters as a pair of char (16-bit) + * values, the first from the high-surrogates range (0xD800-0xDBFF), + * the second from the low-surrogates range (0xDC00-0xDFFF). Then + * they are encoded as usual UTF-8 characters in six bytes. + * Standard UTF-8 representation uses four bytes for supplementary + * characters. + */ + + $str_val = $this->_fread($strlen); + + for ($count = 0; $count < $strlen; $count++ ) { + if (( ord($str_val{$count}) & 0xC0 ) == 0xC0) { + $addBytes = 1; + if (ord($str_val{$count}) & 0x20 ) { + $addBytes++; + + // Never used. Java2 doesn't encode strings in four bytes + if (ord($str_val{$count}) & 0x10 ) { + $addBytes++; + } + } + $str_val .= $this->_fread($addBytes); + $strlen += $addBytes; + + // Check for null character. Java2 encodes null character + // in two bytes. + if (ord($str_val{$count}) == 0xC0 && + ord($str_val{$count+1}) == 0x80 ) { + $str_val{$count} = 0; + $str_val = substr($str_val,0,$count+1) + . substr($str_val,$count+2); + } + $count += $addBytes; + } + } + + return $str_val; + } + } + + /** + * Writes a string to the end of file. + * + * @param string $str + * @throws Zend_Search_Lucene_Exception + */ + public function writeString($str) + { + /** + * This implementation supports only Basic Multilingual Plane + * (BMP) characters (from 0x0000 to 0xFFFF) and doesn't support + * "supplementary characters" (characters whose code points are + * greater than 0xFFFF) + * Java 2 represents these characters as a pair of char (16-bit) + * values, the first from the high-surrogates range (0xD800-0xDBFF), + * the second from the low-surrogates range (0xDC00-0xDFFF). Then + * they are encoded as usual UTF-8 characters in six bytes. + * Standard UTF-8 representation uses four bytes for supplementary + * characters. + */ + + // convert input to a string before iterating string characters + settype($str, 'string'); + + $chars = $strlen = strlen($str); + $containNullChars = false; + + for ($count = 0; $count < $strlen; $count++ ) { + /** + * String is already in Java 2 representation. + * We should only calculate actual string length and replace + * \x00 by \xC0\x80 + */ + if ((ord($str{$count}) & 0xC0) == 0xC0) { + $addBytes = 1; + if (ord($str{$count}) & 0x20 ) { + $addBytes++; + + // Never used. Java2 doesn't encode strings in four bytes + // and we dont't support non-BMP characters + if (ord($str{$count}) & 0x10 ) { + $addBytes++; + } + } + $chars -= $addBytes; + + if (ord($str{$count}) == 0 ) { + $containNullChars = true; + } + $count += $addBytes; + } + } + + if ($chars < 0) { + throw new Zend_Search_Lucene_Exception('Invalid UTF-8 string'); + } + + $this->writeVInt($chars); + if ($containNullChars) { + $this->_fwrite(str_replace($str, "\x00", "\xC0\x80")); + } else { + $this->_fwrite($str); + } + } + + + /** + * Reads binary data from the current position in the file + * and advances the file pointer. + * + * @return string + */ + public function readBinary() + { + return $this->_fread($this->readVInt()); + } +} \ No newline at end of file diff --git a/demos/quickstart/protected/index/Zend/Search/Lucene/Storage/File/Filesystem.php b/demos/quickstart/protected/index/Zend/Search/Lucene/Storage/File/Filesystem.php new file mode 100644 index 00000000..fc6adcf5 --- /dev/null +++ b/demos/quickstart/protected/index/Zend/Search/Lucene/Storage/File/Filesystem.php @@ -0,0 +1,170 @@ +_fileHandle = @fopen($filename, $mode); + + if ($this->_fileHandle===false) { + ini_set('track_errors', $trackErrors); + throw new Zend_Search_Lucene_Exception($php_errormsg); + } + + ini_set('track_errors', $trackErrors); + } + + + /** + * Sets the file position indicator and advances the file pointer. + * The new position, measured in bytes from the beginning of the file, + * is obtained by adding offset to the position specified by whence, + * whose values are defined as follows: + * SEEK_SET - Set position equal to offset bytes. + * SEEK_CUR - Set position to current location plus offset. + * SEEK_END - Set position to end-of-file plus offset. (To move to + * a position before the end-of-file, you need to pass a negative value + * in offset.) + * Upon success, returns 0; otherwise, returns -1 + * + * @param integer $offset + * @param integer $whence + * @return integer + */ + public function seek($offset, $whence=SEEK_SET) + { + return fseek($this->_fileHandle, $offset, $whence); + } + + + /** + * Get file position. + * + * @return integer + */ + public function tell() + { + return ftell($this->_fileHandle); + } + + + /** + * Close File object + */ + public function close() + { + if ($this->_fileHandle !== null ) { + @fclose($this->_fileHandle); + $this->_fileHandle = null; + } + } + + /** + * Get the size of the already opened file + * + * @return integer + */ + public function size() + { + $position = ftell($this->_fileHandle); + fseek($this->_fileHandle, 0, SEEK_END); + $size = ftell($this->_fileHandle); + fseek($this->_fileHandle,$position); + + return $size; + } + + /** + * Read a $length bytes from the file and advance the file pointer. + * + * @param integer $length + * @return string + */ + protected function _fread($length=1) + { + if ($length == 0) { + return ''; + } + + if ($length < 1024) { + return fread($this->_fileHandle, $length); + } + + $data = ''; + while ( $length > 0 && ($nextBlock = fread($this->_fileHandle, $length)) != false ) { + $data .= $nextBlock; + $length -= strlen($nextBlock); + } + return $data; + } + + + /** + * Writes $length number of bytes (all, if $length===null) to the end + * of the file. + * + * @param string $data + * @param integer $length + */ + protected function _fwrite($data, $length=null) + { + if ($length === null ) { + fwrite($this->_fileHandle, $data); + } else { + fwrite($this->_fileHandle, $data, $length); + } + } +} + -- cgit v1.2.3