diff --git a/b3d.lua b/b3d.lua index 4ccb8bc..61b3c0e 100644 --- a/b3d.lua +++ b/b3d.lua @@ -1,6 +1,8 @@ -- Localize globals local assert, error, math, modlib, next, pairs, setmetatable, table = assert, error, math, modlib, next, pairs, setmetatable, table +local read_int, read_single = modlib.binary.read_int, modlib.binary.read_single + -- Set environment local _ENV = {} setfenv(1, _ENV) @@ -21,11 +23,7 @@ function read(stream) end local function int() - local value = byte() + byte() * 0x100 + byte() * 0x10000 + byte() * 0x1000000 - if value >= 2^31 then - return value - 2^32 - end - return value + return read_int(byte, 4) end local function id() @@ -52,7 +50,6 @@ function read(stream) end end - local read_single = modlib.binary.read_single local function float() return read_single(byte) end diff --git a/binary.lua b/binary.lua index c8d7f47..417f308 100644 --- a/binary.lua +++ b/binary.lua @@ -66,6 +66,15 @@ function read_uint(read_byte, bytes) return uint end +function read_int(read_byte, bytes) + local uint = read_uint(read_byte, bytes) + local max = 0x100 ^ bytes + if uint >= max / 2 then + return uint - max + end + return uint +end + function write_uint(write_byte, uint, bytes) for _ = 1, bytes do write_byte(uint % 0x100) @@ -74,6 +83,17 @@ function write_uint(write_byte, uint, bytes) assert(uint == 0) end +function write_int(write_byte, int, bytes) + local max = 0x100 ^ bytes / 2 + if int < 0 then + -- No bound checking is needed: If the int is too small, the uint will be too big + int = max - int + else + assert(int < max) + end + return write_uint(write_byte, int, bytes) +end + --: on_write function(double) --: double set to true to force f64, false for f32, nil for auto function write_float(write_byte, number, on_write, double)