@@ 7,18 7,33 @@ abstract class I
use Mutatable;
private int $value = 0;
+ public function __construct(& $mess = null)
+ {
+ if ($mess !== null) {
+ $padded = str_pad($mess, 8, "\x00");
+ // TODO: Fix storing PHP_INT_MIN and other >63-bit integers.
+ $uval = unpack("P", $padded)[1];
+ $this->value = $uval;
+ if ($uval >= pow(2,(8*get_called_class()::BYTES)-1)) {
+ // Complement.
+ $this->value -= pow(2, 8*get_called_class()::BYTES);
+ }
+ $mess = substr($mess, get_called_class()::BYTES);
+ }
+ }
public function mess()
{
$mess = '';
for ($i = 0; $i < get_called_class()::BYTES; $i++) {
// BARE encodes integers as little-endian (least significant first).
+ $uval = $this->value;
// Twos complement.
- if ($this->value <= 0) {
- // chr makes binary string of least significant byte.
- $mess .= chr(abs($this->value) >> ($i * 8));
- } else {
- $mess .= chr(0xFF - (($this->value - 1) >> ($i * 8)) );
+ if ($this->value < 0) {
+ // TODO: Support >63-bit integers.
+ $uval = $this->value + pow(2, 8*get_called_class()::BYTES);
}
+ // chr makes binary string of least significant byte.
+ $mess .= chr($uval >> ($i * 8));
}
return $mess;
}
@@ 135,9 135,9 @@ class PrimitivesTest extends TestCase
$i8 = new I8();
$this->assertEquals("\0", $i8->mess());
$i8->set(1);
- $this->assertEquals("\xFF", $i8->mess());
+ $this->assertEquals("\x01", $i8->mess(), "Failed encoding I8 1.");
$i8->set(-1);
- $this->assertEquals("\x01", $i8->mess());
+ $this->assertEquals("\xFF", $i8->mess(), "Failed encoding I8 -1.");
$i64 = new I64();
$this->assertEquals(0, $i64->get());
@@ 145,7 145,7 @@ class PrimitivesTest extends TestCase
$i64->set(0x7FFFFFFFFFFFFFFF);
// Twos complement max int looks like 0b1000...0001,
// note that this is little endian.
- $this->assertEquals("\x01\0\0\0\0\0\0\x80", $i64->mess());
+ $this->assertEquals("\xff\xff\xff\xff\xff\xff\xff\x7f", $i64->mess());
// Smallest representable value
$i64->set(-1 << 63);
@@ 153,7 153,37 @@ class PrimitivesTest extends TestCase
$this->assertEquals("\0\0\0\0\0\0\0\x80", $i64->mess());
$i64->set(1);
- $this->assertEquals("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", $i64->mess());
+ $this->assertEquals("\x01\x00\x00\x00\x00\x00\x00\x00", $i64->mess());
+
+ // Example Values
+ $mess = "\x00\x00";
+ $i16 = new I16($mess);
+ $this->assertEquals("", $mess, "Failed to read mess");
+ $this->assertEquals(0, $i16->get());
+ $this->assertEquals("\x00\x00", $i16->mess(), "Failed to create mess");
+ $mess = "\x01\x00";
+ $i16 = new I16($mess);
+ $this->assertEquals("", $mess);
+ $this->assertEquals(1, $i16->get(), "Failed to decode I16 1");
+ $this->assertEquals("\x01\x00", $i16->mess(), "Failed to encode I16 1");
+
+ $mess = "\xFF\xFF";
+ $i16 = new I16($mess);
+ $this->assertEquals("", $mess);
+ $this->assertEquals(-1, $i16->get());
+ $this->assertEquals("\xFF\xFF", $i16->mess());
+
+ $mess = "\xFF\x00";
+ $i16 = new I16($mess);
+ $this->assertEquals("", $mess);
+ $this->assertEquals(255, $i16->get());
+ $this->assertEquals("\xFF\x00", $i16->mess());
+
+ $mess = "\x01\xFF";
+ $i16 = new I16($mess);
+ $this->assertEquals("", $mess);
+ $this->assertEquals(-255, $i16->get());
+ $this->assertEquals("\x01\xFF", $i16->mess(), "Failed to encode I16 -255");
}
public function testString()