Skip to content

Commit 8d3c696

Browse files
committed
Implement iterator multi.iperform and method easy.perform for easy.
```Lua local cURL = require("lcurl") c1 = cURL.easy{url = "http://www.lua.org/"} c2 = cURL.easy{url ="http://luajit.org/"} m = cURL.multi() :add_handle(c1) :add_handle(c2) for a,b,c in m:iperform() do ... end ```
1 parent 9127eff commit 8d3c696

1 file changed

Lines changed: 126 additions & 65 deletions

File tree

src/lua/cURL/impl/cURL.lua

Lines changed: 126 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,69 @@ local function wrap_setopt_flags(k, flags)
3030
end
3131
end
3232

33+
local function make_iterator(self, perform)
34+
local curl = require "lcurl.safe"
35+
36+
local buffers = {resp = {}, _ = {}} do
37+
38+
function buffers:append(e, ...)
39+
local resp = assert(e:getinfo_response_code())
40+
if not self._[e] then self._[e] = {} end
41+
42+
local b = self._[e]
43+
44+
if self.resp[e] ~= resp then
45+
b[#b + 1] = {"response", resp}
46+
self.resp[e] = resp
47+
end
48+
49+
b[#b + 1] = {...}
50+
end
51+
52+
function buffers:next()
53+
for e, t in pairs(self._) do
54+
local m = table.remove(t, 1)
55+
if m then return e, m end
56+
end
57+
end
58+
59+
end
60+
61+
local remain = #self._easy
62+
for _, e in ipairs(self._easy) do
63+
e:setopt_writefunction (function(str) buffers:append(e, "data", str) end)
64+
e:setopt_headerfunction(function(str) buffers:append(e, "header", str) end)
65+
end
66+
67+
assert(perform(self))
68+
69+
return function()
70+
while true do
71+
local e, t = buffers:next()
72+
if t then return t[2], t[1], e end
73+
if remain == 0 then break end
74+
75+
self:wait()
76+
77+
local n, err = assert(perform(self))
78+
79+
if n <= remain then
80+
while true do
81+
local e, ok, err = assert(self:info_read())
82+
if e == 0 then break end
83+
for _, a in ipairs(self._easy) do
84+
if e == a:handle() then e = a break end
85+
end
86+
if ok then buffers:append(e, "done", ok)
87+
else buffers:append(e, "error", err) end
88+
end
89+
remain = n
90+
end
91+
92+
end
93+
end
94+
end
95+
3396
local function class(ctor)
3497
local C = {}
3598
C.__index = function(self, k)
@@ -42,14 +105,16 @@ local function class(ctor)
42105
return fn
43106
end
44107

45-
function C:new()
108+
function C:new(...)
46109
local h, err = ctor()
47110
if not h then return nil, err end
48111

49112
local o = setmetatable({
50113
_handle = h
51114
}, self)
52115

116+
if self.__init then return self.__init(o, ...) end
117+
53118
return o
54119
end
55120

@@ -207,74 +272,17 @@ local perform = wrap_function("perform")
207272
local add_handle = wrap_function("add_handle")
208273
local remove_handle = wrap_function("remove_handle")
209274

210-
local function make_iterator(self)
211-
local curl = require "lcurl.safe"
212-
213-
local buffers = {resp = {}, _ = {}} do
214-
215-
function buffers:append(e, ...)
216-
local resp = assert(e:getinfo_response_code())
217-
if not self._[e] then self._[e] = {} end
218-
219-
local b = self._[e]
220-
221-
if self.resp[e] ~= resp then
222-
b[#b + 1] = {"response", resp}
223-
self.resp[e] = resp
224-
end
225-
226-
b[#b + 1] = {...}
227-
end
228-
229-
function buffers:next()
230-
for e, t in pairs(self._) do
231-
local m = table.remove(t, 1)
232-
if m then return e, m end
233-
end
234-
end
235-
236-
end
237-
238-
local remain = #self._easy
239-
for _, e in ipairs(self._easy) do
240-
e:setopt_writefunction (function(str) buffers:append(e, "data", str) end)
241-
e:setopt_headerfunction(function(str) buffers:append(e, "header", str) end)
242-
end
243-
244-
assert(perform(self))
245-
246-
return function()
247-
while true do
248-
local e, t = buffers:next()
249-
if t then return t[2], t[1], e end
250-
if remain == 0 then break end
251-
252-
self:wait()
253-
254-
local n, err = assert(perform(self))
255-
256-
if n <= remain then
257-
while true do
258-
local e, ok, err = assert(self:info_read())
259-
if e == 0 then break end
260-
for _, a in ipairs(self._easy) do
261-
if e == a:handle() then e = a break end
262-
end
263-
if ok then buffers:append(e, "done", ok)
264-
else buffers:append(e, "error", err) end
265-
end
266-
remain = n
267-
end
268-
269-
end
270-
end
275+
function Multi:__init()
276+
self._easy = {}
277+
return self
271278
end
272279

273280
function Multi:perform()
274-
return make_iterator(self)
281+
return make_iterator(self, perform)
275282
end
276283

277284
function Multi:add_handle(e)
285+
self._easy = self._easy or {}
278286
self._easy[#self._easy + 1] = e
279287
return add_handle(self, e:handle())
280288
end
@@ -311,8 +319,61 @@ function cURL.share_init() return Share:new() end
311319
end
312320

313321
local function Load_cURLv3(cURL, curl)
314-
setmetatable(cURL, {__index = curl})
315-
-- @todo implement new API
322+
323+
-------------------------------------------
324+
local Easy = class(curl.easy) do
325+
326+
function Easy:__init(opt)
327+
if opt then return self:setopt(opt) end
328+
return self
329+
end
330+
331+
local perform = wrap_function("perform")
332+
function Easy:perform(opt)
333+
if opt then
334+
local ok, err = self:setopt(opt)
335+
if not ok then return nil, err end
336+
end
337+
338+
return perform(self)
339+
end
340+
341+
end
342+
-------------------------------------------
343+
344+
-------------------------------------------
345+
local Multi = class(curl.multi) do
346+
347+
function Multi:__init()
348+
self._easy = {}
349+
return self
350+
end
351+
352+
function Multi:iperform()
353+
return make_iterator(self, self.perform)
354+
end
355+
356+
local add_handle = wrap_function("add_handle")
357+
function Multi:add_handle(e)
358+
self._easy[#self._easy + 1] = e
359+
return add_handle(self, e:handle())
360+
end
361+
362+
local remove_handle = wrap_function("remove_handle")
363+
function Multi:remove_handle(e)
364+
self._easy[#self._easy + 1] = e
365+
return remove_handle(self, e:handle())
366+
end
367+
368+
end
369+
-------------------------------------------
370+
371+
setmetatable(cURL, {__index = curl})
372+
373+
function cURL.easy(...) return Easy:new(...) end
374+
375+
function cURL.multi(...) return Multi:new(...) end
376+
316377
end
317378

318379
return function(curl)

0 commit comments

Comments
 (0)