diff options
Diffstat (limited to 'includes/Cdb_PHP.php')
-rw-r--r-- | includes/Cdb_PHP.php | 69 |
1 files changed, 49 insertions, 20 deletions
diff --git a/includes/Cdb_PHP.php b/includes/Cdb_PHP.php index f4029ba5..53175272 100644 --- a/includes/Cdb_PHP.php +++ b/includes/Cdb_PHP.php @@ -1,6 +1,6 @@ <?php /** - * This is a port of D.J. Bernstein's CDB to PHP. It's based on the copy that + * This is a port of D.J. Bernstein's CDB to PHP. It's based on the copy that * appears in PHP 5.3. Changes are: * * Error returns replaced with exceptions * * Exception thrown if sizes or offsets are between 2GB and 4GB @@ -50,7 +50,7 @@ class CdbFunctions { /** * The CDB hash function. - * + * * @param $s * * @return @@ -62,7 +62,7 @@ class CdbFunctions { // Do a 32-bit sum // Inlined here for speed $sum = ($h & 0x3fffffff) + ($h5 & 0x3fffffff); - $h = + $h = ( ( $sum & 0x40000000 ? 1 : 0 ) + ( $h & 0x80000000 ? 2 : 0 ) @@ -82,6 +82,9 @@ class CdbFunctions { * CDB reader class */ class CdbReader_PHP extends CdbReader { + /** The filename */ + var $fileName; + /** The file handle */ var $handle; @@ -104,12 +107,16 @@ class CdbReader_PHP extends CdbReader { var $dpos; /* initialized if cdb_findnext() returns 1 */ - var $dlen; + var $dlen; + /** + * @param $fileName string + */ function __construct( $fileName ) { + $this->fileName = $fileName; $this->handle = fopen( $fileName, 'rb' ); if ( !$this->handle ) { - throw new MWException( 'Unable to open CDB file "' . $fileName . '"' ); + throw new MWException( 'Unable to open CDB file "' . $this->fileName . '".' ); } $this->findStart(); } @@ -157,7 +164,8 @@ class CdbReader_PHP extends CdbReader { protected function read( $length, $pos ) { if ( fseek( $this->handle, $pos ) == -1 ) { // This can easily happen if the internal pointers are incorrect - throw new MWException( __METHOD__.': seek failed, file may be corrupted.' ); + throw new MWException( + 'Seek failed, file "' . $this->fileName . '" may be corrupted.' ); } if ( $length == 0 ) { @@ -166,7 +174,8 @@ class CdbReader_PHP extends CdbReader { $buf = fread( $this->handle, $length ); if ( $buf === false || strlen( $buf ) !== $length ) { - throw new MWException( __METHOD__.': read from CDB file failed, file may be corrupted' ); + throw new MWException( + 'Read from CDB file failed, file "' . $this->fileName . '" may be corrupted.' ); } return $buf; } @@ -179,7 +188,8 @@ class CdbReader_PHP extends CdbReader { protected function unpack31( $s ) { $data = unpack( 'V', $s ); if ( $data[1] > 0x7fffffff ) { - throw new MWException( __METHOD__.': error in CDB file, integer too big' ); + throw new MWException( + 'Error in CDB file "' . $this->fileName . '", integer too big.' ); } return $data[1]; } @@ -257,20 +267,24 @@ class CdbWriter_PHP extends CdbWriter { var $handle, $realFileName, $tmpFileName; var $hplist; - var $numEntries, $pos; + var $numentries, $pos; + /** + * @param $fileName string + */ function __construct( $fileName ) { $this->realFileName = $fileName; $this->tmpFileName = $fileName . '.tmp.' . mt_rand( 0, 0x7fffffff ); $this->handle = fopen( $this->tmpFileName, 'wb' ); if ( !$this->handle ) { - throw new MWException( 'Unable to open CDB file for write "' . $fileName . '"' ); + $this->throwException( + 'Unable to open CDB file "' . $this->tmpFileName . '" for write.' ); } $this->hplist = array(); $this->numentries = 0; $this->pos = 2048; // leaving space for the pointer array, 256 * 8 if ( fseek( $this->handle, $this->pos ) == -1 ) { - throw new MWException( __METHOD__.': fseek failed' ); + $this->throwException( 'fseek failed in file "' . $this->tmpFileName . '".' ); } } @@ -308,7 +322,7 @@ class CdbWriter_PHP extends CdbWriter { unlink( $this->realFileName ); } if ( !rename( $this->tmpFileName, $this->realFileName ) ) { - throw new MWException( 'Unable to move the new CDB file into place.' ); + $this->throwException( 'Unable to move the new CDB file into place.' ); } unset( $this->handle ); } @@ -320,7 +334,7 @@ class CdbWriter_PHP extends CdbWriter { protected function write( $buf ) { $len = fwrite( $this->handle, $buf ); if ( $len !== strlen( $buf ) ) { - throw new MWException( 'Error writing to CDB file.' ); + $this->throwException( 'Error writing to CDB file "'.$this->tmpFileName.'".' ); } } @@ -331,7 +345,8 @@ class CdbWriter_PHP extends CdbWriter { protected function posplus( $len ) { $newpos = $this->pos + $len; if ( $newpos > 0x7fffffff ) { - throw new MWException( 'A value in the CDB file is too large' ); + $this->throwException( + 'A value in the CDB file "'.$this->tmpFileName.'" is too large.' ); } $this->pos = $newpos; } @@ -360,10 +375,10 @@ class CdbWriter_PHP extends CdbWriter { */ protected function addbegin( $keylen, $datalen ) { if ( $keylen > 0x7fffffff ) { - throw new MWException( __METHOD__.': key length too long' ); + $this->throwException( 'Key length too long in file "'.$this->tmpFileName.'".' ); } if ( $datalen > 0x7fffffff ) { - throw new MWException( __METHOD__.': data length too long' ); + $this->throwException( 'Data length too long in file "'.$this->tmpFileName.'".' ); } $buf = pack( 'VV', $keylen, $datalen ); $this->write( $buf ); @@ -391,7 +406,7 @@ class CdbWriter_PHP extends CdbWriter { } // Excessively clever and indulgent code to simultaneously fill $packedTables - // with the packed hashtables, and adjust the elements of $starts + // with the packed hashtables, and adjust the elements of $starts // to actually point to the starts instead of the ends. $packedTables = array_fill( 0, $this->numentries, false ); foreach ( $this->hplist as $item ) { @@ -416,7 +431,7 @@ class CdbWriter_PHP extends CdbWriter { // is taken. for ( $u = 0; $u < $count; ++$u ) { $hp = $packedTables[$starts[$i] + $u]; - $where = CdbFunctions::unsignedMod( + $where = CdbFunctions::unsignedMod( CdbFunctions::unsignedShiftRight( $hp['h'], 8 ), $len ); while ( $hashtable[$where]['p'] ) if ( ++$where == $len ) @@ -426,7 +441,7 @@ class CdbWriter_PHP extends CdbWriter { // Write the hashtable for ( $u = 0; $u < $len; ++$u ) { - $buf = pack( 'vvV', + $buf = pack( 'vvV', $hashtable[$u]['h'] & 0xffff, CdbFunctions::unsignedShiftRight( $hashtable[$u]['h'], 16 ), $hashtable[$u]['p'] ); @@ -438,8 +453,22 @@ class CdbWriter_PHP extends CdbWriter { // Write the pointer array at the start of the file rewind( $this->handle ); if ( ftell( $this->handle ) != 0 ) { - throw new MWException( __METHOD__.': Error rewinding to start of file' ); + $this->throwException( 'Error rewinding to start of file "'.$this->tmpFileName.'".' ); } $this->write( $final ); } + + /** + * Clean up the temp file and throw an exception + * + * @param $msg string + * @throws MWException + */ + protected function throwException( $msg ) { + if ( $this->handle ) { + fclose( $this->handle ); + unlink( $this->tmpFileName ); + } + throw new MWException( $msg ); + } } |