代码拉取完成,页面将自动刷新
const gettype = Object.prototype.toString;
const TYPE_NIL = 0
const TYPE_BOOLEAN = 1
const TYPE_NUMBER = 2
const TYPE_NUMBER_ZERO = 0
const TYPE_NUMBER_BYTE = 1
const TYPE_NUMBER_WORD = 2
const TYPE_NUMBER_DWORD = 4
const TYPE_NUMBER_QWORD = 6
const TYPE_NUMBER_REAL = 8
const TYPE_USERDATA = 3
const TYPE_SHORT_STRING = 4
const TYPE_LONG_STRING = 5
const TYPE_TABLE = 6
const BLOCK_SIZE = 1024
const MAX_COOKIE = 32
function COMBINE_TYPE(t, v) {
return t | (v << 3)
}
/*
* gettype.call('aaaa')输出 [object String]
* gettype.call(2222) 输出 [object Number]
* gettype.call(true) 输出 [object Boolean]
* gettype.call(undefined) 输出 [object Undefined]
* gettype.call(null) 输出 [object Null]
* gettype.call({}) 输出 [object Object]
* gettype.call([]) 输出 [object Array]
* gettype.call(function(){}) 输出 [object Function]
*/
function checktype(value, type) {
var typestr = gettype.call(value)
var cmp = typestr.substring(8, typestr.length - 1)
cmp = cmp.toLowerCase()
if (cmp == type) {
return true
} else {
return cmp
}
}
function isinteger(obj) {
return typeof obj === 'number' && obj%1 === 0
}
function uint64_rshift(num, offset) {
return Math.floor(num / Math.pow(2, offset))
}
// 检测整数需要编码的字节数
function integer_byte(num, offset) {
if (offset === void 0) {
offset = 31
}
var numh = uint64_rshift(num, offset);
if (numh === 0 || numh === -1) {
return 4
} else {
return 8
}
}
function wb_check(size, wb) {
var len = wb.buffer.length - wb.offset
while (len < size) {
var newsize = wb.buffer.length << 1
newbuf = Buffer.allocUnsafe(newsize)
newbuf.fill(wb.buffer, 0, wb.buffer.length)
wb.buffer = newbuf
}
}
function wb_byte(v, wb) {
wb_check(1, wb)
wb.buffer[wb.offset++] = v
}
function wb_nil(wb) {
wb_byte(TYPE_NIL, wb)
}
function wb_integer(number, wb) {
var type = TYPE_NUMBER
var n
if (number == 0) {
// 0
n = COMBINE_TYPE(type, TYPE_NUMBER_ZERO)
wb_byte(n, wb)
} else if (integer_byte(number) == 8) {
// int64
// 8 个字节数字会有问题,建议转成字符串来传输
n = COMBINE_TYPE(type, TYPE_NUMBER_QWORD)
wb_byte(n, wb)
wb.offset = wb.buffer.writeDoubleLE(number, wb.offset)
} else if (number < 0) {
// int32
n = COMBINE_TYPE(type, TYPE_NUMBER_DWORD)
wb_byte(n, wb)
wb.offset = wb.buffer.writeInt32LE(number, wb.offset)
} else if (number < 0x100) {
// uint8
n = COMBINE_TYPE(type, TYPE_NUMBER_BYTE)
wb_byte(n, wb)
wb.offset = wb.buffer.writeUInt8(number, wb.offset)
} else if (number < 0x10000) {
// uint16
n = COMBINE_TYPE(type, TYPE_NUMBER_WORD)
wb_byte(n, wb)
wb.offset = wb.buffer.writeUInt16LE(number, wb.offset)
} else {
// uint32
n = COMBINE_TYPE(type, TYPE_NUMBER_DWORD)
wb_byte(n, wb)
wb.offset = wb.buffer.writeUInt32LE(number, wb.offset)
}
}
function wb_real(number, wb) {
var n = COMBINE_TYPE(TYPE_NUMBER, TYPE_NUMBER_REAL)
wb_byte(n, wb)
wb.offset = wb.buffer.writeDoubleLE(number, wb.offset)
}
function wb_boolean(bool, wb) {
var n = COMBINE_TYPE(TYPE_BOOLEAN, bool ? 1 : 0)
wb_byte(n, wb)
}
function wb_string(value, wb) {
value = Buffer.from(value)
var len = value.length
if (len < MAX_COOKIE) {
var n = COMBINE_TYPE(TYPE_SHORT_STRING, len)
wb_byte(n, wb)
if (len > 0) {
wb.buffer.fill(value, wb.offset, wb.offset+len)
wb.offset += len
}
} else {
if (len < 0x10000) {
var n = COMBINE_TYPE(TYPE_LONG_STRING, 2)
wb_byte(n, wb)
wb.offset = wb.buffer.writeUInt16LE(len, wb.offset)
} else {
var n = COMBINE_TYPE(TYPE_LONG_STRING, 4)
wb_byte(n, wb)
wb.offset = wb.buffer.writeUInt32LE(len, wb.offset)
}
wb.buffer.fill(value, wb.offset, wb.offset+len)
wb.offset += len
}
}
function wb_array(array, wb) {
var length = array.length
if (length >= MAX_COOKIE-1) {
var n = COMBINE_TYPE(TYPE_TABLE, MAX_COOKIE-1)
wb_byte(n, wb)
wb_integer(length, wb)
} else {
var n = COMBINE_TYPE(TYPE_TABLE, length)
wb_byte(n, wb)
}
for (var i = 0; i < length; i++) {
pack_one(array[i], wb)
}
wb_nil(wb) // 做为 [] 与其他变量的分界符
}
function wb_object(obj, wb) {
var n = COMBINE_TYPE(TYPE_TABLE, 0)
wb_byte(n, wb)
for (var i in obj) {
pack_one(i, wb)
pack_one(obj[i], wb)
}
wb_nil(wb) // 做为 {} 与其他变量的分界符
}
function pack_one(value, wb) {
var type = checktype(value)
switch(type) {
case "null":
wb_nil(wb)
break
case "number":
if (isinteger(value)) {
wb_integer(value, wb)
} else {
// double number
wb_real(value, wb)
}
break
case "boolean":
wb_boolean(value, wb)
break
case "string":
wb_string(value, wb)
break
case "object":
wb_object(value, wb)
break
case "array":
wb_array(value, wb)
break
default:
console.log("Unsupport type: " + type + " to serialize")
break
}
}
function skynet_pack(data) {
if (!checktype(data, "object") || !checktype(data, "array")) {
console.warn("pack data type must be object")
return
}
var wb = {}
wb.buffer = Buffer.allocUnsafe(BLOCK_SIZE)
wb.offset = 0 //初始化 偏移量
wb_object(data, wb)
var buff = Buffer.allocUnsafe(wb.offset)
wb.buffer.copy(buff, 0, 0, wb.offset)
return buff
}
function get_integer(buffer, offset, cookie) {
switch(cookie) {
case TYPE_NUMBER_REAL:
var value = buffer.readDoubleLE(offset)
return {size: 8, value}
case TYPE_NUMBER_BYTE:
var value = buffer.readUInt8(offset)
return {size: 1, value}
case TYPE_NUMBER_WORD:
var value = buffer.readUInt16LE(offset)
return {size: 2, value}
case TYPE_NUMBER_DWORD:
var value = buffer.readInt32LE(offset)
return {size: 4, value}
case TYPE_NUMBER_QWORD:
var value = buffer.readDoubleLE(offset)
return {size: 8, value}
default:
console.log("Invalid serialize stream cookie: " + cookie)
break
}
}
function unpack_array(buffer, offset, cookie) {
var length = 0
var oldoffset = offset
var value = []
var type
if (cookie == MAX_COOKIE-1) {
type = buffer[offset++]
var numtb = unpack_one(buffer, offset, type & 0x07, type >> 3)
if (numtb) {
offset += numtb.size
length = numtb.value
} else {
console.log("read array size failed")
}
} else {
length = cookie
}
for (var i = 0; i < length; i++) {
type = buffer[offset++]
var v = unpack_one(buffer, offset, type & 0x07, type >> 3)
offset += v.size
value[i] = v.value
}
return {size: offset - oldoffset + 1, value}
}
function unpack_object(buffer, offset) {
var idx = offset
var type
var obj = {}
while (idx < buffer.length) {
type = buffer[idx++]
var one = unpack_one(buffer, idx, type & 0x07, type>>3)
if (!one || one.nil) {
break
}
idx += one.size
type = buffer[idx++]
var two = unpack_one(buffer, idx, type & 0x07, type>>3)
if (!two) {
break
}
idx += two.size
obj[one.value] = two.value
type = buffer[idx+1]
if ((type & 0x07) == TYPE_NIL) {
++idx
break
}
}
return {size: idx - offset, value: obj}
}
function unpack_one(buffer, offset, type, cookie) {
switch(type) {
case TYPE_SHORT_STRING:
var value = buffer.toString("utf8", offset, offset + cookie)
return {size: cookie, value}
case TYPE_NUMBER:
var tmp = get_integer(buffer, offset, cookie)
return tmp
case TYPE_LONG_STRING:
if (cookie == 2) {
var len = buffer.readUInt16LE(offset)
offset += 2
var value = buffer.toString("utf8", offset, offset + len)
return {size: len, value}
} else if (cookie == 4) {
var len = buffer.readUInt32LE(offset)
offset += 4
var value = buffer.toString("utf8", offset, offset + len)
return {size: len, value}
}
case TYPE_NIL:
return {size: 0, nil: true}
case TYPE_BOOLEAN:
var value = cookie == 1 ? true : false
return {size: 0, value}
case TYPE_TABLE:
if (cookie > 0) {
return unpack_array(buffer, offset, cookie)
} else {
return unpack_object(buffer, offset)
}
}
}
function skynet_unpack(buffer) {
var type = buffer[0]
if ((type & 0x07) !== TYPE_TABLE) {
console.log("unpack data must be a object, type: " + type)
return
}
var result = unpack_object(buffer, 1)
return result.value
}
module.exports = {
pack: skynet_pack,
unpack: skynet_unpack,
checktype: checktype,
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。