Overview
  • Namespace
  • Class

Namespaces

  • apemsel
    • AttributedString

Classes

  • apemsel\AttributedString\AttributedString
  • apemsel\AttributedString\Bitmap
  • apemsel\AttributedString\BooleanArray
  • apemsel\AttributedString\MutableAttributedString
  • apemsel\AttributedString\TokenizedAttributedString

Interfaces

  • apemsel\AttributedString\Attribute
  • apemsel\AttributedString\MutableAttribute
  1 <?php
  2 namespace apemsel\AttributedString;
  3 
  4 /**
  5  * Bitmap
  6  *
  7  * A memory efficient Attribute implementation using a bitmask stored in a string.
  8  *
  9  * @author Adrian Pemsel <apemsel@gmail.com>
 10  */
 11 class Bitmap implements Attribute
 12 {
 13   protected $bitmap;
 14   protected $length;
 15   
 16   /**
 17    * @param int length of bitmask
 18    */
 19   public function __construct($length) {
 20     $this->length = $length;
 21     $this->bitmap = str_repeat(chr(0), ceil($this->length / 8));
 22   }
 23   
 24   /**
 25    * Returns the bitmask as a visual string
 26    *
 27    * @return string bitmask as visual string of 0s and 1s
 28    */
 29   public function __toString() {
 30     return $this->toString();
 31   }
 32   
 33   /**
 34    * Returns the bitmask as a visual string with custom chars for 0s and 1s
 35    *
 36    * @param string $true representation of 1s
 37    * @param string $true representation of 0s
 38    * @return string bitmask as visual string of the given representations
 39    */
 40   public function toString($true = "1", $false = "0") {
 41     $string = str_repeat($false, $this->length);
 42     for ($offset = 0; $offset < $this->length; $offset++) {
 43       if (ord($this->bitmap[(int) ($offset / 8)]) & (1 << $offset % 8)) {
 44         $string[$offset] = $true;
 45       }
 46     }
 47     
 48     return $string;
 49   }
 50   
 51   /**
 52    * Set given range to a state
 53    *
 54    * @param int $from start offset
 55    * @param int $to end offset
 56    * @param bool $state set state to true (default) or false
 57    */
 58   public function setRange($from, $to, $state = true) {
 59     // Set attribute state for given range
 60     for($i = $from; $i <= $to; $i++) {
 61       $this->offsetSet($i, $state);
 62     }
 63   }
 64   
 65   /**
 66    * Search inside bitmap for ranges with the given state
 67    *
 68    * @param int $offset start offset
 69    * @param bool $returnLength if true (default is false), return an array with position and length of the found range
 70    * @param bool $state the state to look for (default is true)
 71    * @param bool $strict perform strict comparison during search
 72    * @return int|int[] either position or position and lenght in an array
 73    */
 74   public function search($offset = 0, $returnLength = false, $state = true, $strict = true) {
 75     for ($i = $offset; $i < $this->length; $i++) {
 76       if (($strict and $this->offsetGet($i) === $state) or (!$strict and $this->offsetGet($i) == $state)) {
 77         if ($returnLength) {
 78           $length = $this->search($i, false, !$state, $strict);
 79           $length = $length ? $length - $i : $this->length - $i;
 80           
 81           return [$i, $length];
 82         } else {
 83           return $i;
 84         }
 85       }
 86     }
 87     
 88     return false;
 89   }
 90   
 91   // ArrayAccess interface
 92   
 93   /**
 94    * Check if the given offset exists in the bitmap
 95    *
 96    * @param int $offset offset
 97    * @return bool does the offset exist
 98    */
 99   public function offsetExists($offset) {
100     return is_int($offset) && $offset >= 0 && $offset < $this->length;
101   }
102   
103   /**
104    * Get bit at given offset
105    *
106    * @param int $offset offset
107    * @return bool bit at given offset
108    */
109   public function offsetGet($offset)
110     {
111         if ($this->offsetExists($offset)) {
112             return (bool) (ord($this->bitmap[(int) ($offset / 8)]) & (1 << $offset % 8));
113         } else {
114             throw new \OutOfRangeException();
115         }
116     }
117   
118   /**
119    * Set bit at given offset
120    *
121    * @param int $offset offset
122    * @param bool $value bit at given offset
123    */
124   public function offsetSet($offset, $value)
125     {
126         if ($this->offsetExists($offset)) {
127             $index = (int) ($offset / 8);
128             if ($value) {
129                 $this->bitmap[$index] = chr(ord($this->bitmap[$index]) | (1 << $offset % 8));
130             } else {
131                 $this->bitmap[$index] = chr(ord($this->bitmap[$index]) & ~(1 << $offset % 8));
132             }
133         } else {
134             throw new \OutOfRangeException();
135         }
136     }
137   
138   /**
139    * Unset bit at given offset - not implemented
140    *
141    * @throws RuntimeException always
142    */
143   public function offsetUnset($offset) {
144     throw new \RuntimeException("Bitmap does not support offsetUnset");
145   }
146   
147   // Countable interface
148   
149   /**
150    * Return bitmap length
151    *
152    * @return int bitmap length
153    */
154   public function count() {
155     return $this->length;
156   }
157 }
158 
API documentation generated by ApiGen