summaryrefslogtreecommitdiff
path: root/script/async/proto.lua
blob: b51749daf7165cc5c1cb0695db5940499e252f89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
local json   = require 'json'
json.null = nil

local function pushError(...)
    local t = table.pack(...)
    for i = 1, t.n do
        t[i] = tostring(t[i])
    end
    local buf = table.concat(t, '\t')
    ERR:push(buf)
end

local function readProtoHead(reader)
    local head = {}
    while true do
        local line = reader 'L'
        if line == '\r\n' then
            break
        else
            local k, v = line:match '^([^:]+)%s*%:%s*(.+)\r\n$'
            if k then
                if k == 'Content-Length' then
                    v = tonumber(v)
                end
                head[k] = v
            else
                pushError('Proto header error:', head)
                break
            end
        end
    end
    return head
end

local function readProtoContent(head)
    local len = head['Content-Length']
    if not len then
        pushError('Proto header error:', head)
        return nil
    end
    local buf = io.read(len)
    if not buf then
        return nil
    end
    local suc, res = pcall(json.decode, buf)
    if not suc then
        pushError('Proto error:', buf)
        return nil
    end
    return res
end

local function readProto()
    local head = readProtoHead(io.read)
    if not head then
        return
    end
    local data = readProtoContent(head)
    if not data then
        return
    end
    OUT:push(data)
end

while true do
    readProto()
    GC:push(ID, collectgarbage 'count')
end