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 + -
显示快捷键?