mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
671 lines
18 KiB
Lua
671 lines
18 KiB
Lua
--[[
|
|
| This file was obtained through the combined efforts
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
|
|
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
|
|
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
|
--]]
|
|
|
|
local math_huge = math.huge
|
|
local math_frexp = math.frexp
|
|
local math_ldexp = math.ldexp
|
|
local math_floor = math.floor
|
|
local math_min = math.min
|
|
local math_max = math.max
|
|
local bit_rshift = bit.rshift
|
|
|
|
--- StringStream type
|
|
-- @name StringStream
|
|
-- @class type
|
|
-- @libtbl ss_methods
|
|
|
|
local ss_methods = {}
|
|
local ss_meta = {
|
|
__index = ss_methods,
|
|
__metatable = "StringStream",
|
|
__tostring = function(self)
|
|
return string.format("Stringstream [%u,%u]", self:tell(), self:size())
|
|
end
|
|
}
|
|
local ss_methods_big = setmetatable({},{__index=ss_methods})
|
|
local ss_meta_big = {
|
|
__index = ss_methods_big,
|
|
__metatable = "StringStream",
|
|
__tostring = function(self)
|
|
return string.format("Stringstream [%u,%u]", self:tell(), self:size())
|
|
end
|
|
}
|
|
|
|
local function StringStream(stream, i, endian)
|
|
local ret = setmetatable({
|
|
index = 1,
|
|
subindex = 1
|
|
}, ss_meta)
|
|
|
|
if stream~=nil then
|
|
assert(isstring(stream), "stream must be a string")
|
|
ret:write(stream)
|
|
if i~=nil then
|
|
assert(isnumber(i), "i must be a number")
|
|
ret:seek(i)
|
|
else
|
|
ret:seek(1)
|
|
end
|
|
end
|
|
if endian~=nil then
|
|
assert(isstring(endian), "endian must be a string")
|
|
ret:setEndian(endian)
|
|
end
|
|
|
|
return ret
|
|
end
|
|
|
|
--Credit https://stackoverflow.com/users/903234/rpfeltz
|
|
--Bugfixes and IEEE754Double credit to me
|
|
local function PackIEEE754Float(number)
|
|
if number == 0 then
|
|
return 0x00, 0x00, 0x00, 0x00
|
|
elseif number == math_huge then
|
|
return 0x00, 0x00, 0x80, 0x7F
|
|
elseif number == -math_huge then
|
|
return 0x00, 0x00, 0x80, 0xFF
|
|
elseif number ~= number then
|
|
return 0x00, 0x00, 0xC0, 0xFF
|
|
else
|
|
local sign = 0x00
|
|
if number < 0 then
|
|
sign = 0x80
|
|
number = -number
|
|
end
|
|
local mantissa, exponent = math_frexp(number)
|
|
exponent = exponent + 0x7F
|
|
if exponent <= 0 then
|
|
mantissa = math_ldexp(mantissa, exponent - 1)
|
|
exponent = 0
|
|
elseif exponent > 0 then
|
|
if exponent >= 0xFF then
|
|
return 0x00, 0x00, 0x80, sign + 0x7F
|
|
elseif exponent == 1 then
|
|
exponent = 0
|
|
else
|
|
mantissa = mantissa * 2 - 1
|
|
exponent = exponent - 1
|
|
end
|
|
end
|
|
mantissa = math_floor(math_ldexp(mantissa, 23) + 0.5)
|
|
return mantissa % 0x100,
|
|
bit_rshift(mantissa, 8) % 0x100,
|
|
(exponent % 2) * 0x80 + bit_rshift(mantissa, 16),
|
|
sign + bit_rshift(exponent, 1)
|
|
end
|
|
end
|
|
local function UnpackIEEE754Float(b4, b3, b2, b1)
|
|
local exponent = (b1 % 0x80) * 0x02 + bit_rshift(b2, 7)
|
|
local mantissa = math_ldexp(((b2 % 0x80) * 0x100 + b3) * 0x100 + b4, -23)
|
|
if exponent == 0xFF then
|
|
if mantissa > 0 then
|
|
return 0 / 0
|
|
else
|
|
if b1 >= 0x80 then
|
|
return -math_huge
|
|
else
|
|
return math_huge
|
|
end
|
|
end
|
|
elseif exponent > 0 then
|
|
mantissa = mantissa + 1
|
|
else
|
|
exponent = exponent + 1
|
|
end
|
|
if b1 >= 0x80 then
|
|
mantissa = -mantissa
|
|
end
|
|
return math_ldexp(mantissa, exponent - 0x7F)
|
|
end
|
|
local function PackIEEE754Double(number)
|
|
if number == 0 then
|
|
return 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
elseif number == math_huge then
|
|
return 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7F
|
|
elseif number == -math_huge then
|
|
return 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF
|
|
elseif number ~= number then
|
|
return 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF
|
|
else
|
|
local sign = 0x00
|
|
if number < 0 then
|
|
sign = 0x80
|
|
number = -number
|
|
end
|
|
local mantissa, exponent = math_frexp(number)
|
|
exponent = exponent + 0x3FF
|
|
if exponent <= 0 then
|
|
mantissa = math_ldexp(mantissa, exponent - 1)
|
|
exponent = 0
|
|
elseif exponent > 0 then
|
|
if exponent >= 0x7FF then
|
|
return 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, sign + 0x7F
|
|
elseif exponent == 1 then
|
|
exponent = 0
|
|
else
|
|
mantissa = mantissa * 2 - 1
|
|
exponent = exponent - 1
|
|
end
|
|
end
|
|
mantissa = math_floor(math_ldexp(mantissa, 52) + 0.5)
|
|
return mantissa % 0x100,
|
|
math_floor(mantissa / 0x100) % 0x100, --can only rshift up to 32 bit numbers. mantissa is too big
|
|
math_floor(mantissa / 0x10000) % 0x100,
|
|
math_floor(mantissa / 0x1000000) % 0x100,
|
|
math_floor(mantissa / 0x100000000) % 0x100,
|
|
math_floor(mantissa / 0x10000000000) % 0x100,
|
|
(exponent % 0x10) * 0x10 + math_floor(mantissa / 0x1000000000000),
|
|
sign + bit_rshift(exponent, 4)
|
|
end
|
|
end
|
|
local function UnpackIEEE754Double(b8, b7, b6, b5, b4, b3, b2, b1)
|
|
local exponent = (b1 % 0x80) * 0x10 + bit_rshift(b2, 4)
|
|
local mantissa = math_ldexp(((((((b2 % 0x10) * 0x100 + b3) * 0x100 + b4) * 0x100 + b5) * 0x100 + b6) * 0x100 + b7) * 0x100 + b8, -52)
|
|
if exponent == 0x7FF then
|
|
if mantissa > 0 then
|
|
return 0 / 0
|
|
else
|
|
if b1 >= 0x80 then
|
|
return -math_huge
|
|
else
|
|
return math_huge
|
|
end
|
|
end
|
|
elseif exponent > 0 then
|
|
mantissa = mantissa + 1
|
|
else
|
|
exponent = exponent + 1
|
|
end
|
|
if b1 >= 0x80 then
|
|
mantissa = -mantissa
|
|
end
|
|
return math_ldexp(mantissa, exponent - 0x3FF)
|
|
end
|
|
|
|
--- Sets the endianness of the string stream
|
|
--@param endian The endianness of number types. "big" or "little" (default "little")
|
|
function ss_methods:setEndian(endian)
|
|
if endian == "little" then
|
|
debug.setmetatable(self, ss_meta)
|
|
elseif endian == "big" then
|
|
debug.setmetatable(self, ss_meta_big)
|
|
else
|
|
error("Invalid endian specified", 2)
|
|
end
|
|
end
|
|
|
|
--- Writes the given string and advances the buffer pointer.
|
|
--@param data A string of data to write
|
|
function ss_methods:write(data)
|
|
if self.index > #self then -- Most often case
|
|
self[self.index] = data
|
|
self.index = self.index + 1
|
|
self.subindex = 1
|
|
else
|
|
local i = 1
|
|
local length = #data
|
|
while length > 0 do
|
|
if self.index > #self then -- End of buffer
|
|
self[self.index] = string.sub(data, i)
|
|
self.index = self.index + 1
|
|
self.subindex = 1
|
|
break
|
|
else
|
|
local cur = self[self.index]
|
|
local sublength = math_min(#cur - self.subindex + 1, length)
|
|
self[self.index] = string.sub(cur,1,self.subindex-1) .. string.sub(data,i,i+sublength-1) .. string.sub(cur,self.subindex+sublength)
|
|
length = length - sublength
|
|
i = i + sublength
|
|
if length > 0 then
|
|
self.index = self.index + 1
|
|
self.subindex = 1
|
|
else
|
|
self.subindex = self.subindex + sublength
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--- Reads the specified number of bytes from the buffer and advances the buffer pointer.
|
|
--@param length How many bytes to read
|
|
--@return A string containing the bytes
|
|
function ss_methods:read(length)
|
|
local ret = {}
|
|
while length > 0 do
|
|
local cur = self[self.index]
|
|
if cur then
|
|
if self.subindex == 1 and length >= #cur then
|
|
ret[#ret+1] = cur
|
|
self.index = self.index + 1
|
|
length = length - #cur
|
|
else
|
|
local sublength = math_min(#cur - self.subindex + 1, length)
|
|
ret[#ret+1] = string.sub(cur, self.subindex, self.subindex + sublength - 1)
|
|
length = length - sublength
|
|
if length > 0 then
|
|
self.index = self.index + 1
|
|
self.subindex = 1
|
|
else
|
|
self.subindex = self.subindex + sublength
|
|
end
|
|
end
|
|
else
|
|
break
|
|
end
|
|
end
|
|
return table.concat(ret)
|
|
end
|
|
|
|
--- Sets internal pointer to i. The position will be clamped to [1, buffersize+1]
|
|
--@param i The position
|
|
function ss_methods:seek(pos)
|
|
if pos < 1 then error("Index must be 1 or greater", 2) end
|
|
self.index = #self+1
|
|
self.subindex = 1
|
|
|
|
local length = 0
|
|
for i, v in ipairs(self) do
|
|
length = length + #v
|
|
if length >= pos then
|
|
self.index = i
|
|
self.subindex = pos - (length - #v)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
--- Move the internal pointer by amount i
|
|
--@param length The offset
|
|
function ss_methods:skip(length)
|
|
while length>0 do
|
|
local cur = self[self.index]
|
|
if cur then
|
|
local sublength = math_min(#cur - self.subindex + 1, length)
|
|
length = length - sublength
|
|
self.subindex = self.subindex + sublength
|
|
if self.subindex>#cur then
|
|
self.index = self.index + 1
|
|
self.subindex = 1
|
|
end
|
|
else
|
|
self.index = #self.index + 1
|
|
self.subindex = 1
|
|
break
|
|
end
|
|
end
|
|
while length<0 do
|
|
local cur = self[self.index]
|
|
if cur then
|
|
local sublength = math_max(-self.subindex, length)
|
|
length = length - sublength
|
|
self.subindex = self.subindex + sublength
|
|
if self.subindex<1 then
|
|
self.index = self.index - 1
|
|
self.subindex = self[self.index] and #self[self.index] or 1
|
|
end
|
|
else
|
|
self.index = 1
|
|
self.subindex = 1
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
--- Returns the internal position of the byte reader.
|
|
--@return The buffer position
|
|
function ss_methods:tell()
|
|
local length = 0
|
|
for i=1, self.index-1 do
|
|
length = length + #self[i]
|
|
end
|
|
return length + self.subindex
|
|
end
|
|
|
|
--- Tells the size of the byte stream.
|
|
--@return The buffer size
|
|
function ss_methods:size()
|
|
local length = 0
|
|
for i, v in ipairs(self) do
|
|
length = length + #v
|
|
end
|
|
return length
|
|
end
|
|
|
|
--- Reads an unsigned 8-bit (one byte) integer from the byte stream and advances the buffer pointer.
|
|
--@return The uint8 at this position
|
|
function ss_methods:readUInt8()
|
|
return string.byte(self:read(1))
|
|
end
|
|
function ss_methods_big:readUInt8()
|
|
return string.byte(self:read(1))
|
|
end
|
|
|
|
--- Reads an unsigned 16 bit (two byte) integer from the byte stream and advances the buffer pointer.
|
|
--@return The uint16 at this position
|
|
function ss_methods:readUInt16()
|
|
local a,b = string.byte(self:read(2), 1, 2)
|
|
return b * 0x100 + a
|
|
end
|
|
function ss_methods_big:readUInt16()
|
|
local a,b = string.byte(self:read(2), 1, 2)
|
|
return a * 0x100 + b
|
|
end
|
|
|
|
--- Reads an unsigned 32 bit (four byte) integer from the byte stream and advances the buffer pointer.
|
|
--@return The uint32 at this position
|
|
function ss_methods:readUInt32()
|
|
local a,b,c,d = string.byte(self:read(4), 1, 4)
|
|
return d * 0x1000000 + c * 0x10000 + b * 0x100 + a
|
|
end
|
|
function ss_methods_big:readUInt32()
|
|
local a,b,c,d = string.byte(self:read(4), 1, 4)
|
|
return a * 0x1000000 + b * 0x10000 + c * 0x100 + d
|
|
end
|
|
|
|
--- Reads a signed 8-bit (one byte) integer from the byte stream and advances the buffer pointer.
|
|
--@return The int8 at this position
|
|
function ss_methods:readInt8()
|
|
local x = self:readUInt8()
|
|
if x>=0x80 then x = x - 0x100 end
|
|
return x
|
|
end
|
|
|
|
--- Reads a signed 16-bit (two byte) integer from the byte stream and advances the buffer pointer.
|
|
--@return The int16 at this position
|
|
function ss_methods:readInt16()
|
|
local x = self:readUInt16()
|
|
if x>=0x8000 then x = x - 0x10000 end
|
|
return x
|
|
end
|
|
|
|
--- Reads a signed 32-bit (four byte) integer from the byte stream and advances the buffer pointer.
|
|
--@return The int32 at this position
|
|
function ss_methods:readInt32()
|
|
local x = self:readUInt32()
|
|
if x>=0x80000000 then x = x - 0x100000000 end
|
|
return x
|
|
end
|
|
|
|
--- Reads a 4 byte IEEE754 float from the byte stream and advances the buffer pointer.
|
|
--@return The float32 at this position
|
|
function ss_methods:readFloat()
|
|
return UnpackIEEE754Float(string.byte(self:read(4), 1, 4))
|
|
end
|
|
function ss_methods_big:readFloat()
|
|
local a,b,c,d = string.byte(self:read(4), 1, 4)
|
|
return UnpackIEEE754Float(d, c, b, a)
|
|
end
|
|
|
|
--- Reads a 8 byte IEEE754 double from the byte stream and advances the buffer pointer.
|
|
--@return The double at this position
|
|
function ss_methods:readDouble()
|
|
return UnpackIEEE754Double(string.byte(self:read(8), 1, 8))
|
|
end
|
|
function ss_methods_big:readDouble()
|
|
local a,b,c,d,e,f,g,h = string.byte(self:read(8), 1, 8)
|
|
return UnpackIEEE754Double(h, g, f, e, d, c, b, a)
|
|
end
|
|
|
|
--- Reads until the given byte and advances the buffer pointer.
|
|
--@param byte The byte to read until (in number form)
|
|
--@return The string of bytes read
|
|
function ss_methods:readUntil(byte)
|
|
byte = string.char(byte)
|
|
local ret = {}
|
|
for i=self.index, #self do
|
|
local cur = self[self.index]
|
|
local find = string.find(cur, byte, self.subindex, true)
|
|
if find then
|
|
ret[#ret+1] = string.sub(cur, self.subindex, find)
|
|
self.subindex = find+1
|
|
if self.subindex > #cur then
|
|
self.index = self.index + 1
|
|
self.subindex = 1
|
|
end
|
|
break
|
|
else
|
|
if self.subindex == 1 then
|
|
ret[#ret+1] = cur
|
|
else
|
|
ret[#ret+1] = string.sub(cur, self.subindex)
|
|
end
|
|
self.index = self.index + 1
|
|
self.subindex = 1
|
|
end
|
|
end
|
|
return table.concat(ret)
|
|
end
|
|
|
|
--- returns a null terminated string, reads until "\x00" and advances the buffer pointer.
|
|
--@return The string of bytes read
|
|
function ss_methods:readString()
|
|
local s = self:readUntil(0)
|
|
return string.sub(s, 1, #s-1)
|
|
end
|
|
|
|
--- Writes a byte to the buffer and advances the buffer pointer.
|
|
--@param x An int8 to write
|
|
function ss_methods:writeInt8(x)
|
|
if x==math_huge or x==-math_huge or x~=x then error("Can't convert error float to integer!", 2) end
|
|
if x < 0 then x = x + 0x100 end
|
|
self:write(string.char(x%0x100))
|
|
end
|
|
|
|
--- Writes a short to the buffer and advances the buffer pointer.
|
|
--@param x An int16 to write
|
|
function ss_methods:writeInt16(x)
|
|
if x==math_huge or x==-math_huge or x~=x then error("Can't convert error float to integer!", 2) end
|
|
if x < 0 then x = x + 0x10000 end
|
|
self:write(string.char(x%0x100, bit_rshift(x, 8)%0x100))
|
|
end
|
|
function ss_methods_big:writeInt16(x)
|
|
if x==math_huge or x==-math_huge or x~=x then error("Can't convert error float to integer!", 2) end
|
|
if x < 0 then x = x + 0x10000 end
|
|
self:write(bit_rshift(x, 8)%0x100, string.char(x%0x100))
|
|
end
|
|
|
|
--- Writes an int to the buffer and advances the buffer pointer.
|
|
--@param x An int32 to write
|
|
function ss_methods:writeInt32(x)
|
|
if x==math_huge or x==-math_huge or x~=x then error("Can't convert error float to integer!", 2) end
|
|
if x < 0 then x = x + 0x100000000 end
|
|
self:write(string.char(x%0x100, bit_rshift(x, 8)%0x100, bit_rshift(x, 16)%0x100, bit_rshift(x, 24)%0x100))
|
|
end
|
|
function ss_methods_big:writeInt32(x)
|
|
if x==math_huge or x==-math_huge or x~=x then error("Can't convert error float to integer!", 2) end
|
|
if x < 0 then x = x + 0x100000000 end
|
|
self:write(string.char(bit_rshift(x, 24)%0x100, bit_rshift(x, 16)%0x100, bit_rshift(x, 8)%0x100), x%0x100)
|
|
end
|
|
|
|
--- Writes a 4 byte IEEE754 float to the byte stream and advances the buffer pointer.
|
|
--@param x The float to write
|
|
function ss_methods:writeFloat(x)
|
|
self:write(string.char(PackIEEE754Float(x)))
|
|
end
|
|
function ss_methods_big:writeFloat(x)
|
|
local a,b,c,d = PackIEEE754Float(x)
|
|
self:write(string.char(d,c,b,a))
|
|
end
|
|
|
|
--- Writes a 8 byte IEEE754 double to the byte stream and advances the buffer pointer.
|
|
--@param x The double to write
|
|
function ss_methods:writeDouble(x)
|
|
self:write(string.char(PackIEEE754Double(x)))
|
|
end
|
|
function ss_methods_big:writeDouble(x)
|
|
local a,b,c,d,e,f,g,h = PackIEEE754Double(x)
|
|
self:write(string.char(h,g,f,e,d,c,b,a))
|
|
end
|
|
|
|
--- Writes a string to the buffer putting a null at the end and advances the buffer pointer.
|
|
--@param string The string of bytes to write
|
|
function ss_methods:writeString(string)
|
|
self:write(string)
|
|
self:write("\0")
|
|
end
|
|
|
|
--- Returns the buffer as a string
|
|
--@return The buffer as a string
|
|
function ss_methods:getString()
|
|
return table.concat(self)
|
|
end
|
|
|
|
do
|
|
do
|
|
function ss_methods:writeBool(b)
|
|
self:writeInt8(b and 1 or 0)
|
|
end
|
|
|
|
function ss_methods:readBool()
|
|
return self:readInt8() == 1
|
|
end
|
|
end
|
|
|
|
do
|
|
function ss_methods:writeVector(val)
|
|
self:writeDouble(val.x)
|
|
self:writeDouble(val.y)
|
|
self:writeDouble(val.z)
|
|
end
|
|
|
|
function ss_methods:readVector()
|
|
local x = self:readDouble()
|
|
local y = self:readDouble()
|
|
local z = self:readDouble()
|
|
|
|
return Vector(x,y,z)
|
|
end
|
|
end
|
|
|
|
do
|
|
function ss_methods:writeAngle(val)
|
|
self:writeDouble(val.p)
|
|
self:writeDouble(val.y)
|
|
self:writeDouble(val.r)
|
|
end
|
|
|
|
function ss_methods:readAngle()
|
|
local x = self:readDouble()
|
|
local y = self:readDouble()
|
|
local z = self:readDouble()
|
|
|
|
return Angle(x,y,z)
|
|
end
|
|
end
|
|
|
|
do
|
|
function ss_methods:writeColor(val)
|
|
self:writeDouble(val.r)
|
|
self:writeDouble(val.g)
|
|
self:writeDouble(val.b)
|
|
self:writeDouble(val.a)
|
|
end
|
|
|
|
function ss_methods:readColor()
|
|
local r = self:readDouble()
|
|
local g = self:readDouble()
|
|
local b = self:readDouble()
|
|
local a = self:readDouble()
|
|
|
|
return Color(r,g,b,a)
|
|
end
|
|
end
|
|
|
|
do
|
|
function ss_methods:writeEntity(val)
|
|
self:writeInt32(val:EntIndex())
|
|
end
|
|
|
|
function ss_methods:readEntity()
|
|
return Entity(self:readInt32())
|
|
end
|
|
end
|
|
|
|
function ss_methods:writeTable(tab)
|
|
for k, v in pairs( tab ) do
|
|
self:writeType( k )
|
|
self:writeType( v )
|
|
end
|
|
|
|
self:writeType( nil )
|
|
end
|
|
|
|
function ss_methods:readTable()
|
|
local tab = {}
|
|
|
|
while true do
|
|
local k = self:readType()
|
|
if k == nil then
|
|
return tab
|
|
end
|
|
|
|
tab[k] = self:readType()
|
|
end
|
|
end
|
|
|
|
local write_functions = {
|
|
[TYPE_NIL] = function(s, t, v) s:writeInt8( t ) end,
|
|
[TYPE_STRING] = function(s, t, v) s:writeInt8( t ) s:writeString( v ) end,
|
|
[TYPE_NUMBER] = function(s, t, v) s:writeInt8( t ) s:writeDouble( v ) end,
|
|
[TYPE_TABLE] = function(s, t, v) s:writeInt8( t ) s:writeTable( v ) end,
|
|
[TYPE_BOOL] = function(s, t, v) s:writeInt8( t ) s:writeBool( v ) end,
|
|
[TYPE_VECTOR] = function(s, t, v) s:writeInt8( t ) s:writeVector( v ) end,
|
|
[TYPE_ANGLE] = function(s, t, v) s:writeInt8( t ) s:writeAngle( v ) end,
|
|
[TYPE_COLOR] = function(s, t, v) s:writeInt8( t ) s:writeColor( v ) end,
|
|
[TYPE_ENTITY] = function(s, t, v) s:writeInt8( t ) s:writeEntity( v ) end,
|
|
|
|
}
|
|
|
|
function ss_methods:writeType( v )
|
|
local typeid = nil
|
|
|
|
if IsColor(v) then
|
|
typeid = TYPE_COLOR
|
|
else
|
|
typeid = TypeID(v)
|
|
end
|
|
|
|
local func = write_functions[typeid]
|
|
|
|
if func then
|
|
return func(self, typeid, v)
|
|
end
|
|
|
|
error("StringStream:writeType: Couldn't write " .. type(v) .. " (type " .. typeid .. ")")
|
|
end
|
|
|
|
local read_functions = {
|
|
[TYPE_NIL] = function(s) return nil end,
|
|
[TYPE_STRING] = function(s) return s:readString() end,
|
|
[TYPE_NUMBER] = function(s) return s:readDouble() end,
|
|
[TYPE_TABLE] = function(s) return s:readTable() end,
|
|
[TYPE_BOOL] = function(s) return s:readBool() end,
|
|
[TYPE_VECTOR] = function(s) return s:readVector() end,
|
|
[TYPE_ANGLE] = function(s) return s:readAngle() end,
|
|
[TYPE_COLOR] = function(s) return s:readColor() end,
|
|
[TYPE_ENTITY] = function(s) return s:readEntity() end,
|
|
}
|
|
|
|
function ss_methods:readType( typeid )
|
|
typeid = typeid or self:readUInt8(8)
|
|
|
|
local func = read_functions[typeid]
|
|
|
|
if func then
|
|
return func(self)
|
|
end
|
|
|
|
error("StringStream:readType: Couldn't read type " .. tostring(typeid))
|
|
end
|
|
end
|
|
|
|
return StringStream
|