dime.php

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

PHP
629
字号
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4                                                        |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group                                |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license,      |
// | that is bundled with this package in the file LICENSE, and is        |
// | available at through the world-wide-web at                           |
// | http://www.php.net/license/2_02.txt.                                 |
// | If you did not receive a copy of the PHP license and are unable to   |
// | obtain it through the world-wide-web, please send a note to          |
// | license@php.net so we can mail you a copy immediately.               |
// +----------------------------------------------------------------------+
// | Authors: Shane Caraveo <shane@caraveo.com>                           |
// | 		  Ralf Hofmann <ralf.hofmann@verdisoft.com>					  |
// +----------------------------------------------------------------------+
//
// $Id: DIME.php 6819 2007-06-20 13:09:21Z kevin_fourie $
//

require_once 'PEAR.php';
/**
 *
 *  DIME Encoding/Decoding
 *
 * What is it?
 *   This class enables you to manipulate and build
 *   a DIME encapsulated message.
 *
 * http://www.ietf.org/internet-drafts/draft-nielsen-dime-02.txt
 *
 * 09/18/02 Ralf -  A huge number of changes to be compliant 
 * 					with the DIME Specification Release 17 June 2002
 * 
 * TODO: lots of stuff needs to be tested.
 *           Definitily have to go through DIME spec and
 *           make things work right, most importantly, sec 3.3
 *           make examples, document
 *
 * see test/dime_mesage_test.php for example of usage
 * 
 * @author  Shane Caraveo <shane@caraveo.com>, 
 *          Ralf Hofmann <ralf.hofmann@verdisoft.com>	 
 * @version $Revision: 6819 $
 * @package Net_DIME
 */
define('NET_DIME_TYPE_UNCHANGED',0x00);
define('NET_DIME_TYPE_MEDIA',0x01);
define('NET_DIME_TYPE_URI',0x02);
define('NET_DIME_TYPE_UNKNOWN',0x03);
define('NET_DIME_TYPE_NONE',0x04);

define('NET_DIME_VERSION',0x0001);

define('NET_DIME_RECORD_HEADER',12);

define('NET_DIME_FLAGS', 0);
define('NET_DIME_OPTS_LEN', 1);
define('NET_DIME_ID_LEN', 2);
define('NET_DIME_TYPE_LEN', 3);
define('NET_DIME_DATA_LEN', 4);
define('NET_DIME_OPTS', 5);
define('NET_DIME_ID', 6);
define('NET_DIME_TYPE', 7);
define('NET_DIME_DATA', 8);

class Net_DIME_Record extends PEAR
{
    // these are used to hold the padded length
    var $OPTS_LENGTH = 0;
    var $ID_LENGTH = 0;
    var $TYPE_LENGTH = 0; 
    var $DATA_LENGTH = 0;
    var $_haveOpts = FALSE;
    var $_haveID = FALSE;
    var $_haveType = FALSE;
    var $_haveData = FALSE;
    var $debug = FALSE;
    var $padstr = "\0";
    /**
     * Elements
     * [NET_DIME_FLAGS],    16 bits: VERSION:MB:ME:CF:TYPE_T
     * [NET_DIME_OPTS_LEN], 16 bits: OPTIONS_LENGTH
     * [NET_DIME_ID_LEN],   16 bits: ID_LENGTH
     * [NET_DIME_TYPE_LEN], 16 bits: TYPE_LENGTH
     * [NET_DIME_DATA_LEN], 32 bits: DATA_LENGTH
	 * [NET_DIME_OPTS]             : OPTIONS
	 * [NET_DIME_ID]     		   : ID
	 * [NET_DIME_TYPE]             : TYPE
	 * [NET_DIME_DATA]             : DATA
     */
    var $Elements = array(NET_DIME_FLAGS => 0,  NET_DIME_OPTS_LEN => 0, 
	                      NET_DIME_ID_LEN => 0, NET_DIME_TYPE_LEN => 0, 
     					  NET_DIME_DATA_LEN => 0,
	 					  NET_DIME_OPTS => '',
						  NET_DIME_ID => '',
						  NET_DIME_TYPE => '',
						  NET_DIME_DATA => '');
    
    function Net_DIME_Record($debug = FALSE)
    {
        $this->debug = $debug;
        if ($debug) $this->padstr = '*';
    }

    function setMB()
    {
        $this->Elements[NET_DIME_FLAGS] |= 0x0400;
    }

    function setME()
    {
        $this->Elements[NET_DIME_FLAGS] |= 0x0200;
    }

    function setCF()
    {
        $this->Elements[NET_DIME_FLAGS] |= 0x0100;
    }

    function isChunk()
    {
        return $this->Elements[NET_DIME_FLAGS] & 0x0100;
    }

    function isEnd()
    {
        return $this->Elements[NET_DIME_FLAGS] & 0x0200;
    }
    
    function isStart()
    {
        return $this->Elements[NET_DIME_FLAGS] & 0x0400;
    }
    
