mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
670
lua/pac3/libraries/string_stream.lua
Normal file
670
lua/pac3/libraries/string_stream.lua
Normal file
@@ -0,0 +1,670 @@
|
||||
--[[
|
||||
| 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
|
||||
Reference in New Issue
Block a user