Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
Struct = {}
|
|
|
|
|
|
|
|
function Struct.pack(format, ...)
|
2015-05-19 13:13:14 +02:00
|
|
|
local stream = {}
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
local vars = {...}
|
|
|
|
local endianness = true
|
|
|
|
|
2015-05-19 18:50:02 +02:00
|
|
|
for i = 1, format:len() do
|
|
|
|
local opt = format:sub(i, i)
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
|
2015-05-19 18:50:02 +02:00
|
|
|
if opt == '>' then
|
|
|
|
endianness = false
|
|
|
|
elseif opt:find('[bBhHiIlL]') then
|
|
|
|
local n = opt:find('[hH]') and 2 or opt:find('[iI]') and 4 or opt:find('[lL]') and 8 or 1
|
2015-05-19 13:13:14 +02:00
|
|
|
local val = tonumber(table.remove(vars, 1))
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
|
|
|
|
if val < 0 then
|
|
|
|
val = val + 2 ^ (n * 8 - 1)
|
|
|
|
end
|
|
|
|
|
2015-05-19 13:13:14 +02:00
|
|
|
local bytes = {}
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
for j = 1, n do
|
2015-05-19 13:13:14 +02:00
|
|
|
table.insert(bytes, string.char(val % (2 ^ 8)))
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
val = math.floor(val / (2 ^ 8))
|
|
|
|
end
|
|
|
|
|
|
|
|
if not endianness then
|
2015-05-19 13:13:14 +02:00
|
|
|
table.insert(stream, string.reverse(table.concat(bytes)))
|
|
|
|
else
|
|
|
|
table.insert(stream, table.concat(bytes))
|
|
|
|
end
|
2015-05-19 18:50:02 +02:00
|
|
|
elseif opt:find('[fd]') then
|
2015-05-19 13:13:14 +02:00
|
|
|
local val = tonumber(table.remove(vars, 1))
|
|
|
|
local sign = 0
|
|
|
|
|
|
|
|
if val < 0 then
|
|
|
|
sign = 1
|
|
|
|
val = -val
|
|
|
|
end
|
|
|
|
|
|
|
|
local mantissa, exponent = math.frexp(val)
|
|
|
|
if val == 0 then
|
|
|
|
mantissa = 0
|
|
|
|
exponent = 0
|
|
|
|
else
|
|
|
|
mantissa = (mantissa * 2 - 1) * math.ldexp(0.5, (opt == 'd') and 53 or 24)
|
|
|
|
exponent = exponent + ((opt == 'd') and 1022 or 126)
|
|
|
|
end
|
|
|
|
|
|
|
|
local bytes = {}
|
|
|
|
if opt == 'd' then
|
|
|
|
val = mantissa
|
|
|
|
for i = 1, 6 do
|
|
|
|
table.insert(bytes, string.char(math.floor(val) % (2 ^ 8)))
|
|
|
|
val = math.floor(val / (2 ^ 8))
|
|
|
|
end
|
|
|
|
else
|
|
|
|
table.insert(bytes, string.char(math.floor(mantissa) % (2 ^ 8)))
|
|
|
|
val = math.floor(mantissa / (2 ^ 8))
|
|
|
|
table.insert(bytes, string.char(math.floor(val) % (2 ^ 8)))
|
|
|
|
val = math.floor(val / (2 ^ 8))
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
end
|
|
|
|
|
2015-05-19 13:13:14 +02:00
|
|
|
table.insert(bytes, string.char(math.floor(exponent * ((opt == 'd') and 16 or 128) + val) % (2 ^ 8)))
|
|
|
|
val = math.floor((exponent * ((opt == 'd') and 16 or 128) + val) / (2 ^ 8))
|
|
|
|
table.insert(bytes, string.char(math.floor(sign * 128 + val) % (2 ^ 8)))
|
|
|
|
val = math.floor((sign * 128 + val) / (2 ^ 8))
|
|
|
|
|
|
|
|
if not endianness then
|
|
|
|
table.insert(stream, string.reverse(table.concat(bytes)))
|
|
|
|
else
|
|
|
|
table.insert(stream, table.concat(bytes))
|
|
|
|
end
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
elseif opt == 's' then
|
2015-05-19 13:13:14 +02:00
|
|
|
table.insert(stream, tostring(table.remove(vars, 1)))
|
|
|
|
table.insert(stream, string.char(0))
|
2015-05-19 18:50:02 +02:00
|
|
|
elseif opt == 'c' then
|
|
|
|
local n = format:sub(i + 1):match('%d+')
|
|
|
|
local length = tonumber(n)
|
|
|
|
|
|
|
|
if length > 0 then
|
|
|
|
local str = tostring(table.remove(vars, 1))
|
|
|
|
if length - str:len() > 0 then
|
|
|
|
str = str .. string.rep(' ', length - str:len())
|
|
|
|
end
|
|
|
|
table.insert(stream, str:sub(1, length))
|
|
|
|
end
|
|
|
|
i = i + n:len()
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-05-19 13:13:14 +02:00
|
|
|
return table.concat(stream)
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
function Struct.unpack(format, stream)
|
|
|
|
local vars = {}
|
2015-05-19 13:13:14 +02:00
|
|
|
local iterator = 1
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
local endianness = true
|
|
|
|
|
2015-05-19 18:50:02 +02:00
|
|
|
for i = 1, format:len() do
|
|
|
|
local opt = format:sub(i, i)
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
|
2015-05-19 18:50:02 +02:00
|
|
|
if opt == '>' then
|
|
|
|
endianness = false
|
|
|
|
elseif opt:find('[bBhHiIlL]') then
|
|
|
|
local n = opt:find('[hH]') and 2 or opt:find('[iI]') and 4 or opt:find('[lL]') and 8 or 1
|
|
|
|
local signed = opt:lower() == opt
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
|
|
|
|
local val = 0
|
|
|
|
for j = 1, n do
|
2015-05-19 18:50:02 +02:00
|
|
|
local byte = string.byte(stream:sub(iterator, iterator))
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
if endianness then
|
|
|
|
val = val + byte * (2 ^ ((j - 1) * 8))
|
|
|
|
else
|
|
|
|
val = val + byte * (2 ^ ((n - j) * 8))
|
|
|
|
end
|
2015-05-19 13:13:14 +02:00
|
|
|
iterator = iterator + 1
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
if signed then
|
|
|
|
val = val - 2 ^ (n * 8 - 1)
|
|
|
|
end
|
|
|
|
|
|
|
|
table.insert(vars, val)
|
2015-05-19 18:50:02 +02:00
|
|
|
elseif opt:find('[fd]') then
|
2015-05-19 13:13:14 +02:00
|
|
|
local n = (opt == 'd') and 8 or 4
|
2015-05-19 18:50:02 +02:00
|
|
|
local x = stream:sub(iterator, iterator + n - 1)
|
2015-05-19 13:13:14 +02:00
|
|
|
iterator = iterator + n
|
|
|
|
|
|
|
|
if not endianness then
|
|
|
|
x = string.reverse(x)
|
|
|
|
end
|
|
|
|
|
|
|
|
local sign = 1
|
|
|
|
local mantissa = string.byte(x, (opt == 'd') and 7 or 3) % ((opt == 'd') and 16 or 128)
|
|
|
|
for i = n - 2, 1, -1 do
|
|
|
|
mantissa = mantissa * (2 ^ 8) + string.byte(x, i)
|
|
|
|
end
|
|
|
|
|
|
|
|
if string.byte(x, n) > 127 then
|
|
|
|
sign = -1
|
|
|
|
end
|
|
|
|
|
|
|
|
local exponent = (string.byte(x, n) % 128) * ((opt == 'd') and 16 or 2) + math.floor(string.byte(x, n - 1) / ((opt == 'd') and 16 or 128))
|
|
|
|
if exponent == 0 then
|
|
|
|
table.insert(vars, 0.0)
|
|
|
|
else
|
|
|
|
mantissa = (math.ldexp(mantissa, (opt == 'd') and -52 or -23) + 1) * sign
|
|
|
|
table.insert(vars, math.ldexp(mantissa, exponent - ((opt == 'd') and 1023 or 127)))
|
|
|
|
end
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
elseif opt == 's' then
|
2015-05-19 13:13:14 +02:00
|
|
|
local bytes = {}
|
2015-05-19 18:50:02 +02:00
|
|
|
for j = iterator, stream:len() do
|
|
|
|
if stream:sub(j, j) == string.char(0) then
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
break
|
|
|
|
end
|
|
|
|
|
2015-05-19 18:50:02 +02:00
|
|
|
table.insert(bytes, stream:sub(j, j))
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
end
|
|
|
|
|
2015-05-19 13:13:14 +02:00
|
|
|
local str = table.concat(bytes)
|
2015-05-19 18:50:02 +02:00
|
|
|
iterator = iterator + str:len() + 1
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
table.insert(vars, str)
|
2015-05-19 18:50:02 +02:00
|
|
|
elseif opt == 'c' then
|
|
|
|
local n = format:sub(i + 1):match('%d+')
|
|
|
|
table.insert(vars, stream:sub(iterator, iterator + tonumber(n)))
|
|
|
|
iterator = iterator + tonumber(n)
|
|
|
|
i = i + n:len()
|
Add binary operations for lua
This is something I was always missing - posibbility to operate on
binary files or streams in pure lua. In most cases we do only need to
read simple variables from files such as integers with different amount
of bytes. This "class" will provide that ability.
It's a simple implementation of following C module for lua:
http://www.inf.puc-rio.br/~roberto/struct/
It has much less, though. Following elements have been implemented:
">" flag to set mode to big endian.
"<" flag to set mode to little endian.
"b" a signed char.
"B" an unsigned char.
"h" a signed short (2 bytes).
"H" an unsigned short (2 bytes).
"i" a signed int (4 bytes).
"I" an unsigned int (4 bytes).
"l" a signed long (8 bytes).
"L" an unsigned long (8 bytes).
"s" a zero-terminated string.
An example how to use it:
```lua
local packed = Struct.pack('<LIhBsb', 123456789123456789, 123456789,
-3200, 255, 'Test message', -1)
-- packed is now a lua string we can save to file as binary data
local L, I, h, B, s, b = Struct.unpack('<LIhBsb', packed)
print(L, I, h, B, s, b)
```
You can use g_resources.readFileContents as function to read binary
files and parse them via this class.
2015-05-18 21:31:16 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return unpack(vars)
|
|
|
|
end
|