dime.php

来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 629 行 · 第 1/2 页

PHP
629
字号
            $p += $this->DATA_LENGTH-$have;
        }
        return substr($data,$p);
    }   
}


class Net_DIME_Message extends PEAR
{

    var $record_size = 4096;
    #var $records =array();
    var $parts = array();
    var $currentPart = -1;
    var $stream = NULL;
    var $_currentRecord;
    var $_proc = array();
    var $type;
    var $typestr;
    var $mb = 1;
    var $me = 0;
    var $cf = 0;
    var $id = NULL;
    var $debug = FALSE;
    /**
     * constructor
     *
     * this currently takes a file pointer as provided
     * by fopen
     *
     * TODO: integrate with the php streams stuff
     */
    function Net_DIME_Message($stream=NULL, $record_size = 4096, $debug = FALSE)
    {
        $this->stream = $stream;
        $this->record_size = $record_size;
        $this->debug = $debug;
    }
    
    function _makeRecord(&$data, $typestr='', $id=NULL, $type=NET_DIME_TYPE_UNKNOWN)
    {
        $record = new Net_DIME_Record($this->debug);
        if ($this->mb) {
            $record->setMB();
            // all subsequent records are not message begin!
            $this->mb = 0; 
        }
        if ($this->me) $record->setME();
        if ($this->cf) $record->setCF();
        $record->setData($data);
        $record->setType($typestr,$type);
        if ($id) $record->setID($id);
        #if ($this->debug) {
        #    print str_replace('\0','*',$record->encode());
        #}
        return $record->encode();
    }
    
    function startChunk(&$data, $typestr='', $id=NULL, $type=NET_DIME_TYPE_UNKNOWN)
    {
        $this->me = 0;
        $this->cf = 1;
        $this->type = $type;
        $this->typestr = $typestr;
        if ($id) {
            $this->id = $id;
        } else {
            $this->id = md5(time());
        }
        return $this->_makeRecord($data, $this->typestr, $this->id, $this->type);
    }

    function doChunk(&$data)
    {
        $this->me = 0;
        $this->cf = 1;
        return $this->_makeRecord($data, NULL, NULL, NET_DIME_TYPE_UNCHANGED);
    }

    function endChunk()
    {
        $this->cf = 0;
        $data = NULL;
        $rec = $this->_makeRecord($data, NULL, NULL, NET_DIME_TYPE_UNCHANGED);
        $this->id = 0;
        $this->cf = 0;
        $this->id = 0;
        $this->type = NET_DIME_TYPE_UNKNOWN;
        $this->typestr = NULL;
        return $rec;
    }
    
    function endMessage()
    {
        $this->me = 1;
        $data = NULL;
        $rec = $this->_makeRecord($data, NULL, NULL, NET_DIME_TYPE_NONE);
        $this->me = 0;
        $this->mb = 1;
        $this->id = 0;
        return $rec;
    }
    
    /**
     * sendRecord
     *
     * given a chunk of data, it creates DIME records
     * and writes them to the stream
     *
     */
    function sendData(&$data, $typestr='', $id=NULL, $type=NET_DIME_TYPE_UNKNOWN)
    {
        $len = strlen($data);
        if ($len > $this->record_size) {
            $chunk = substr($data, 0, $this->record_size);
            $p = $this->record_size;
            $rec = $this->startChunk($chunk,$typestr,$id,$type);
            fwrite($this->stream, $rec);
            while ($p < $len) {
                $chunk = substr($data, $p, $this->record_size);
                $p += $this->record_size;
                $rec = $this->doChunk($chunk);
                fwrite($this->stream, $rec);
            }
            $rec = $this->endChunk();
            fwrite($this->stream, $rec);
            return;
        }
        $rec = $this->_makeRecord($data, $typestr,$id,$type);
        fwrite($this->stream, $rec);
    }
    
    function sendEndMessage()
    {
        $rec = $this->endMessage();
        fwrite($this->stream, $rec);
    }
    
    /**
     * sendFile
     *
     * given a filename, it reads the file,
     * creates records and writes them to the stream
     *
     */
    function sendFile($filename, $typestr='', $id=NULL, $type=NET_DIME_TYPE_UNKNOWN)
    {
        $f = fopen($filename, "rb");
        if ($f) {
            if ($data = fread($f, $this->record_size)) {
                $this->startChunk($data,$typestr,$id,$type);
            }
            while ($data = fread($f, $this->record_size)) {
                $this->doChunk($data,$typestr,$id,$type);
            }
            $this->endChunk();
            fclose($f);
        }
    }