    function getID()
    {
        return $this->Elements[NET_DIME_ID];
    }

    function getType()
    {
        return $this->Elements[NET_DIME_TYPE];
    }

    function getData()
    {
        return $this->Elements[NET_DIME_DATA];
    }
    
    function getDataLength()
    {
        return $this->Elements[NET_DIME_DATA_LEN];
    }
    
    function setType($typestring, $type=NET_DIME_TYPE_UNKNOWN)
    {
        $typelen = strlen($typestring) & 0xFFFF;
        $type = $type << 4;
        $this->Elements[NET_DIME_FLAGS] = ($this->Elements[NET_DIME_FLAGS] & 0xFF0F) | $type;
        $this->Elements[NET_DIME_TYPE_LEN] = $typelen;
        $this->TYPE_LENGTH = $this->_getPadLength($typelen);
        $this->Elements[NET_DIME_TYPE] = $typestring;
    }
    
    function generateID()
    {
        $id = md5(time());
        $this->setID($id);
        return $id;
    }
    
    function setID($id)
    {
        $idlen = strlen($id) & 0xFFFF;
        $this->Elements[NET_DIME_ID_LEN] = $idlen;
        $this->ID_LENGTH = $this->_getPadLength($idlen);
        $this->Elements[NET_DIME_ID] = $id;
    }
    
    function setData($data, $size=0)
    {
        $datalen = $size?$size:strlen($data);
        $this->Elements[NET_DIME_DATA_LEN] = $datalen;
        $this->DATA_LENGTH = $this->_getPadLength($datalen);
        $this->Elements[NET_DIME_DATA] = $data;
    }
    
    function encode()
    {
		// insert version 
	    $this->Elements[NET_DIME_FLAGS] = ($this->Elements[NET_DIME_FLAGS] & 0x07FF) | (NET_DIME_VERSION << 11);

        // the real dime encoding
        $format =   '%c%c%c%c%c%c%c%c%c%c%c%c'.
                    '%'.$this->OPTS_LENGTH.'s'.
                    '%'.$this->ID_LENGTH.'s'.
                    '%'.$this->TYPE_LENGTH.'s'.
                    '%'.$this->DATA_LENGTH.'s';
        return sprintf($format,
	                   ($this->Elements[NET_DIME_FLAGS]&0x0000FF00)>>8,
    	               ($this->Elements[NET_DIME_FLAGS]&0x000000FF),
        	           ($this->Elements[NET_DIME_OPTS_LEN]&0x0000FF00)>>8,
            	       ($this->Elements[NET_DIME_OPTS_LEN]&0x000000FF),
        	           ($this->Elements[NET_DIME_ID_LEN]&0x0000FF00)>>8,
            	       ($this->Elements[NET_DIME_ID_LEN]&0x000000FF),
        	           ($this->Elements[NET_DIME_TYPE_LEN]&0x0000FF00)>>8,
            	       ($this->Elements[NET_DIME_TYPE_LEN]&0x000000FF),
                	   ($this->Elements[NET_DIME_DATA_LEN]&0xFF000000)>>24,
	                   ($this->Elements[NET_DIME_DATA_LEN]&0x00FF0000)>>16,
    	               ($this->Elements[NET_DIME_DATA_LEN]&0x0000FF00)>>8,
        	           ($this->Elements[NET_DIME_DATA_LEN]&0x000000FF),
            	       str_pad($this->Elements[NET_DIME_OPTS], $this->OPTS_LENGTH, $this->padstr),
            	       str_pad($this->Elements[NET_DIME_ID], $this->ID_LENGTH, $this->padstr),
                	   str_pad($this->Elements[NET_DIME_TYPE], $this->TYPE_LENGTH, $this->padstr),
	                   str_pad($this->Elements[NET_DIME_DATA], $this->DATA_LENGTH, $this->padstr));
    }
    
    function _getPadLength($len)
    {
        $pad = 0;
        if ($len) {
            $pad = $len % 4;
            if ($pad) $pad = 4 - $pad;
        }
        return $len + $pad;
    }
    
