aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ltn12.lua53
-rw-r--r--test/mimetest.lua2
2 files changed, 36 insertions, 19 deletions
diff --git a/src/ltn12.lua b/src/ltn12.lua
index 04656cb..4fabb7d 100644
--- a/src/ltn12.lua
+++ b/src/ltn12.lua
@@ -26,28 +26,45 @@ function filter.cycle(low, ctx, extra)
26 end 26 end
27end 27end
28 28
29-- given the return of a filter, can it have pending data?
30local function pending(s)
31 return s ~= "" and s
32end
33
29-- chains two filters together 34-- chains two filters together
30local function chain2(f1, f2) 35local function chain2(f1, f2)
31 assert(f1 and f2) 36 local cf1, cf2
32 local co = coroutine.create(function(chunk) 37 return function(chunk)
33 while true do 38 -- if f2 has pending data, service it first, always
34 local filtered1 = f1(chunk) 39 if pending(cf2) then
35 local filtered2 = f2(filtered1) 40 cf2 = f2(cf1)
36 local done2 = filtered1 and "" 41 if pending(cf2) then return cf2 end
37 while true do 42 end
38 if filtered2 == "" or filtered2 == nil then break end 43 -- here either f2 was already empty or we just found out it is
39 coroutine.yield(filtered2) 44 -- we get filtered data from f1
40 filtered2 = f2(done2) 45 cf1 = f1(chunk)
46 -- make sure next time we call f1 to get pending data,
47 -- we don't pass the same chunk again
48 if chunk then chunk = "" end
49 -- while there is data in f1
50 while pending(cf1) do
51 -- pass the new data to f2
52 cf2 = f2(cf1)
53 -- if f2 produced something, return it
54 if pending(cf2) then
55 -- make sure next time we call f2 to get pending data,
56 -- we don't pass the same chunk again
57 if cf1 then cf1 = "" end
58 return cf2
41 end 59 end
42 if filtered1 == "" then chunk = coroutine.yield(filtered1) 60 -- here f2 is still not satisfied with the amount of data
43 elseif filtered1 == nil then return nil 61 -- f1 produced. we keep trying.
44 else chunk = chunk and "" end 62 cf1 = f1(chunk)
45 end 63 end
46 end) 64 -- here f1 was empty or it became empty without managing
47 return function(chunk) 65 -- to produce enough data for f2 to produce something
48 local ret, a, b = coroutine.resume(co, chunk) 66 cf2 = f2(cf1)
49 if ret then return a, b 67 return cf2
50 else return nil, a end
51 end 68 end
52end 69end
53 70
diff --git a/test/mimetest.lua b/test/mimetest.lua
index d549ba6..0b3db33 100644
--- a/test/mimetest.lua
+++ b/test/mimetest.lua
@@ -8,7 +8,7 @@ local qptest = "qptest.bin"
8local eqptest = "qptest.bin2" 8local eqptest = "qptest.bin2"
9local dqptest = "qptest.bin3" 9local dqptest = "qptest.bin3"
10 10
11local b64test = "luasocket.so" 11local b64test = "luasocket.dylib"
12local eb64test = "b64test.bin" 12local eb64test = "b64test.bin"
13local db64test = "b64test.bin2" 13local db64test = "b64test.bin2"
14 14