@@ 0,0 1,44 @@
+<?php
+
+namespace BareMess;
+
+class UInt
+{
+ use Mutatable;
+ private int $value = 0;
+
+ public function __construct(& $mess = null)
+ {
+ if ($mess === null){
+ return;
+ }
+ $this->value = 0;
+ for($i = 0; $i < strlen($mess); $i++) {
+ // Least significant bits first
+ $this->value += (ord($mess[$i]) & 0b01111111) << (7 * $i);
+ if(! (ord($mess[$i]) & 0b10000000) ) {
+ $mess = substr($mess, $i + 1);
+ return;
+ }
+ }
+ }
+
+ public function mess()
+ {
+ $mess = '';
+ // The number of bytes should be greater than or equal to the number required,
+ // value < pow(2, 7 * bytes)
+ $bytes = floor(log($this->value + 1, 2) / 7) + 1;
+
+ for ($i = 0; $i < $bytes; $i++) {
+ // BARE encodes integers as little-endian (least significant first),
+ $bits = ($this->value >> ($i * 7)) & 0b01111111;
+ // with the most significant bit being set for all except the last byte.
+ if ($i != $bytes - 1) {
+ $bits = $bits | 0b10000000;
+ }
+ $mess .= chr($bits);
+ }
+ return $mess;
+ }
+}
@@ 6,6 6,7 @@ use BareMess\Bare;
use BareMess\Example\PublicKey;
use BareMess\{I8,I16,I32,I64};
use BareMess\{U8,U16,U32,U64};
+use BareMess\UInt;
use PHPUnit\Framework\TestCase;
class PrimitivesTest extends TestCase
@@ 87,6 88,43 @@ class PrimitivesTest extends TestCase
// TODO: Test strings longer than 127 characters
}
+ public function testUInt()
+ {
+ // Various equivalent uints.
+ $mess = "\xC2\x80\x00\xC2\x00\x42";
+ $uint = new UInt($mess);
+ $uint2 = new UInt($mess);
+ $uint3 = new UInt($mess);
+ $this->assertEquals('', $mess);
+ $this->assertEquals(66, $uint->get());
+ $this->assertEquals(66, $uint2->get());
+ $this->assertEquals(66, $uint3->get());
+ $this->assertEquals("\x42", $uint->mess());
+ $this->assertEquals("\x42", $uint2->mess());
+ $this->assertEquals("\x42", $uint3->mess());
+
+ $uint->set(0);
+ $this->assertEquals("\x00", $uint->mess());
+
+ // This is usually equal to PHP_INT_MAX
+ $sixtythreeBitNumber = 0x7FFFFFFFFFFFFFFF;
+ $mess = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F";
+ $uint = new UInt($mess);
+ $this->assertEquals("", $mess);
+ $this->assertEquals($sixtythreeBitNumber, $uint->get());
+ $mess = $uint->mess();
+ $uint2 = new UInt($mess);
+ $this->assertEquals('', $mess);
+ $this->assertEquals($sixtythreeBitNumber, $uint2->get());
+
+ // Test round-tripping with mess (since these have multiple representations).
+ $uint->set(pow(2,7*8));
+ $mess = $uint->mess();
+ $uint2 = new UInt($mess);
+ $this->assertEquals("", $mess);
+ $this->assertEquals(pow(2, 7*8), $uint2->get());
+ }
+
public function testUs()
{
$u8 = new U8();