aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ltn12.lua73
1 files changed, 28 insertions, 45 deletions
diff --git a/src/ltn12.lua b/src/ltn12.lua
index 993d3c3..6c5ea28 100644
--- a/src/ltn12.lua
+++ b/src/ltn12.lua
@@ -31,55 +31,38 @@ function filter.cycle(low, ctx, extra)
31 end 31 end
32end 32end
33 33
34-- given the return of a filter, can it have pending data? 34-- chains a bunch of filters together
35local function pending(s) 35-- by Wim Couwenberg
36 return s ~= "" and s 36function filter.chain(...)
37end 37 local current = 1
38 38 local bottom = 1
39-- chains two filters together 39 local top = table.getn(arg)
40local function chain2(f1, f2) 40 local retry = ""
41 local cf1, cf2
42 return function(chunk) 41 return function(chunk)
43 -- if f2 has pending data, service it first, always 42 if chunk ~= retry then
44 if pending(cf2) then 43 current = bottom
45 cf2 = f2(cf1) 44 retry = chunk and retry
46 if pending(cf2) then return cf2 end
47 end 45 end
48 -- here either f2 was already empty or we just found out it is 46 repeat
49 -- we get filtered data from f1 47 if current == bottom then
50 cf1 = f1(chunk) 48 chunk = arg[current](chunk)
51 -- make sure next time we call f1 to get pending data, 49 if chunk == "" or bottom == top then return chunk
52 -- we don't pass the same chunk again 50 elseif chunk then current = current + 1
53 if chunk then chunk = "" end 51 else
54 -- while there is data in f1 52 bottom = bottom + 1
55 while pending(cf1) do 53 current = bottom
56 -- pass the new data to f2 54 end
57 cf2 = f2(cf1) 55 else
58 -- if f2 produced something, return it 56 chunk = arg[current](chunk or "")
59 if pending(cf2) then 57 if chunk == "" then
60 -- make sure next time we call f2 to get pending data, 58 chunk = retry
61 -- we don't pass the same chunk again 59 current = current - 1
62 if cf1 then cf1 = "" end 60 elseif current == top then return chunk
63 return cf2 61 else current = current + 1
62 end
64 end 63 end
65 -- here f2 is still not satisfied with the amount of data 64 until false
66 -- f1 produced. we keep trying.
67 cf1 = f1(chunk)
68 end
69 -- here f1 was empty or it became empty without managing
70 -- to produce enough data for f2 to produce something
71 cf2 = f2(cf1)
72 return cf2
73 end
74end
75
76-- chains a bunch of filters together
77function filter.chain(...)
78 local f = arg[1]
79 for i = 2, table.getn(arg) do
80 f = chain2(f, arg[i])
81 end 65 end
82 return f
83end 66end
84 67
85----------------------------------------------------------------------------- 68-----------------------------------------------------------------------------