TimeTrex/classes/bitmask/bitmask.class.php

190 lines
4.8 KiB
PHP
Raw Permalink Normal View History

2022-12-13 07:10:06 +01:00
<?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();
}
}
?>