util-soc-imp-tp.lua /size: 3116 b    last modification: 2020-07-01 14:35
1-- original file : tp.lua
2-- for more into : see util-soc.lua
3
4local setmetatable, next, type, tonumber = setmetatable, next, type, tonumber
5local find, upper = string.find, string.upper
6
7local socket     = socket or require("socket")
8local ltn12      = ltn12  or require("ltn12")
9
10local skipsocket = socket.skip
11local sinksocket = socket.sink
12local tcpsocket  = socket.tcp
13
14local ltn12pump  = ltn12.pump
15local pumpall    = ltn12pump.all
16local pumpstep   = ltn12pump.step
17
18local tp = {
19    TIMEOUT = 60,
20}
21
22socket.tp = tp
23
24local function get_reply(c)
25    local line, err = c:receive()
26    local reply = line
27    if err then return
28        nil, err
29    end
30    local code, sep = skipsocket(2, find(line, "^(%d%d%d)(.?)"))
31    if not code then
32        return nil, "invalid server reply"
33    end
34    if sep == "-" then
35        local current
36        repeat
37            line, err = c:receive()
38            if err then
39                return nil, err
40            end
41            current, sep = skipsocket(2, find(line, "^(%d%d%d)(.?)"))
42            reply = reply .. "\n" .. line
43        until code == current and sep == " "
44    end
45    return code, reply
46end
47
48local methods = { }
49local mt      = { __index = methods }
50
51function methods.getpeername(self)
52    return self.c:getpeername()
53end
54
55function methods.getsockname(self)
56    return self.c:getpeername()
57end
58
59function methods.check(self, ok)
60    local code, reply = get_reply(self.c)
61    if not code then
62        return nil, reply
63    end
64    local c = tonumber(code)
65    local t = type(ok)
66    if t == "function" then
67        return ok(c,reply)
68    elseif t == "table" then
69        for i=1,#ok do
70            if find(code,ok[i]) then
71                return c, reply
72            end
73        end
74        return nil, reply
75    elseif find(code, ok) then
76        return c, reply
77    else
78        return nil, reply
79    end
80end
81
82function methods.command(self, cmd, arg)
83    cmd = upper(cmd)
84    if arg then
85        cmd = cmd .. " " .. arg .. "\r\n"
86    else
87        cmd = cmd .. "\r\n"
88    end
89    return self.c:send(cmd)
90end
91
92function methods.sink(self, snk, pat)
93    local chunk, err = self.c:receive(pat)
94    return snk(chunk, err)
95end
96
97function methods.send(self, data)
98    return self.c:send(data)
99end
100
101function methods.receive(self, pat)
102    return self.c:receive(pat)
103end
104
105function methods.getfd(self)
106    return self.c:getfd()
107end
108
109function methods.dirty(self)
110    return self.c:dirty()
111end
112
113function methods.getcontrol(self)
114    return self.c
115end
116
117function methods.source(self, source, step)
118    local sink = sinksocket("keep-open", self.c)
119    local ret, err = pumpall(source, sink, step or pumpstep)
120    return ret, err
121end
122
123function methods.close(self)
124    self.c:close()
125    return 1
126end
127
128function tp.connect(host, port, timeout, create)
129    local c, e = (create or tcpsocket)()
130    if not c then
131        return nil, e
132    end
133    c:settimeout(timeout or tp.TIMEOUT)
134    local r, e = c:connect(host, port)
135    if not r then
136        c:close()
137        return nil, e
138    end
139    return setmetatable({ c = c }, mt)
140end
141
142package.loaded["socket.tp"] = tp
143
144return tp
145