    function decode(&$data)
    {
        // REAL DIME decoding
        $this->Elements[NET_DIME_FLAGS]    = (hexdec(bin2hex($data[0]))<<8) + hexdec(bin2hex($data[1]));
        $this->Elements[NET_DIME_OPTS_LEN] = (hexdec(bin2hex($data[2]))<<8) + hexdec(bin2hex($data[3]));
        $this->Elements[NET_DIME_ID_LEN]   = (hexdec(bin2hex($data[4]))<<8) + hexdec(bin2hex($data[5]));
        $this->Elements[NET_DIME_TYPE_LEN] = (hexdec(bin2hex($data[6]))<<8) + hexdec(bin2hex($data[7]));
        $this->Elements[NET_DIME_DATA_LEN] = (hexdec(bin2hex($data[8]))<<24) +
		                             (hexdec(bin2hex($data[9]))<<16) +
                                     (hexdec(bin2hex($data[10]))<<8) +
                                      hexdec(bin2hex($data[11]));
        $p = 12;
		
		$version = (($this->Elements[NET_DIME_FLAGS]>>11) & 0x001F);
		
		if ($version == NET_DIME_VERSION) 
		{
	        $this->OPTS_LENGTH = $this->_getPadLength($this->Elements[NET_DIME_OPTS_LEN]);        
	        $this->ID_LENGTH = $this->_getPadLength($this->Elements[NET_DIME_ID_LEN]);
	        $this->TYPE_LENGTH = $this->_getPadLength($this->Elements[NET_DIME_TYPE_LEN]);
	        $this->DATA_LENGTH = $this->_getPadLength($this->Elements[NET_DIME_DATA_LEN]);
	                
	        $datalen = strlen($data);
	        $this->Elements[NET_DIME_OPTS] = substr($data,$p,$this->Elements[NET_DIME_OPTS_LEN]);
	        $this->_haveOpts = (strlen($this->Elements[NET_DIME_OPTS]) == $this->Elements[NET_DIME_OPTS_LEN]);
	        if ($this->_haveOpts) {
	            $p += $this->OPTS_LENGTH;		
		        $this->Elements[NET_DIME_ID] = substr($data,$p,$this->Elements[NET_DIME_ID_LEN]);
		        $this->_haveID = (strlen($this->Elements[NET_DIME_ID]) == $this->Elements[NET_DIME_ID_LEN]);
		        if ($this->_haveID) {
		            $p += $this->ID_LENGTH;
		            $this->Elements[NET_DIME_TYPE] = substr($data,$p,$this->Elements[NET_DIME_TYPE_LEN]);
		            $this->_haveType = (strlen($this->Elements[NET_DIME_TYPE]) == $this->Elements[NET_DIME_TYPE_LEN]);
		            if ($this->_haveType) {
		                $p += $this->TYPE_LENGTH;
		                $this->Elements[NET_DIME_DATA] = substr($data,$p,$this->Elements[NET_DIME_DATA_LEN]);
		                $this->_haveData = (strlen($this->Elements[NET_DIME_DATA]) == $this->Elements[NET_DIME_DATA_LEN]);
		                if ($this->_haveData) {
		                    $p += $this->DATA_LENGTH;
		                } else {
		                    $p += strlen($this->Elements[NET_DIME_DATA]);
		                }
		            } else {
		                $p += strlen($this->Elements[NET_DIME_TYPE]);
					}
		        } else {
		            $p += strlen($this->Elements[NET_DIME_ID]);
				}
		    } else {
		    	$p += strlen($this->Elements[NET_DIME_OPTS]);					
	        }
		}
        return substr($data, $p);
    }
    
    function addData(&$data)
    {
        $datalen = strlen($data);
        $p = 0;
        if (!$this->_haveOpts) {
            $have = strlen($this->Elements[NET_DIME_OPTS]);
            $this->Elements[NET_DIME_OPTS] .= substr($data,$p,$this->Elements[NET_DIME_OPTS_LEN]-$have);
            $this->_haveOpts = (strlen($this->Elements[NET_DIME_OPTS]) == $this->Elements[DIME_OTPS_LEN]);
            if (!$this->_haveOpts) return NULL;
            $p += $this->OPTS_LENGTH-$have;
        }
        if (!$this->_haveID) {
            $have = strlen($this->Elements[NET_DIME_ID]);
            $this->Elements[NET_DIME_ID] .= substr($data,$p,$this->Elements[NET_DIME_ID_LEN]-$have);
            $this->_haveID = (strlen($this->Elements[NET_DIME_ID]) == $this->Elements[NET_DIME_ID_LEN]);
            if (!$this->_haveID) return NULL;
            $p += $this->ID_LENGTH-$have;
        }
        if (!$this->_haveType && $p < $datalen) {
            $have = strlen($this->Elements[NET_DIME_TYPE]);
            $this->Elements[NET_DIME_TYPE] .= substr($data,$p,$this->Elements[NET_DIME_TYPE_LEN]-$have);
            $this->_haveType = (strlen($this->Elements[NET_DIME_TYPE]) == $this->Elements[NET_DIME_TYPE_LEN]);
            if (!$this->_haveType) return NULL;
            $p += $this->TYPE_LENGTH-$have;
        }
        if (!$this->_haveData && $p < $datalen) {
            $have = strlen($this->Elements[NET_DIME_DATA]);
            $this->Elements[NET_DIME_DATA] .= substr($data,$p,$this->Elements[NET_DIME_DATA_LEN]-$have);
            $this->_haveData = (strlen($this->Elements[NET_DIME_DATA]) == $this->Elements[NET_DIME_DATA_LEN]);
            if (!$this->_haveData) return NULL;

⌨️ 快捷键说明

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