Merge "[JobQueue] Added support for approximate FIFO job queues."
[lhc/web/wiklou.git] / includes / Cdb_PHP.php
index e1e6d28..f58e07e 100644 (file)
@@ -6,6 +6,21 @@
  *    * Exception thrown if sizes or offsets are between 2GB and 4GB
  *    * Some variables renamed
  *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
  * @file
  */
 
@@ -82,6 +97,9 @@ class CdbFunctions {
  * CDB reader class
  */
 class CdbReader_PHP extends CdbReader {
+       /** The filename */
+       var $fileName;
+
        /** The file handle */
        var $handle;
 
@@ -108,11 +126,13 @@ class CdbReader_PHP extends CdbReader {
 
        /**
         * @param $fileName string
+        * @throws MWException
         */
        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();
        }
@@ -160,7 +180,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 ) {
@@ -169,7 +190,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;
        }
@@ -177,12 +199,14 @@ class CdbReader_PHP extends CdbReader {
        /**
         * Unpack an unsigned integer and throw an exception if it needs more than 31 bits
         * @param $s
-        * @return
+        * @throws MWException
+        * @return mixed
         */
        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];
        }
@@ -270,13 +294,14 @@ class CdbWriter_PHP extends CdbWriter {
                $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 . '".' );
                }
        }
 
@@ -314,7 +339,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 );
        }
@@ -326,7 +351,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.'".' );
                }
        }
 
@@ -337,7 +362,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;
        }
@@ -366,10 +392,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 );
@@ -444,8 +470,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 );
+       }
 }