dotfiles from arch
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
local json = require 'json'
|
||||
local inspect = require 'inspect'
|
||||
local pcall = pcall
|
||||
local tonumber = tonumber
|
||||
|
||||
---@class jsonrpc
|
||||
local m = {}
|
||||
m.type = 'jsonrpc'
|
||||
|
||||
function m.encode(pack)
|
||||
pack.jsonrpc = '2.0'
|
||||
local content = json.encode(pack)
|
||||
local buf = ('Content-Length: %d\r\n\r\n%s'):format(#content, content)
|
||||
return buf
|
||||
end
|
||||
|
||||
---@param reader fun(arg: integer):string
|
||||
local function readProtoHead(reader)
|
||||
local head = {}
|
||||
local line = ''
|
||||
while true do
|
||||
local char = reader(1)
|
||||
if char == nil then
|
||||
-- 说明管道已经关闭了
|
||||
return nil, 'Disconnected!'
|
||||
end
|
||||
line = line .. char
|
||||
if line == '\r\n' then
|
||||
break
|
||||
end
|
||||
if line:sub(-2) ~= '\r\n' then
|
||||
goto continue
|
||||
end
|
||||
local k, v = line:match '^([^:]+)%s*%:%s*(.+)\r\n$'
|
||||
if not k then
|
||||
return nil, 'Proto header error: ' .. line
|
||||
end
|
||||
if k == 'Content-Length' then
|
||||
v = tonumber(v)
|
||||
end
|
||||
head[k] = v
|
||||
line = ''
|
||||
::continue::
|
||||
end
|
||||
return head
|
||||
end
|
||||
|
||||
---@param reader fun(arg: integer):string
|
||||
function m.decode(reader)
|
||||
local head, err = readProtoHead(reader)
|
||||
if not head then
|
||||
return nil, err
|
||||
end
|
||||
local len = head['Content-Length']
|
||||
if not len then
|
||||
return nil, 'Proto header error: ' .. inspect(head)
|
||||
end
|
||||
local content = reader(len)
|
||||
if not content then
|
||||
return nil, 'Proto read error'
|
||||
end
|
||||
---@type any
|
||||
local null = json.null
|
||||
json.null = nil
|
||||
local suc, res = pcall(json.decode, content)
|
||||
json.null = null
|
||||
if not suc then
|
||||
return nil, 'Proto parse error: ' .. res
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
return m
|
||||
Reference in New Issue
Block a user