190 lines
4.8 KiB
PHP
190 lines
4.8 KiB
PHP
<?php
|
|
class bitmask {
|
|
/**
|
|
* Two-dimensional array containing all bits and their values. This array is populated by the class
|
|
*
|
|
* @var array
|
|
* @access public
|
|
*/
|
|
var $mask_array = array();
|
|
|
|
/**
|
|
* Contains the mask created by the class. It can contain multiple 32 bit masks separated by a hyphen (-)
|
|
* in order to represent extremely large bitmasks on systems without gmp available.
|
|
*
|
|
* @var string
|
|
* @access public
|
|
*/
|
|
var $assoc_keys = array();
|
|
/**
|
|
* Contains the keys for associative array
|
|
*
|
|
* @var array
|
|
* @access public
|
|
*/
|
|
var $forward_mask = '';
|
|
|
|
/**
|
|
* Contains the actual binary number represented by the mask.
|
|
*
|
|
* @var string
|
|
* @access public
|
|
*/
|
|
var $bin_mask = '';
|
|
|
|
/**
|
|
* @return void
|
|
* @desc Sets the $bin_mask variable based on the $forward_mask
|
|
* @access private
|
|
*/
|
|
function _set_binmask() {
|
|
$masks = explode('-',$this->forward_mask);
|
|
if (count($masks) > 1) {
|
|
for ($c = count($masks) - 2; $c >= 0; $c--) {
|
|
$bin_val .= str_pad((string)(base_convert($masks[$c],10,2)),32,'0',STR_PAD_LEFT);
|
|
}
|
|
$bin_val = base_convert($masks[count($masks) - 1],10,2) . $bin_val;
|
|
} else {
|
|
$bin_val = base_convert($masks[0],10,2);
|
|
}
|
|
$this->bin_mask = $bin_val;
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
* @desc Sets the $mask_array variable based on the $bin_mask
|
|
* @access private
|
|
*/
|
|
function _set_mask_array() {
|
|
unset($this->mask_array);
|
|
for ($c = (strlen($this->bin_mask) - 1); $c >= 0; $c--) {
|
|
$this->mask_array[] = $this->bin_mask[$c];
|
|
}
|
|
}
|
|
|
|
function _zeroclean() {
|
|
$this->forward_mask = preg_replace('/(-0)+$/','',$this->forward_mask);
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
* @param unknown $bitnum
|
|
* @desc Check if the bit at position $bitnum is set.
|
|
*/
|
|
function bit_isset($bitnum) {
|
|
return ($this->bin_mask[(strlen($this->bin_mask) - 1 - $bitnum)])?true:false;
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
* @param int $bitnum
|
|
* @desc Set the bit at location $bitnum
|
|
*/
|
|
function set_bit($bitnum) {
|
|
if (!$this->bit_isset($bitnum)) {
|
|
$masknum = (($bitnum - ($bitnum % 32)) / 32);
|
|
$masks = explode('-',$this->forward_mask);
|
|
if (($masknum - count($masks)) > 0) {
|
|
for ($c = count($masks); $c <= $masknum; $c++) {
|
|
$masks[$c] = 0;
|
|
}
|
|
}
|
|
$masks[$masknum] += pow(2,($bitnum - (32 * $masknum)));
|
|
$this->forward_mask = implode('-',$masks);
|
|
$this->_set_binmask();
|
|
$this->_set_mask_array();
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
* @param int $bitnum
|
|
* @desc Unset the bit at location $bitnum
|
|
*/
|
|
function unset_bit($bitnum) {
|
|
if ($this->bit_isset($bitnum)) {
|
|
$masknum = (($bitnum - ($bitnum % 32)) / 32);
|
|
$masks = explode('-',$this->forward_mask);
|
|
$masks[$masknum] -= pow(2,($bitnum - (32 * $masknum)));
|
|
$this->forward_mask = implode('-',$masks);
|
|
$this->_zeroclean();
|
|
$this->_set_binmask();
|
|
$this->_set_mask_array();
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
* @param mixed $mask_element
|
|
* @desc Can be either an array of values or empty. If you wish to add empty values,
|
|
* they can only be added in arrays where there is a non-empty value subsequent in the array.
|
|
*/
|
|
function add_element($mask_element = true) {
|
|
$lastbit = strlen($this->bin_mask);
|
|
if (is_array($mask_element)) {
|
|
foreach ($mask_element as $value) {
|
|
if ($value) $retval = $this->set_bit($lastbit);
|
|
$lastbit++;
|
|
}
|
|
} else {
|
|
$retval = $this->set_bit(strlen($this->bin_mask));
|
|
}
|
|
return $retval;
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
* @param array $assoc_bits
|
|
* @desc Allows you to enter an associative array of bit values
|
|
*/
|
|
function add_assoc($assoc_bits) {
|
|
foreach ($assoc_bits as $key => $value) {
|
|
$keys[] = $key;
|
|
$values[] = $value;
|
|
}
|
|
$this->add_element($values);
|
|
$this->assoc_keys = $keys;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
* @param bool $all_values
|
|
* @param bool $force
|
|
* @desc Returns associative array of either all values ($all_values == true) or only
|
|
* selected values ($all_values == false). By setting $force to true, you can force
|
|
* the return of an array where not all selections were taken into account due to not
|
|
* enough key values being entered.
|
|
*/
|
|
function assoc_get($all_values = true, $force = false) {
|
|
if ((count($this->assoc_keys) < count($this->mask_array)) && !$force) die ('More bits than array keys');
|
|
if ($all_values) {
|
|
foreach ($this->assoc_keys as $key => $value) {
|
|
$retval[$value] = $this->mask_array[$key];
|
|
}
|
|
} else {
|
|
foreach ($this->assoc_keys as $key => $value) {
|
|
if ($this->mask_array[$key]) $retval[$value] = $this->mask_array[$key];
|
|
}
|
|
}
|
|
return $retval;
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
* @param string $mask
|
|
* @desc Populates the object variables based on the value of $mask which is an integer.
|
|
*/
|
|
function reverse_mask($mask) {
|
|
$this->forward_mask = $mask;
|
|
$this->_set_binmask();
|
|
$this->_set_mask_array();
|
|
}
|
|
}
|
|
?>
|