From ecb8db95a4ed38ec1a816a4ae42a1ddc7d1c0d0c Mon Sep 17 00:00:00 2001 From: Diego Nehab Date: Thu, 29 Jul 2004 05:11:21 +0000 Subject: [PATCH] Coroutine-free filter.chain. --- src/ltn12.lua | 55 +++++++++++++++++++++++++++++++---------------- test/mimetest.lua | 2 +- 2 files changed, 37 insertions(+), 20 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) end end +-- given the return of a filter, can it have pending data? +local function pending(s) + return s ~= "" and s +end + -- chains two filters together local function chain2(f1, f2) - assert(f1 and f2) - local co = coroutine.create(function(chunk) - while true do - local filtered1 = f1(chunk) - local filtered2 = f2(filtered1) - local done2 = filtered1 and "" - while true do - if filtered2 == "" or filtered2 == nil then break end - coroutine.yield(filtered2) - filtered2 = f2(done2) - end - if filtered1 == "" then chunk = coroutine.yield(filtered1) - elseif filtered1 == nil then return nil - else chunk = chunk and "" end - end - end) + local cf1, cf2 return function(chunk) - local ret, a, b = coroutine.resume(co, chunk) - if ret then return a, b - else return nil, a end + -- if f2 has pending data, service it first, always + if pending(cf2) then + cf2 = f2(cf1) + if pending(cf2) then return cf2 end + end + -- here either f2 was already empty or we just found out it is + -- we get filtered data from f1 + cf1 = f1(chunk) + -- make sure next time we call f1 to get pending data, + -- we don't pass the same chunk again + if chunk then chunk = "" end + -- while there is data in f1 + while pending(cf1) do + -- pass the new data to f2 + cf2 = f2(cf1) + -- if f2 produced something, return it + if pending(cf2) then + -- make sure next time we call f2 to get pending data, + -- we don't pass the same chunk again + if cf1 then cf1 = "" end + return cf2 + end + -- here f2 is still not satisfied with the amount of data + -- f1 produced. we keep trying. + cf1 = f1(chunk) + end + -- here f1 was empty or it became empty without managing + -- to produce enough data for f2 to produce something + cf2 = f2(cf1) + return cf2 end end 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" local eqptest = "qptest.bin2" local dqptest = "qptest.bin3" -local b64test = "luasocket.so" +local b64test = "luasocket.dylib" local eb64test = "b64test.bin" local db64test = "b64test.bin2"