333 lines
No EOL
6.6 KiB
Lua
333 lines
No EOL
6.6 KiB
Lua
local Reader = XClass(nil, "Reader")
|
|
local ReadByType = {}
|
|
local MaxInt32 = 2147483647
|
|
local FloatToInt = 10000
|
|
function Reader:Ctor(bytes, len, index)
|
|
self.bytes = bytes
|
|
self.len = len
|
|
self.index = index or 1
|
|
end
|
|
|
|
function Reader:Close()
|
|
self.bytes = nil
|
|
end
|
|
|
|
|
|
function Reader:Read(type)
|
|
return ReadByType[type](self)
|
|
end
|
|
|
|
function Reader:ReadFloat()
|
|
|
|
local num = self:ReadInt()
|
|
if not num then
|
|
return nil
|
|
end
|
|
|
|
num = num / 10000
|
|
|
|
local a, b = math.modf(num) --拆分整数位和小数位
|
|
if b == 0 then
|
|
num = a
|
|
end
|
|
|
|
return num
|
|
--
|
|
-- if self.index + 3 > self.len then
|
|
-- return
|
|
-- end
|
|
-- local b1, b2, b3, b4 = string.byte(self.bytes, self.index, self.index + 3)
|
|
-- self.index = self.index + 4
|
|
-- local sign = b4 > 0x7F --最高位符号位
|
|
-- local expo = (b4 % 0x80) * 0x02 + math.floor(b3 / 0x80) --整数部分
|
|
-- local mant = ((b3 % 0x80) * 0x100 + b2) * 0x100 + b1 --小数部分
|
|
-- if sign then
|
|
-- sign = -1
|
|
-- else
|
|
-- sign = 1
|
|
-- end
|
|
-- local n
|
|
-- if mant == 0 and expo == 0 then
|
|
-- n = sign * 0
|
|
-- elseif expo == 0xFF then
|
|
-- if mant == 0 then
|
|
-- n = sign * math.huge
|
|
-- else
|
|
-- n = nil
|
|
-- end
|
|
-- else
|
|
-- if (expo > 0) and (expo < 0xFF) then
|
|
-- n = sign * (1 + mant / 8388608) * (1 << (expo - 0x7F))
|
|
-- else
|
|
-- n = sign * (mant / 8388608) * (1 << 0x7F)
|
|
-- end
|
|
-- end
|
|
-- return n
|
|
end
|
|
|
|
|
|
function Reader:ReadBool()
|
|
local value = string.byte(self.bytes, self.index, self.index)
|
|
self.index = self.index + 1
|
|
return value == 1 and true or nil
|
|
end
|
|
|
|
--读取string
|
|
function Reader:ReadString()
|
|
|
|
local postion = self.index
|
|
local ass = string.byte(self.bytes, postion, postion)
|
|
|
|
while ass > 0 do
|
|
postion = postion + 1
|
|
ass = string.byte(self.bytes, postion, postion)
|
|
if ass == nil then
|
|
XLog.Error(string.format("读取字符串异常 postion = %s,len = %s index =%s", postion, self.len, self.index))
|
|
end
|
|
end
|
|
|
|
if postion == self.index then
|
|
self.index = self.index + 1
|
|
return
|
|
end
|
|
|
|
local value = string.char(string.byte(self.bytes, self.index, postion - 1))
|
|
self.index = postion + 1
|
|
|
|
return value
|
|
end
|
|
|
|
function Reader:ReadIntFix()
|
|
self.index = self.index + 4
|
|
local b1, b2, b3, b4 = string.byte(self.bytes, 1, 4)
|
|
return b1 | b2 << 8 | b3 << 16 | b4 << 24
|
|
end
|
|
|
|
function Reader:ReadInt()
|
|
return self:ReadInt32Variant()
|
|
end
|
|
|
|
function Reader:ReadInt32Variant()
|
|
return self:ReadUInt32Variant()
|
|
end
|
|
|
|
function Reader:ReadUInt32Variant()
|
|
local value = 0
|
|
local tempByte
|
|
local index = 0
|
|
|
|
while not tempByte or ((tempByte >> 7) > 0) do
|
|
tempByte = string.byte(self.bytes, self.index, self.index)
|
|
local temp1 = (tempByte & 0x7F) << index
|
|
value = value | temp1
|
|
index = index + 7
|
|
self.index = self.index + 1
|
|
end
|
|
|
|
--负数,MaxInt32 = 2147483647 因为lua number是64bit 所以需要特殊处理负数
|
|
if value > MaxInt32 then
|
|
local newValue = 0
|
|
value = -(((~ value) & MaxInt32) + 1)
|
|
end
|
|
|
|
if value == 0 then
|
|
return nil
|
|
end
|
|
|
|
return value
|
|
end
|
|
|
|
function Reader:ReadListString()
|
|
|
|
local len = self:ReadInt()
|
|
if not len or len <= 0 then
|
|
return nil
|
|
end
|
|
|
|
local list = {}
|
|
for i = 1, len do
|
|
table.insert(list, self:ReadString())
|
|
end
|
|
|
|
return list
|
|
end
|
|
|
|
|
|
function Reader:ReadListBool()
|
|
|
|
local len = self:ReadInt()
|
|
if not len or len <= 0 then
|
|
return nil
|
|
end
|
|
|
|
local list = {}
|
|
for i = 1, len do
|
|
table.insert(list, self:ReadBool())
|
|
end
|
|
|
|
return list
|
|
end
|
|
|
|
|
|
function Reader:ReadListInt()
|
|
|
|
local len = self:ReadInt()
|
|
if not len or len <= 0 then
|
|
return nil
|
|
end
|
|
|
|
local list = {}
|
|
for i = 1, len do
|
|
table.insert(list, self:ReadInt() or 0)
|
|
end
|
|
|
|
return list
|
|
end
|
|
|
|
function Reader:ReadListFloat()
|
|
|
|
local len = self:ReadInt()
|
|
if not len or len <= 0 then
|
|
return nil
|
|
end
|
|
|
|
local list = {}
|
|
for i = 1, len do
|
|
table.insert(list, self:ReadFloat() or 0)
|
|
end
|
|
|
|
return list
|
|
end
|
|
|
|
function Reader:ReadDicStringString()
|
|
|
|
local len = self:ReadInt()
|
|
if not len or len <= 0 then
|
|
return nil
|
|
end
|
|
|
|
local dic = {}
|
|
for i = 1, len do
|
|
local key = self:ReadString()
|
|
local value = self:ReadString()
|
|
dic[key] = value
|
|
end
|
|
|
|
return dic
|
|
end
|
|
|
|
function Reader:ReadDicIntInt()
|
|
|
|
local len = self:ReadInt()
|
|
if not len or len <= 0 then
|
|
return nil
|
|
end
|
|
|
|
local dic = {}
|
|
for i = 1, len do
|
|
local key = self:ReadInt() or 0
|
|
local value = self:ReadInt() or 0
|
|
dic[key] = value
|
|
end
|
|
|
|
return dic
|
|
end
|
|
|
|
function Reader:ReadDicIntString()
|
|
|
|
local len = self:ReadInt()
|
|
if not len or len <= 0 then
|
|
return nil
|
|
end
|
|
|
|
local dic = {}
|
|
for i = 1, len do
|
|
local key = self:ReadInt() or 0
|
|
local value = self:ReadString()
|
|
dic[key] = value
|
|
end
|
|
|
|
return dic
|
|
end
|
|
|
|
|
|
function Reader:ReadDicStringInt()
|
|
|
|
local len = self:ReadInt() or 0
|
|
if not len or len <= 0 then
|
|
return nil
|
|
end
|
|
|
|
local dic = {}
|
|
for i = 1, len do
|
|
local key = self:ReadString()
|
|
local value = self:ReadInt()
|
|
dic[key] = value
|
|
end
|
|
|
|
return dic
|
|
end
|
|
|
|
function Reader:ReadDicIntFloat()
|
|
|
|
local len = self:ReadInt()
|
|
if not len or len <= 0 then
|
|
return nil
|
|
end
|
|
|
|
local dic = {}
|
|
for i = 1, len do
|
|
local key = self:ReadInt() or 0
|
|
local value = self:ReadFloat()
|
|
dic[key] = value
|
|
end
|
|
|
|
return dic
|
|
end
|
|
|
|
--读取Fix
|
|
function Reader:ReadFix()
|
|
local str = self:ReadString()
|
|
if not str then
|
|
return nil
|
|
end
|
|
|
|
return FixParse(str)
|
|
end
|
|
|
|
--读取Fix
|
|
function Reader:ReadListFix()
|
|
local len = self:ReadInt()
|
|
if not len or len <= 0 then
|
|
return nil
|
|
end
|
|
|
|
local list = {}
|
|
for i = 1, len do
|
|
table.insert(list, self:ReadFix())
|
|
end
|
|
|
|
return list
|
|
end
|
|
|
|
|
|
ReadByType = {
|
|
[1] = Reader.ReadBool,
|
|
[2] = Reader.ReadString,
|
|
[3] = Reader.ReadFix,
|
|
[4] = Reader.ReadListString,
|
|
[5] = Reader.ReadListBool,
|
|
[6] = Reader.ReadListInt,
|
|
[7] = Reader.ReadListFloat,
|
|
[8] = Reader.ReadListFix,
|
|
[9] = Reader.ReadDicStringString,
|
|
[10] = Reader.ReadDicIntInt,
|
|
[11] = Reader.ReadDicIntString,
|
|
[12] = Reader.ReadDicStringInt,
|
|
[13] = Reader.ReadDicIntFloat,
|
|
[14] = Reader.ReadInt,
|
|
[15] = Reader.ReadFloat,
|
|
}
|
|
|
|
|
|
return Reader |