file.php

来自「视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.」· PHP 代码 · 共 828 行 · 第 1/2 页

PHP
828
字号
<?php/* vim: set expandtab tabstop=4 shiftwidth=4: */// +----------------------------------------------------------------------+// | Copyright (c) 2002-2003 Brent Cook                                        |// +----------------------------------------------------------------------+// | This library is free software; you can redistribute it and/or        |// | modify it under the terms of the GNU Lesser General Public           |// | License as published by the Free Software Foundation; either         |// | version 2.1 of the License, or (at your option) any later version.   |// |                                                                      |// | This library 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    |// | Lesser General Public License for more details.                      |// |                                                                      |// | You should have received a copy of the GNU Lesser General Public     |// | License along with this library; if not, write to the Free Software  |// | Foundation, Inc., 59 Temple Place, Suite 330,Boston,MA 02111-1307 USA|// +----------------------------------------------------------------------+//// $Id: File.php,v 1.12 2003/01/27 04:31:42 busterb Exp $require_once 'DBA.php';// {{{ constants/** * Location in the index file for a block location */define('DBA_SIMPLE_LOC',0);/** * Location in the index file for a block size */define('DBA_SIMPLE_SIZE',1);/** * Location in the index file for a block value size */define('DBA_SIMPLE_VSIZE',2);/** * Location in the index file for a block key */define('DBA_SIMPLE_KEY',3);// }}}/** * DBA_Driver_File provides a simple, file-based implementation of a * DBM-style database. It uses two files, and index and a data file to * manage key/value pairs. These two files use the suffixes '.dat' and * '.idx'. When a database is opened, only the index file is read. The * index file contains pointers to locations within the data file, which * are used to retrieve values. * * The class uses a concept of blocks for data storage. When the first value * is inserted, a new block is created by appending to the data file. If that * value is deleted, it remains in the data file, but is marked as empty in * the index file. A list of available blocks is kept, so when a new value * is inserted, its size is compared to the list of available blocks. If one * is of sufficient size, it is reused and marked as used in the index file. * Blocks can be of any length. * * In updating the index, lines are simply appended to the file after each * operation. So, the index file might have the same block listed multiple time * , just in different states. When the database is closed, it rewrites the * index file, removing and duplicate entries for a single block. The index * reader only uses the last entry for a block from the index file, so if close * is not called for some reason, the index file is still in a valid state. * * The optimize function merely removes duplicated index entries by rewriting * the file, the same as close. * The sync function calls fflush on the data and index files. * * @author  Brent Cook * @version 1.0 * @access  public * @package DBA */class DBA_Driver_File extends DBA{    // {{{ instance variables    /**     * Name of the database     * @access private     */    var $_dbName;    /**     * Handle to data file     * @access private     */    var $_datFP;    /**     * Handle to index file     * @access private     */    var $_idxFP;    /**     * Indicates the current ability for read/write operations     * @access private     */    var $_writable;    /**     * Indicates the current ability for read operations     * @access private     */    var $_readable;    /**     * Determines if the driver should use an index file     * @access private     */    var $_indexed;    // }}}    // {{{ DBA_Driver_File($indexed = true)    /* Constructor     *     * @access public     * @param   string  $driver dba driver to use     */    function DBA_Driver_File($indexed = true)    {        // call the base constructor        $this->DBA();        $this->_indexed = true;    }    // }}}    // {{{ open($dbName='', $mode='r', $persistent = false)    /**     * Opens a database.     *     * @access  public     * @param   string  $dbName The name of a database     * @param   string  $mode The mode in which to open a database.     *                   'r' opens read-only.     *                   'w' opens read-write.     *                   'n' creates a new database and opens read-write.     *                   'c' creates a new database if the database does not     *                      exist and opens read-write.     * @param   boolean $persistent Determines whether to open the database     *                  peristently. Not supported here.     * @return  object  PEAR_Error on failure     */    function open($dbName='', $mode='r', $persistent = false)    {        if ($persistent) {            return $this->raiseError(DBA_ERROR_UNSUP_PERSISTENCE);        }        if ($dbName == '') {            return $this->raiseError(DBA_ERROR_NO_DBNAME);        } else {            $this->_dbName = $dbName;            $dat_name = $dbName.'.dat';            $idx_name = $dbName.'.idx';        }        switch ($mode) {            case 'r':                    // open for reading                    $file_mode = 'rb';                    $this->_writable = false;                    $this->_readable = true;                    break;            case 'n':                    // create a new database                    $file_mode = 'w+b';                    $this->_writable = true;                    $this->_readable = true;                    break;            case 'c':                    // should we create a new database?                    if (!DBA_Driver_File::db_exists($dbName)) {                        $file_mode = 'w+b';                        $this->_writable = true;                        $this->_readable = true;                        break;                    } // otherwise, we just open for writing            case 'w':                    $file_mode = 'r+b';                    $this->_writable = true;                    $this->_readable = true;                    break;            default:                return $this->raiseError(DBA_ERROR_INVALID_MODE, NULL, NULL,                    'filemode: '.$mode);        }        // open the index file        $this->_idxFP = @fopen($idx_name, $file_mode);        if ($this->_idxFP === false) {            $this->_writable = false;            $this->_readable = false;            return $this->raiseError(DBA_ERROR_CANNOT_OPEN, NULL, NULL,                'could not open idx file '.$idx_name);        }        // open the data file        $this->_datFP = @fopen($dat_name, $file_mode);        if ($this->_datFP === false) {            fclose ($this->_idxFP);            $this->_writable = false;            $this->_readable = false;            return $this->raiseError(DBA_ERROR_CANNOT_OPEN, NULL, NULL,                'could not open data file '.$dat_name);        }        // get a shared lock if read-only, otherwise get an exclusive lock        if ($file_mode == 'r') {            flock ($this -> _idxFP, LOCK_SH);            flock ($this -> _datFP, LOCK_SH);        } else {            flock ($this -> _idxFP, LOCK_EX);            flock ($this -> _datFP, LOCK_EX);        }        // we are writing to a new file, so we do not need to read anything        if ($file_mode != 'w+') {            // parse the index file            $this->_readIdx();        }    }    // }}}    // {{{ close()    /**     * Closes an open database.     *     * @access  public     * @return  object  PEAR_Error on failure     */    function close()    {        if ($this->isOpen())        {            if ($this->isWritable())            {                $this->_writeIdx();            }            $this->_readable = false;            $this->_writable = false;            fclose($this->_idxFP);            fclose($this->_datFP);        } else {            return $this->raiseError(DBA_ERROR_NOT_OPEN);        }    }    // }}}    // {{{ reopen($mode)    /**     * Reopens an already open database in read-only or write mode.     * If the database is already in the requested mode, then this function     * does nothing.     *     * @access  public     * @param   string  $mode 'r' for read-only, 'w' for read/write     * @return  object  PEAR_Error on failure     */    function reopen($mode)    {        if ($this->isOpen()) {            if (($mode == 'r') && $this->isWritable()) {                // Reopening as read-only                $this->close();                return $this->open($this->_dbName, 'r');            } else {                if (($mode == 'w') && (!$this -> _writable))                {                    // Reopening as read-write                    $this->close();                    return $this->open($this->_dbName, 'w');                }            }        } else {            return $this->raiseError(DBA_ERROR_NOT_OPEN);        }    }    // }}}    // {{{ _DBA_Driver_File()    /**     * PEAR emulated destructor calls close on PHP shutdown     * @access private     */    function _DBA_Driver_File()    {        $this->close();    }    // }}}    // {{{ getName()    /**     * Returns the name of the opened database. Assumes database is open     * @returns string the name of the opened database     */    function getName()    {        return $this->_dbName;    }    // }}}    // {{{ isOpen()    /**     * Returns the current open status for the database     *     * @access  public     * @return  boolean true if the database is open, false if it is closed     */    function isOpen()    {        return($this->_readable || $this->_writable);    }    // }}}    // {{{ isReadable()    /**     * Returns the current read status for the database     *     * @access  public     * @return  boolean true if the database is readable, false if it is not     */    function isReadable()    {        return $this->_readable;    }    // }}}    // {{{ isWritable()    /**     * Returns the current write status for the database     *     * @access  public     * @return  boolean true if the database is writable, false if it is not     */     function isWritable()     {         return $this->_writable;     }    // }}}    // {{{ remove($key)    /**     * Removes the value at location $key     *     * @access  public     * @param   string  $key key to remove     * @return  object  PEAR_Error on failure     */    function remove($key)    {        if ($this->isWritable()) {            if (isset($this->_usedBlocks[$key])) {                $this->_freeUsedBlock($key);            } else {                return $this->raiseError(DBA_ERROR_NOT_FOUND, NULL, NULL, 'key: '.$key);            }        } else {            return $this->raiseError(DBA_ERROR_NOT_WRITEABLE);        }    }    // }}}    // {{{ &fetch($key)    /**     * Returns the value that is stored at $key.     *     * @access  public     * @param   string $key key to examine     * @return  mixed  the requested value on success, false on failure     */    function &fetch($key)    {        if ($this->isReadable()) {            if (!isset($this->_usedBlocks[$key])) {                return $this->raiseError(DBA_ERROR_NOT_FOUND, NULL, NULL, 'key: '.$key);            } else {                fseek($this->_datFP, $this->_usedBlocks[$key][DBA_SIMPLE_LOC]);                return fread($this->_datFP,$this->_usedBlocks[$key][DBA_SIMPLE_VSIZE]);            }        } else {            return $this->raiseError(DBA_ERROR_NOT_READABLE);        }    }    // }}}    // {{{ firstkey()    /**     * Returns the first key in the database     *     * @access  public     * @return  mixed  string on success, false on failure     */    function firstkey()    {        if ($this->isReadable() && ($this->size() > 0)) {            reset($this->_usedBlocks);            return key($this->_usedBlocks);        } else {            return false;        }    }    // }}}    // {{{ nextkey()    /**     * Returns the next key in the database, false if there is a problem     *     * @access  public

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?