diff -r 5b37998e522e -r 162c1de6545a web/lib/Zend/Search/Lucene/Storage/File/Memory.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/lib/Zend/Search/Lucene/Storage/File/Memory.php Fri Mar 11 15:05:35 2011 +0100 @@ -0,0 +1,601 @@ +_data = $data; + } + + /** + * Reads $length number of bytes at the current position in the + * file and advances the file pointer. + * + * @param integer $length + * @return string + */ + protected function _fread($length = 1) + { + $returnValue = substr($this->_data, $this->_position, $length); + $this->_position += $length; + return $returnValue; + } + + + /** + * 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) + { + switch ($whence) { + case SEEK_SET: + $this->_position = $offset; + break; + + case SEEK_CUR: + $this->_position += $offset; + break; + + case SEEK_END: + $this->_position = strlen($this->_data); + $this->_position += $offset; + break; + + default: + break; + } + } + + /** + * Get file position. + * + * @return integer + */ + public function tell() + { + return $this->_position; + } + + /** + * Flush output. + * + * Returns true on success or false on failure. + * + * @return boolean + */ + public function flush() + { + // Do nothing + + return true; + } + + /** + * 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) + { + // We do not need to check if file position points to the end of "file". + // Only append operation is supported now + + if ($length !== null) { + $this->_data .= substr($data, 0, $length); + } else { + $this->_data .= $data; + } + + $this->_position = strlen($this->_data); + } + + /** + * Lock file + * + * Lock type may be a LOCK_SH (shared lock) or a LOCK_EX (exclusive lock) + * + * @param integer $lockType + * @return boolean + */ + public function lock($lockType, $nonBlockinLock = false) + { + // Memory files can't be shared + // do nothing + + return true; + } + + /** + * Unlock file + */ + public function unlock() + { + // Memory files can't be shared + // do nothing + } + + /** + * Reads a byte from the current position in the file + * and advances the file pointer. + * + * @return integer + */ + public function readByte() + { + return ord($this->_data[$this->_position++]); + } + + /** + * Writes a byte to the end of the file. + * + * @param integer $byte + */ + public function writeByte($byte) + { + // We do not need to check if file position points to the end of "file". + // Only append operation is supported now + + $this->_data .= chr($byte); + $this->_position = strlen($this->_data); + + return 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) + { + $returnValue = substr($this->_data, $this->_position, $num); + $this->_position += $num; + + return $returnValue; + } + + /** + * Writes num bytes of data (all, if $num===null) to the end + * of the string. + * + * @param string $data + * @param integer $num + */ + public function writeBytes($data, $num=null) + { + // We do not need to check if file position points to the end of "file". + // Only append operation is supported now + + if ($num !== null) { + $this->_data .= substr($data, 0, $num); + } else { + $this->_data .= $data; + } + + $this->_position = strlen($this->_data); + } + + + /** + * Reads an integer from the current position in the file + * and advances the file pointer. + * + * @return integer + */ + public function readInt() + { + $str = substr($this->_data, $this->_position, 4); + $this->_position += 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) + { + // We do not need to check if file position points to the end of "file". + // Only append operation is supported now + + settype($value, 'integer'); + $this->_data .= chr($value>>24 & 0xFF) . + chr($value>>16 & 0xFF) . + chr($value>>8 & 0xFF) . + chr($value & 0xFF); + + $this->_position = strlen($this->_data); + } + + + /** + * Returns a long integer from the current position in the file + * and advances the file pointer. + * + * @return integer + * @throws Zend_Search_Lucene_Exception + */ + public function readLong() + { + /** + * Check, that we work in 64-bit mode. + * fseek() uses long for offset. Thus, largest index segment file size in 32bit mode is 2Gb + */ + if (PHP_INT_SIZE > 4) { + $str = substr($this->_data, $this->_position, 8); + $this->_position += 8; + + 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]); + } else { + return $this->readLong32Bit(); + } + } + + /** + * Writes long integer to the end of file + * + * @param integer $value + * @throws Zend_Search_Lucene_Exception + */ + public function writeLong($value) + { + // We do not need to check if file position points to the end of "file". + // Only append operation is supported now + + /** + * Check, that we work in 64-bit mode. + * fseek() and ftell() use long for offset. Thus, largest index segment file size in 32bit mode is 2Gb + */ + if (PHP_INT_SIZE > 4) { + settype($value, 'integer'); + $this->_data .= chr($value>>56 & 0xFF) . + chr($value>>48 & 0xFF) . + chr($value>>40 & 0xFF) . + chr($value>>32 & 0xFF) . + chr($value>>24 & 0xFF) . + chr($value>>16 & 0xFF) . + chr($value>>8 & 0xFF) . + chr($value & 0xFF); + } else { + $this->writeLong32Bit($value); + } + + $this->_position = strlen($this->_data); + } + + + /** + * Returns a long integer from the current position in the file, + * advances the file pointer and return it as float (for 32-bit platforms). + * + * @return integer|float + * @throws Zend_Search_Lucene_Exception + */ + public function readLong32Bit() + { + $wordHigh = $this->readInt(); + $wordLow = $this->readInt(); + + if ($wordHigh & (int)0x80000000) { + // It's a negative value since the highest bit is set + if ($wordHigh == (int)0xFFFFFFFF && ($wordLow & (int)0x80000000)) { + return $wordLow; + } else { + require_once 'Zend/Search/Lucene/Exception.php'; + throw new Zend_Search_Lucene_Exception('Long integers lower than -2147483648 (0x80000000) are not supported on 32-bit platforms.'); + } + + } + + if ($wordLow < 0) { + // Value is large than 0x7FFF FFFF. Represent low word as float. + $wordLow &= 0x7FFFFFFF; + $wordLow += (float)0x80000000; + } + + if ($wordHigh == 0) { + // Return value as integer if possible + return $wordLow; + } + + return $wordHigh*(float)0x100000000/* 0x00000001 00000000 */ + $wordLow; + } + + + /** + * Writes long integer to the end of file (32-bit platforms implementation) + * + * @param integer|float $value + * @throws Zend_Search_Lucene_Exception + */ + public function writeLong32Bit($value) + { + if ($value < (int)0x80000000) { + require_once 'Zend/Search/Lucene/Exception.php'; + throw new Zend_Search_Lucene_Exception('Long integers lower than -2147483648 (0x80000000) are not supported on 32-bit platforms.'); + } + + if ($value < 0) { + $wordHigh = (int)0xFFFFFFFF; + $wordLow = (int)$value; + } else { + $wordHigh = (int)($value/(float)0x100000000/* 0x00000001 00000000 */); + $wordLow = $value - $wordHigh*(float)0x100000000/* 0x00000001 00000000 */; + + if ($wordLow > 0x7FFFFFFF) { + // Highest bit of low word is set. Translate it to the corresponding negative integer value + $wordLow -= 0x80000000; + $wordLow |= 0x80000000; + } + } + + $this->writeInt($wordHigh); + $this->writeInt($wordLow); + } + + /** + * 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->_data[$this->_position++]); + $val = $nextByte & 0x7F; + + for ($shift=7; ($nextByte & 0x80) != 0; $shift += 7) { + $nextByte = ord($this->_data[$this->_position++]); + $val |= ($nextByte & 0x7F) << $shift; + } + return $val; + } + + /** + * Writes a variable-length integer to the end of file. + * + * @param integer $value + */ + public function writeVInt($value) + { + // We do not need to check if file position points to the end of "file". + // Only append operation is supported now + + settype($value, 'integer'); + while ($value > 0x7F) { + $this->_data .= chr( ($value & 0x7F)|0x80 ); + $value >>= 7; + } + $this->_data .= chr($value); + + $this->_position = strlen($this->_data); + } + + + /** + * 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 = substr($this->_data, $this->_position, $strlen); + $this->_position += $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 .= substr($this->_data, $this->_position, $addBytes); + $this->_position += $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. + */ + + // We do not need to check if file position points to the end of "file". + // Only append operation is supported now + + // 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) { + require_once 'Zend/Search/Lucene/Exception.php'; + throw new Zend_Search_Lucene_Exception('Invalid UTF-8 string'); + } + + $this->writeVInt($chars); + if ($containNullChars) { + $this->_data .= str_replace($str, "\x00", "\xC0\x80"); + + } else { + $this->_data .= $str; + } + + $this->_position = strlen($this->_data); + } + + + /** + * Reads binary data from the current position in the file + * and advances the file pointer. + * + * @return string + */ + public function readBinary() + { + $length = $this->readVInt(); + $returnValue = substr($this->_data, $this->_position, $length); + $this->_position += $length; + return $returnValue; + } +} +