~earboxer/bare-mess-php

7de6200aca29a59eaecd74db1616f65ecb2db8d9 — Zach DeCook 1 year, 11 months ago 5299c3e
Is: Fix implementation

(With better testing for I8, I16, and I64)
2 files changed, 54 insertions(+), 9 deletions(-)

M src/I.php
M tests/PrimitivesTest.php
M src/I.php => src/I.php +20 -5
@@ 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;
    }

M tests/PrimitivesTest.php => tests/PrimitivesTest.php +34 -4
@@ 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()