@@ -30,6 +30,69 @@ local function wrap_setopt_flags(k, flags)
3030 end
3131end
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+
3396local 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")
207272local add_handle = wrap_function (" add_handle" )
208273local 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
271278end
272279
273280function Multi :perform ()
274- return make_iterator (self )
281+ return make_iterator (self , perform )
275282end
276283
277284function Multi :add_handle (e )
285+ self ._easy = self ._easy or {}
278286 self ._easy [# self ._easy + 1 ] = e
279287 return add_handle (self , e :handle ())
280288end
@@ -311,8 +319,61 @@ function cURL.share_init() return Share:new() end
311319end
312320
313321local 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+
316377end
317378
318379return function (curl )
0 commit comments