    /**
     * encodeData
     *
     * given data, encode it in DIME
     *
     */
    function encodeData($data, $typestr='', $id=NULL, $type=NET_DIME_TYPE_UNKNOWN)
    {
        $len = strlen($data);
        $resp = '';
        if ($len > $this->record_size) {
            $chunk = substr($data, 0, $this->record_size);
            $p = $this->record_size;
            $resp .= $this->startChunk($chunk,$typestr,$id,$type);
            while ($p < $len) {
                $chunk = substr($data, $p, $this->record_size);
                $p += $this->record_size;
                $resp .= $this->doChunk($chunk);
            }
            $resp .= $this->endChunk();
        } else {
            $resp .= $this->_makeRecord($data, $typestr,$id,$type);
        }
        return $resp;
    }

    /**
     * sendFile
     *
     * given a filename, it reads the file,
     * creates records and writes them to the stream
     *
     */
    function encodeFile($filename, $typestr='', $id=NULL, $type=NET_DIME_TYPE_UNKNOWN)
    {
        $f = fopen($filename, "rb");
        if ($f) {
            if ($data = fread($f, $this->record_size)) {
                $resp = $this->startChunk($data,$typestr,$id,$type);
            }
            while ($data = fread($f, $this->record_size)) {
                $resp = $this->doChunk($data,$typestr,$id,$type);
            }
            $resp = $this->endChunk();
            fclose($f);
        }
        return $resp;
    }
    
    /**
     * _processData
     *
     * creates Net_DIME_Records from provided data
     *
     */
    function _processData(&$data)
    {
        $leftover = NULL;
        if (!$this->_currentRecord) {
            $this->_currentRecord = new Net_DIME_Record($this->debug);
            $data = $this->_currentRecord->decode($data);
        } else {
            $data = $this->_currentRecord->addData($data);
        }
				
        if ($this->_currentRecord->_haveData) {
            if (count($this->parts)==0 && !$this->_currentRecord->isStart()) {
                // raise an error!
                return PEAR::raiseError('First Message is not a DIME begin record!');
            }

            if ($this->_currentRecord->isEnd() && $this->_currentRecord->getDataLength()==0) {
                return NULL;
            }
            
            if ($this->currentPart < 0 && !$this->_currentRecord->isChunk()) {
                $this->parts[] = array();
                $this->currentPart = count($this->parts)-1;
                $this->parts[$this->currentPart]['id']   = $this->_currentRecord->getID();
                $this->parts[$this->currentPart]['type'] = $this->_currentRecord->getType();
                $this->parts[$this->currentPart]['data'] = $this->_currentRecord->getData();
                $this->currentPart = -1;
            } else {
                if ($this->currentPart < 0) {
                    $this->parts[] = array();
                    $this->currentPart = count($this->parts)-1;
                    $this->parts[$this->currentPart]['id']   = $this->_currentRecord->getID();
                    $this->parts[$this->currentPart]['type'] = $this->_currentRecord->getType();
                    $this->parts[$this->currentPart]['data'] = $this->_currentRecord->getData();
                } else {
                    $this->parts[$this->currentPart]['data'] .= $this->_currentRecord->getData();
                    if (!$this->_currentRecord->isChunk()) {
                        // we reached the end of the chunk
                        $this->currentPart = -1;
                    }
                }
            }
            #$this->records[] = $this->_currentRecord;
            if (!$this->_currentRecord->isEnd()) $this->_currentRecord = NULL;
        }
        return NULL;
    }
    
    /**
     * decodeData
     *
     * decodes a DIME encrypted string of data
     *
     */
    function decodeData(&$data) {
        while (strlen($data) >= NET_DIME_RECORD_HEADER) {
            $err = $this->_processData($data);
            if (PEAR::isError($err)) {
                return $err;
            }
        }
    }
    
    /**
     * read
     *
     * reads the stream and creates
     * an array of records
     *
     * it can accept the start of a previously read buffer
     * this is usefull in situations where you need to read
     * headers before discovering that the data is DIME encoded
     * such as in the case of reading an HTTP response.
     */
    function read($buf=NULL)
    {
        while ($data = fread($this->stream, 8192)) {
            if ($buf) {
                $data = $buf.$data;
                $buf = NULL;
            }
            if ($this->debug)
                echo "read: ".strlen($data)." bytes\n";
            $err = $this->decodeData($data);
            if (PEAR::isError($err)) {
                return $err;
            }
            
            // store any leftover data to be used again
            // should be < NET_DIME_RECORD_HEADER bytes
            $buf = $data;
        }
        if (!$this->_currentRecord || !$this->_currentRecord->isEnd()) {
            return PEAR::raiseError('reached stream end without end record');
        }
        return NULL;
    }
}
?>

⌨️ 快捷键说明

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