mirror of
https://github.com/appgurueu/modlib.git
synced 2024-11-26 17:23:45 +01:00
Add binary module to reduce code duplication
This commit is contained in:
parent
7a92f3b492
commit
2005754a46
29
b3d.lua
29
b3d.lua
@ -45,34 +45,9 @@ function read(stream)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local read_single = modlib.binary.read_single
|
||||||
local function float()
|
local function float()
|
||||||
-- TODO properly truncate to single floating point
|
return read_single(byte)
|
||||||
local byte_4, byte_3, byte_2, byte_1 = byte(), byte(), byte(), byte()
|
|
||||||
local sign = 1
|
|
||||||
if byte_1 >= 0x80 then
|
|
||||||
sign = -1
|
|
||||||
byte_1 = byte_1 - 0x80
|
|
||||||
end
|
|
||||||
local exponent = byte_1 * 2
|
|
||||||
if byte_2 >= 0x80 then
|
|
||||||
exponent = exponent + 1
|
|
||||||
byte_2 = byte_2 - 0x80
|
|
||||||
end
|
|
||||||
local mantissa = ((((byte_4 / 0x100) + byte_3) / 0x100) + byte_2) / 0x80
|
|
||||||
if exponent == 0xFF then
|
|
||||||
if mantissa == 0 then
|
|
||||||
return sign * math.huge
|
|
||||||
end
|
|
||||||
-- Differentiating quiet and signalling nan is not possible in Lua, hence we don't have to do it
|
|
||||||
-- HACK ((0/0)^1) yields nan, 0/0 yields -nan
|
|
||||||
return sign == 1 and ((0/0)^1) or 0/0
|
|
||||||
end
|
|
||||||
assert(mantissa < 1)
|
|
||||||
if exponent == 0 then
|
|
||||||
-- subnormal value
|
|
||||||
return sign * 2^-126 * mantissa
|
|
||||||
end
|
|
||||||
return sign * 2 ^ (exponent - 127) * (1 + mantissa)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function float_array(length)
|
local function float_array(length)
|
||||||
|
115
binary.lua
Normal file
115
binary.lua
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
-- All little endian
|
||||||
|
|
||||||
|
--+ Reads doubles (f64) or floats (f32)
|
||||||
|
--: double reads an f64 if true, f32 otherwise
|
||||||
|
function read_float(read_byte, double)
|
||||||
|
-- First read the mantissa
|
||||||
|
local mantissa = 0
|
||||||
|
for _ = 1, double and 6 or 2 do
|
||||||
|
mantissa = (mantissa + read_byte()) / 0x100
|
||||||
|
end
|
||||||
|
-- Second and first byte in big endian: last bit of exponent + 7 bits of mantissa, sign bit + 7 bits of exponent
|
||||||
|
local byte_2, byte_1 = read_byte(), read_byte()
|
||||||
|
local sign = 1
|
||||||
|
if byte_1 >= 0x80 then
|
||||||
|
sign = -1
|
||||||
|
byte_1 = byte_1 - 0x80
|
||||||
|
end
|
||||||
|
local exponent = byte_1 * 2
|
||||||
|
if byte_2 >= 0x80 then
|
||||||
|
exponent = exponent + 1
|
||||||
|
byte_2 = byte_2 - 0x80
|
||||||
|
end
|
||||||
|
mantissa = (mantissa + byte_2) / 0x80
|
||||||
|
if exponent == 0xFF then
|
||||||
|
if mantissa == 0 then
|
||||||
|
return sign * math.huge
|
||||||
|
end
|
||||||
|
-- Differentiating quiet and signalling nan is not possible in Lua, hence we don't have to do it
|
||||||
|
-- HACK ((0/0)^1) yields nan, 0/0 yields -nan
|
||||||
|
return sign == 1 and ((0/0)^1) or 0/0
|
||||||
|
end
|
||||||
|
assert(mantissa < 1)
|
||||||
|
if exponent == 0 then
|
||||||
|
-- subnormal value
|
||||||
|
return sign * 2^-126 * mantissa
|
||||||
|
end
|
||||||
|
return sign * 2 ^ (exponent - 127) * (1 + mantissa)
|
||||||
|
end
|
||||||
|
|
||||||
|
--+ Reads a single floating point number (f32)
|
||||||
|
function read_single(read_byte)
|
||||||
|
return read_float(read_byte)
|
||||||
|
end
|
||||||
|
|
||||||
|
--+ Reads a double (f64)
|
||||||
|
function read_double(read_byte)
|
||||||
|
return read_float(read_byte, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function read_uint(read_byte, bytes)
|
||||||
|
local factor = 1
|
||||||
|
local uint = 0
|
||||||
|
for _ = 1, bytes do
|
||||||
|
uint = uint + read_byte() * factor
|
||||||
|
factor = factor * 0x100
|
||||||
|
end
|
||||||
|
return uint
|
||||||
|
end
|
||||||
|
|
||||||
|
function write_uint(write_byte, uint, bytes)
|
||||||
|
for _ = 1, bytes do
|
||||||
|
write_byte(uint % 0x100)
|
||||||
|
uint = math.floor(uint / 0x100)
|
||||||
|
end
|
||||||
|
assert(uint == 0)
|
||||||
|
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)
|
||||||
|
local sign = 0
|
||||||
|
if number < 0 then
|
||||||
|
number = -number
|
||||||
|
sign = 0x80
|
||||||
|
end
|
||||||
|
local mantissa, exponent = math.frexp(number)
|
||||||
|
exponent = exponent + 127
|
||||||
|
if exponent > 1 then
|
||||||
|
-- TODO ensure this deals properly with subnormal numbers
|
||||||
|
mantissa = mantissa * 2 - 1
|
||||||
|
exponent = exponent - 1
|
||||||
|
end
|
||||||
|
local sign_byte = sign + math.floor(exponent / 2)
|
||||||
|
mantissa = mantissa * 0x80
|
||||||
|
local exponent_byte = (exponent % 2) * 0x80 + math.floor(mantissa)
|
||||||
|
mantissa = mantissa % 1
|
||||||
|
local mantissa_bytes = {}
|
||||||
|
-- TODO ensure this check is proper
|
||||||
|
if double == nil then
|
||||||
|
double = mantissa % 2^-23 > 0
|
||||||
|
end
|
||||||
|
if on_write then
|
||||||
|
on_write(double)
|
||||||
|
end
|
||||||
|
local len = double and 6 or 2
|
||||||
|
for index = len, 1, -1 do
|
||||||
|
mantissa = mantissa * 0x100
|
||||||
|
mantissa_bytes[index] = math.floor(mantissa)
|
||||||
|
mantissa = mantissa % 1
|
||||||
|
end
|
||||||
|
assert(mantissa == 0)
|
||||||
|
for index = 1, len do
|
||||||
|
write_byte(mantissa_bytes[index])
|
||||||
|
end
|
||||||
|
write_byte(exponent_byte)
|
||||||
|
write_byte(sign_byte)
|
||||||
|
end
|
||||||
|
|
||||||
|
function write_single(write_byte, number)
|
||||||
|
return write_float(write_byte, number, nil, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
function write_double(write_byte, number)
|
||||||
|
return write_float(write_byte, number, nil, true)
|
||||||
|
end
|
87
bluon.lua
87
bluon.lua
@ -160,48 +160,21 @@ function write(self, object, stream)
|
|||||||
local function byte(byte)
|
local function byte(byte)
|
||||||
stream:write(string.char(byte))
|
stream:write(string.char(byte))
|
||||||
end
|
end
|
||||||
|
local write_uint = modlib.binary.write_uint
|
||||||
local function uint(type, uint)
|
local function uint(type, uint)
|
||||||
for _ = 1, uint_widths[type] do
|
write_uint(byte, uint, uint_widths[type])
|
||||||
byte(uint % 0x100)
|
|
||||||
uint = math.floor(uint / 0x100)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
local function uint_with_type(base, _uint)
|
local function uint_with_type(base, _uint)
|
||||||
local type_offset = uint_type(_uint)
|
local type_offset = uint_type(_uint)
|
||||||
byte(base + type_offset)
|
byte(base + type_offset)
|
||||||
uint(type_offset, _uint)
|
uint(type_offset, _uint)
|
||||||
end
|
end
|
||||||
local function float(number)
|
local write_float = modlib.binary.write_float
|
||||||
local sign = 0
|
local function float_on_write(double)
|
||||||
if number < 0 then
|
|
||||||
number = -number
|
|
||||||
sign = 0x80
|
|
||||||
end
|
|
||||||
local mantissa, exponent = math.frexp(number)
|
|
||||||
exponent = exponent + 127
|
|
||||||
if exponent > 1 then
|
|
||||||
-- TODO ensure this deals properly with subnormal numbers
|
|
||||||
mantissa = mantissa * 2 - 1
|
|
||||||
exponent = exponent - 1
|
|
||||||
end
|
|
||||||
local sign_byte = sign + math.floor(exponent / 2)
|
|
||||||
mantissa = mantissa * 0x80
|
|
||||||
local exponent_byte = (exponent % 2) * 0x80 + math.floor(mantissa)
|
|
||||||
mantissa = mantissa % 1
|
|
||||||
local mantissa_bytes = {}
|
|
||||||
-- TODO ensure this check is proper
|
|
||||||
local double = mantissa % 2^-23 > 0
|
|
||||||
byte(double and type_ranges.number or type_ranges.number_f32)
|
byte(double and type_ranges.number or type_ranges.number_f32)
|
||||||
local len = double and 6 or 2
|
end
|
||||||
for index = len, 1, -1 do
|
local function float(number)
|
||||||
mantissa = mantissa * 0x100
|
write_float(byte, number, float_on_write)
|
||||||
mantissa_bytes[index] = string.char(math.floor(mantissa))
|
|
||||||
mantissa = mantissa % 1
|
|
||||||
end
|
|
||||||
assert(mantissa == 0)
|
|
||||||
stream:write(table.concat(mantissa_bytes))
|
|
||||||
byte(exponent_byte)
|
|
||||||
byte(sign_byte)
|
|
||||||
end
|
end
|
||||||
local aux_write = self.aux_write
|
local aux_write = self.aux_write
|
||||||
local function _write(object)
|
local function _write(object)
|
||||||
@ -285,49 +258,13 @@ function read(self, stream)
|
|||||||
local function byte()
|
local function byte()
|
||||||
return stream_read(1):byte()
|
return stream_read(1):byte()
|
||||||
end
|
end
|
||||||
local function uint(bytes)
|
local read_uint = modlib.binary.read_uint
|
||||||
local factor = 1
|
local function uint(type)
|
||||||
local int = 0
|
return read_uint(byte, uint_widths[type])
|
||||||
for _ = 1, uint_widths[bytes] do
|
|
||||||
int = int + byte() * factor
|
|
||||||
factor = factor * 0x100
|
|
||||||
end
|
|
||||||
return int
|
|
||||||
end
|
end
|
||||||
-- TODO get rid of code duplication (see b3d.lua)
|
local read_float = modlib.binary.read_float
|
||||||
local function float(double)
|
local function float(double)
|
||||||
-- First read the mantissa
|
return read_float(byte, double)
|
||||||
local mantissa = 0
|
|
||||||
for _ = 1, double and 6 or 2 do
|
|
||||||
mantissa = (mantissa + byte()) / 0x100
|
|
||||||
end
|
|
||||||
-- Second and first byte in big endian: last bit of exponent + 7 bits of mantissa, sign bit + 7 bits of exponent
|
|
||||||
local byte_2, byte_1 = byte(), byte()
|
|
||||||
local sign = 1
|
|
||||||
if byte_1 >= 0x80 then
|
|
||||||
sign = -1
|
|
||||||
byte_1 = byte_1 - 0x80
|
|
||||||
end
|
|
||||||
local exponent = byte_1 * 2
|
|
||||||
if byte_2 >= 0x80 then
|
|
||||||
exponent = exponent + 1
|
|
||||||
byte_2 = byte_2 - 0x80
|
|
||||||
end
|
|
||||||
mantissa = (mantissa + byte_2) / 0x80
|
|
||||||
if exponent == 0xFF then
|
|
||||||
if mantissa == 0 then
|
|
||||||
return sign * math.huge
|
|
||||||
end
|
|
||||||
-- Differentiating quiet and signalling nan is not possible in Lua, hence we don't have to do it
|
|
||||||
-- HACK ((0/0)^1) yields nan, 0/0 yields -nan
|
|
||||||
return sign == 1 and ((0/0)^1) or 0/0
|
|
||||||
end
|
|
||||||
assert(mantissa < 1)
|
|
||||||
if exponent == 0 then
|
|
||||||
-- subnormal value
|
|
||||||
return sign * 2^-126 * mantissa
|
|
||||||
end
|
|
||||||
return sign * 2 ^ (exponent - 127) * (1 + mantissa)
|
|
||||||
end
|
end
|
||||||
local aux_read = self.aux_read
|
local aux_read = self.aux_read
|
||||||
local function _read(type)
|
local function _read(type)
|
||||||
|
1
init.lua
1
init.lua
@ -90,6 +90,7 @@ for _, component in ipairs{
|
|||||||
"kdtree",
|
"kdtree",
|
||||||
"heap",
|
"heap",
|
||||||
"ranked_set",
|
"ranked_set",
|
||||||
|
"binary",
|
||||||
"b3d",
|
"b3d",
|
||||||
"bluon"
|
"bluon"
|
||||||
} do
|
} do
|
||||||
|
Loading…
Reference in New Issue
Block a user