Using Wim's filter.chain...

This commit is contained in:
Diego Nehab 2004-10-12 19:47:02 +00:00
parent 3c51a4cdd1
commit 396946b63a
2 changed files with 31 additions and 48 deletions

2
TODO
View File

@ -4,7 +4,7 @@ new scheme to choose family/protocol of object to create
change ltn13 to make sure drawbacks are obvious change ltn13 to make sure drawbacks are obvious
- check discussion - check discussion
make sure errors not thrown by try() are not caught by protect() make sure errors not thrown by try() are not caught by protect()
use wim's filter.chain use wim's filter.chain or something better
use mike's "don't set to blocking before closing unless needed" patch? use mike's "don't set to blocking before closing unless needed" patch?
take a look at DB's smtp patch (add "extra argument" table) take a look at DB's smtp patch (add "extra argument" table)
move wsocket.c:sock_send kludge to buffer.c:sendraw (probably)? move wsocket.c:sock_send kludge to buffer.c:sendraw (probably)?

View File

@ -31,55 +31,38 @@ function filter.cycle(low, ctx, extra)
end end
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)
local cf1, cf2
return function(chunk)
-- 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
-- chains a bunch of filters together -- chains a bunch of filters together
-- by Wim Couwenberg
function filter.chain(...) function filter.chain(...)
local f = arg[1] local current = 1
for i = 2, table.getn(arg) do local bottom = 1
f = chain2(f, arg[i]) local top = table.getn(arg)
local retry = ""
return function(chunk)
if chunk ~= retry then
current = bottom
retry = chunk and retry
end
repeat
if current == bottom then
chunk = arg[current](chunk)
if chunk == "" or bottom == top then return chunk
elseif chunk then current = current + 1
else
bottom = bottom + 1
current = bottom
end
else
chunk = arg[current](chunk or "")
if chunk == "" then
chunk = retry
current = current - 1
elseif current == top then return chunk
else current = current + 1
end
end
until false
end end
return f
end end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------