Files
tianrunCRM/Assets/trCRM/upgradeRes4Dev/priority/lua/bio/BioOutputStream.lua

335 lines
11 KiB
Lua
Raw Normal View History

2020-07-04 14:41:25 +08:00
do
require("public.class")
require("bio.BioType")
BioOutputStream = {}
local B2Type = BioType.B2Type;
local IntB2TypeList = BioType.IntB2TypeList;
local StringB2TypeList = BioType.StringB2TypeList;
local MapB2TypeList = BioType.MapB2TypeList;
local ListB2TypeList = BioType.ListB2TypeList
local type = type
local sub = string.sub
local strupper = string.upper;
local strlen = string.len;
local strbyte = string.byte
local strchar = string.char
local floorInt = math.floor
--===================================================
--===================================================
-- 数据流
LuaB2OutputStream = class("LuaB2OutputStream");
function LuaB2OutputStream:ctor(v)
self.content = {}
end
function LuaB2OutputStream:init(v)
self.content = {}
end
function LuaB2OutputStream:writeByte(v)
table.insert(self.content, strchar(v))
end
function LuaB2OutputStream:writeString(v)
table.insert(self.content, v)
end
function LuaB2OutputStream:toBytes()
--local ret = "";
--for i, v in ipairs(self.content) do
-- ret = ret .. v;
--end
return table.concat(self.content, "");
end
function LuaB2OutputStream:release()
self.content = {};
end
--===================================================
--===================================================
--===================================================
-- 原始数据类型
BioOutputStream.DataType = {
NIL = "nil",
BOOLEAN = "boolean",
STRING = "string",
NUMBER = "number",
LONG = "long",
DOUBLE = "double",
USERDATA = "userdata",
FUNCTION = "function",
THREAD = "thread",
TABLE = "table",
INT4B = "int4b",
INT16B = "int16b",
INT32B = "int32b",
}
---@public 取得数据的类型主要是对number做了处理
function BioOutputStream.getDataType(obj)
--nil, boolean, number, string, userdata, function, thread, table
local val = nil;
local t = type(obj);
val = BioOutputStream.DataType[strupper(type(obj))];
if val == nil then
val = "undefined";
end
return val;
end
function BioOutputStream.getNumberType(obj)
local val = nil;
local t = type(obj);
if t == "number" then
local minInt = floorInt(obj);
if minInt == obj then
-- 说明是整数
if (obj >= -128 and obj <= 127) then
val = BioOutputStream.DataType.INT4B
elseif (obj >= -32768 and obj <= 32767) then
val = BioOutputStream.DataType.INT16B
elseif (obj >= -2147483648 and obj <= 2147483647) then
val = BioOutputStream.DataType.INT32B
else
val = BioOutputStream.DataType.LONG
end
else
val = BioOutputStream.DataType.DOUBLE
end
end
return val;
end
---@public 返回table是否为一个array 第二返回值如查是array的时候是table的count
function BioOutputStream.isArray(t)
if t == nil then
return false, 0;
end
local i = 0
local ret = true;
for _ in pairs(t) do
i = i + 1
if t[i] == nil then
ret = false
end
end
return ret, i
end
--===================================================
---public Void writeObject (LuaB2OutputStream os, obj)
---@param optional LuaB2OutputStream os
---@param optional object obj
--[[
local os = LuaB2OutputStream.new();
BioOutputStream.writeObject(os, map)
local bytes = os:toBytes()
--]]
function BioOutputStream.writeObject (os, obj)
if os == nil then
os = LuaB2OutputStream.new();
end
local objType = BioOutputStream.getDataType(obj)
if (objType == BioOutputStream.DataType.NIL) then
BioOutputStream.writeNil(os)
elseif (objType == BioOutputStream.DataType.TABLE) then
BioOutputStream.writeMap(os, obj);
elseif (objType == BioOutputStream.DataType.NUMBER) then
BioOutputStream.writeNumber(os, obj);
elseif (objType == BioOutputStream.DataType.STRING) then
BioOutputStream.writeString(os, obj);
elseif (objType == BioOutputStream.DataType.BOOLEAN) then
BioOutputStream.writeBoolean(os, obj);
else
--//throw new IOException("unsupported obj then" + obj);
print("B2IO unsupported error then type=[" .. tostring(objType) .. "] val=[" .. obj .. "]");
end
end
function BioOutputStream.writeNil(os)
BioOutputStream.WriteByte(os, B2Type.NULL);
return os;
end
function BioOutputStream.WriteByte(os, v)
local v2 = v;
if v < 0 then
v2 = v + 256;
end
os:writeByte(v2)
return os;
end
function BioOutputStream.writeNumber(os, v)
local numType = BioOutputStream.getNumberType(v)
if numType == BioOutputStream.DataType.INT4B or
numType == BioOutputStream.DataType.INT16B or
numType == BioOutputStream.DataType.INT32B then
BioOutputStream.writeInt(os, v)
elseif numType == BioOutputStream.DataType.LONG then
BioOutputStream.writeLong(os, v);
elseif numType == BioOutputStream.DataType.DOUBLE then
BioOutputStream.writeDouble(os, v);
end
return os;
end
function BioOutputStream.writeInt(os, v)
if v == -1 then
BioOutputStream.WriteByte(os, B2Type.INT_N1);
elseif v >= 0 and v <= 32 then
local t = IntB2TypeList[v + 1]
BioOutputStream.WriteByte(os, t);
else
if (v >= -128 and v <= 127) then
BioOutputStream.WriteByte(os, B2Type.INT_8B);
BioOutputStream.WriteByte(os, v);
elseif (v >= -32768 and v <= 32767) then
BioOutputStream.WriteByte(os, B2Type.INT_16B);
local v2 = v;
--if v < 0 then
-- v2 = v + 65536
--end
BioOutputStream.WriteByte(os, math.floor(v2 / 256));
BioOutputStream.WriteByte(os, v2 % 256);
else
BioOutputStream.WriteByte(os, B2Type.INT_32B);
local v2 = v;
--if v < 0 then
-- v2 = v + 4294967296
--end
BioOutputStream.WriteByte(os, math.floor(v2 / 16777216));
v2 = v2 % 16777216
BioOutputStream.WriteByte(os, math.floor(v2 / 65536));
v2 = v2 % 65536
BioOutputStream.WriteByte(os, math.floor(v2 / 256));
BioOutputStream.WriteByte(os, v2 % 256);
end
end
return os;
end
function BioOutputStream.writeLong(os, v)
BioOutputStream.WriteByte(os, B2Type.LONG_64B);
local v2 = v;
--if v < 0 then
-- v2 = v + 4294967296
--end
BioOutputStream.WriteByte(os, math.floor(v2 / 72057594037927936));
v2 = v2 % 72057594037927936
BioOutputStream.WriteByte(os, math.floor(v2 / 281474976710656));
v2 = v2 % 281474976710656
BioOutputStream.WriteByte(os, math.floor(v2 / 1099511627776));
v2 = v2 % 1099511627776
BioOutputStream.WriteByte(os, math.floor(v2 / 4294967296));
v2 = v2 % 4294967296
BioOutputStream.WriteByte(os, math.floor(v2 / 16777216));
v2 = v2 % 16777216
BioOutputStream.WriteByte(os, math.floor(v2 / 65536));
v2 = v2 % 65536
BioOutputStream.WriteByte(os, math.floor(v2 / 256));
BioOutputStream.WriteByte(os, v2 % 256);
return os;
end
function BioOutputStream.writeDouble(os, v)
BioOutputStream.WriteByte(os, B2Type.DOUBLE_64B);
BioOutputStream.writeString(os, tostring(v));
return os;
end
function BioOutputStream.writeString(os, v)
if (v == nil) then
BioOutputStream.writeNil(os);
return os;
end
local len = strlen(v);
local t = StringB2TypeList[len + 1]
if t then
BioOutputStream.WriteByte(os, t);
os:writeString(v);
else
BioOutputStream.WriteByte(os, B2Type.STR);
BioOutputStream.writeInt(os, len);
os:writeString(v);
end
end
function BioOutputStream.writeBoolean(os, v)
if v then
BioOutputStream.WriteByte(os, B2Type.BOOLEAN_TRUE);
else
BioOutputStream.WriteByte(os, B2Type.BOOLEAN_FALSE);
end
return os;
end
function BioOutputStream.writeMap(os, v)
if (v == nil) then
BioOutputStream.writeNil(os);
end
local isArray, len = BioOutputStream.isArray(v)
if isArray then
if len <= 24 then
BioOutputStream.WriteByte(os, ListB2TypeList[len + 1]);
else
BioOutputStream.WriteByte(os, B2Type.VECTOR);
BioOutputStream.writeInt(os, len);
end
for i, val in ipairs(v) do
BioOutputStream.writeObject(os, val);
end
else
if len <= 15 then
BioOutputStream.WriteByte(os, MapB2TypeList[len + 1]);
else
BioOutputStream.WriteByte(os, B2Type.HASHTABLE);
BioOutputStream.writeInt(os, len);
end
for key, val in pairs(v) do
BioOutputStream.writeObject(os, key);
BioOutputStream.writeObject(os, val);
end
end
end
--两个字节的and 操作
function BioOutputStream.byte_xor(a, b)
local bit_value_tb = {
[8] = 2 ^ 7;
[7] = 2 ^ 6;
[6] = 2 ^ 5;
[5] = 2 ^ 4;
[4] = 2 ^ 3;
[3] = 2 ^ 2;
[2] = 2 ^ 1;
[1] = 2 ^ 0; };
local value = 0;
for i = 8, 1, -1 do
local bit_value = bit_value_tb[i];
if a >= bit_value and b < bit_value then
value = value + bit_value;
elseif a < bit_value and b >= bit_value then
value = value + bit_value;
end
if a >= bit_value then
a = a - bit_value;
end
if b >= bit_value then
b = b - bit_value;
end
end
return value;
end
--------------------------------------------
return BioOutputStream;
end