Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch introduces a simple BitSet class that can be used to handle boolean flags. Releases: master Resolves: #87665 Change-Id: I32911ed1213421ef30596c2aceb4b8cbd27a8a45 Reviewed-on: https://review.typo3.org/c/59650 Tested-by: TYPO3com <noreply@typo3.com> Tested-by: Susanne Moog <susanne.moog@typo3.org> Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de> Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Reviewed-by: Oliver Klee <typo3-coding@oliverklee.de> Reviewed-by: Susanne Moog <susanne.moog@typo3.org> Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de> Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
- Loading branch information
1 parent
9116fcd
commit 81ddfe4
Showing
3 changed files
with
249 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<?php | ||
declare(strict_types = 1); | ||
|
||
/* | ||
* This file is part of the TYPO3 CMS project. | ||
* | ||
* It is free software; you can redistribute it and/or modify it under | ||
* the terms of the GNU General Public License, either version 2 | ||
* of the License, or any later version. | ||
* | ||
* For the full copyright and license information, please read the | ||
* LICENSE.txt file that was distributed with this source code. | ||
* | ||
* The TYPO3 project - inspiring people to share! | ||
*/ | ||
|
||
namespace TYPO3\CMS\Core\DataStructure; | ||
|
||
/** | ||
* Class TYPO3\CMS\Core\DataStructure\BitSet | ||
*/ | ||
class BitSet | ||
{ | ||
/** | ||
* @var int | ||
*/ | ||
private $set; | ||
|
||
/** | ||
* @param int $set | ||
*/ | ||
public function __construct(int $set = 0) | ||
{ | ||
$this->set = $set; | ||
} | ||
|
||
/** | ||
* @param int $bitIndex | ||
*/ | ||
public function set(int $bitIndex): void | ||
{ | ||
$this->set |= $bitIndex; | ||
} | ||
|
||
/** | ||
* @param int $bitIndex | ||
* @param bool $value | ||
*/ | ||
public function setValue(int $bitIndex, bool $value): void | ||
{ | ||
if ($value) { | ||
$this->set($bitIndex); | ||
} else { | ||
$this->unset($bitIndex); | ||
} | ||
} | ||
|
||
/** | ||
* @param int $bitIndex | ||
*/ | ||
public function unset(int $bitIndex): void | ||
{ | ||
$this->set &= ~$bitIndex; | ||
} | ||
|
||
/** | ||
* @param int $bitIndex | ||
* @return bool | ||
*/ | ||
public function get(int $bitIndex): bool | ||
{ | ||
return ($bitIndex & $this->set) === $bitIndex; | ||
} | ||
} |
87 changes: 87 additions & 0 deletions
87
...sext/core/Documentation/Changelog/master/Feature-87665-IntroduceBitSetClass.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
.. include:: ../../Includes.txt | ||
|
||
======================================== | ||
Feature: #87665 - Introduce BitSet class | ||
======================================== | ||
|
||
See :issue:`87665` | ||
|
||
Description | ||
=========== | ||
|
||
To efficiently handle boolean flags, bit sets can be used. Therefore a new class :php:`\TYPO3\CMS\Core\DataStructure\BitSet` has been introduced. | ||
The bit set can be used standalone and accessed from the outside but it can also be used to create specific BitSet classes that extend the BitSet class. | ||
|
||
The functionality is best described by an example: | ||
|
||
:: | ||
|
||
<?php | ||
declare(strict_types = 1); | ||
|
||
define('PERMISSIONS_NONE', 0b0); // 0 | ||
define('PERMISSIONS_PAGE_SHOW', 0b1); // 1 | ||
define('PERMISSIONS_PAGE_EDIT', 0b10); // 2 | ||
define('PERMISSIONS_PAGE_DELETE', 0b100); // 4 | ||
define('PERMISSIONS_PAGE_NEW', 0b1000); // 8 | ||
define('PERMISSIONS_CONTENT_EDIT', 0b10000); // 16 | ||
define('PERMISSIONS_ALL', 0b11111); // 31 | ||
|
||
$bitSet = new \TYPO3\CMS\Core\DataStructure\BitSet(PERMISSIONS_PAGE_SHOW | PERMISSIONS_PAGE_NEW); | ||
$bitSet->get(PERMISSIONS_PAGE_SHOW); // true | ||
$bitSet->get(PERMISSIONS_CONTENT_EDIT); // false | ||
|
||
Another example shows how to possibly extend the :php:`\TYPO3\CMS\Core\DataStructure\BitSet` class. | ||
|
||
:: | ||
|
||
<?php | ||
declare(strict_types = 1); | ||
|
||
class Permissions extends \TYPO3\CMS\Core\DataStructure\BitSet | ||
{ | ||
public const NONE = 0b0; // 0 | ||
public const PAGE_SHOW = 0b1; // 1 | ||
public const PAGE_EDIT = 0b10; // 2 | ||
public const PAGE_DELETE = 0b100; // 4 | ||
public const PAGE_NEW = 0b1000; // 8 | ||
public const CONTENT_EDIT = 0b10000; // 16 | ||
public const ALL = 0b11111; // 31 | ||
|
||
/** | ||
* @param int $permission | ||
* @return bool | ||
*/ | ||
public function hasPermission(int $permission): bool | ||
{ | ||
return $this->get($permission); | ||
} | ||
|
||
/** | ||
* @return bool | ||
*/ | ||
public function hasAllPermissions(): bool | ||
{ | ||
return $this->get(static::ALL); | ||
} | ||
|
||
/** | ||
* @param int $permission | ||
*/ | ||
public function allow(int $permission): void | ||
{ | ||
$this->set($permission); | ||
} | ||
} | ||
|
||
$permissions = new Permissions(Permissions::PAGE_SHOW | Permissions::PAGE_NEW); | ||
$permissions->hasPermission(Permissions::PAGE_SHOW); // true | ||
$permissions->hasPermission(Permissions::CONTENT_EDIT); // false | ||
|
||
|
||
Impact | ||
====== | ||
|
||
This class may come in handy in all situations where boolean flags need to be managed in an efficient way. | ||
|
||
.. index:: PHP-API, ext:core |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
<?php | ||
declare(strict_types = 1); | ||
|
||
/* | ||
* This file is part of the TYPO3 CMS project. | ||
* | ||
* It is free software; you can redistribute it and/or modify it under | ||
* the terms of the GNU General Public License, either version 2 | ||
* of the License, or any later version. | ||
* | ||
* For the full copyright and license information, please read the | ||
* LICENSE.txt file that was distributed with this source code. | ||
* | ||
* The TYPO3 project - inspiring people to share! | ||
*/ | ||
|
||
namespace TYPO3\CMS\Core\Tests\Unit\DataStructure; | ||
|
||
use TYPO3\CMS\Core\DataStructure\BitSet; | ||
use TYPO3\TestingFramework\Core\Unit\UnitTestCase; | ||
|
||
/** | ||
* Class TYPO3\CMS\Core\Tests\Unit\DataStructure\BitSetTest | ||
*/ | ||
class BitSetTest extends UnitTestCase | ||
{ | ||
/** | ||
* @test | ||
*/ | ||
public function defaultBitSetOnlyHasZeroByteSet(): void | ||
{ | ||
$bitSet = new BitSet(); | ||
static::assertTrue($bitSet->get(0b0)); | ||
static::assertFalse($bitSet->get(0b1)); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function constructorSetsInternalSet(): void | ||
{ | ||
$bitSet = new BitSet(0b1 | 0b100); | ||
static::assertTrue($bitSet->get(0b1)); | ||
static::assertTrue($bitSet->get(0b100)); | ||
static::assertFalse($bitSet->get(0b10)); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function setSetsBit(): void | ||
{ | ||
$bitSet = new BitSet(0b101); | ||
static::assertTrue($bitSet->get(0b1)); | ||
static::assertTrue($bitSet->get(0b100)); | ||
static::assertFalse($bitSet->get(0b10)); | ||
|
||
$bitSet->set(0b10); | ||
static::assertTrue($bitSet->get(0b10)); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function setValueSetsBit(): void | ||
{ | ||
$bitSet = new BitSet(); | ||
static::assertFalse($bitSet->get(0b1)); | ||
|
||
$bitSet->setValue(0b1, true); | ||
static::assertTrue($bitSet->get(0b1)); | ||
|
||
$bitSet->setValue(0b1, false); | ||
static::assertFalse($bitSet->get(0b1)); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function clearUnsetsBit(): void | ||
{ | ||
$bitSet = new BitSet(0b111); | ||
$bitSet->unset(0b10); | ||
static::assertTrue($bitSet->get(0b1)); | ||
static::assertTrue($bitSet->get(0b100)); | ||
static::assertFalse($bitSet->get(0b10)); | ||
} | ||
} |