aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2004-10-12 19:47:02 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2004-10-12 19:47:02 +0000
commit396946b63a95fc9949b75aed82c7ac1c132ccd40 (patch)
tree2e273e5cd0d3e351847a738044e49b1d3820b341
parent3c51a4cdd1f1169c90322863f763ee1462914fa8 (diff)
downloadluasocket-396946b63a95fc9949b75aed82c7ac1c132ccd40.tar.gz
luasocket-396946b63a95fc9949b75aed82c7ac1c132ccd40.tar.bz2
luasocket-396946b63a95fc9949b75aed82c7ac1c132ccd40.zip
Using Wim's filter.chain...
-rw-r--r--TODO2
-rw-r--r--src/ltn12.lua73
2 files changed, 29 insertions, 46 deletions
diff --git a/TODO b/TODO
index 37ae5a9..557c0db 100644
--- a/TODO
+++ b/TODO
@@ -4,7 +4,7 @@ new scheme to choose family/protocol of object to create
4change ltn13 to make sure drawbacks are obvious 4change ltn13 to make sure drawbacks are obvious
5 - check discussion 5 - check discussion
6make sure errors not thrown by try() are not caught by protect() 6make sure errors not thrown by try() are not caught by protect()
7use wim's filter.chain 7use wim's filter.chain or something better
8use mike's "don't set to blocking before closing unless needed" patch? 8use mike's "don't set to blocking before closing unless needed" patch?
9take a look at DB's smtp patch (add "extra argument" table) 9take a look at DB's smtp patch (add "extra argument" table)
10move wsocket.c:sock_send kludge to buffer.c:sendraw (probably)? 10move wsocket.c:sock_send kludge to buffer.c:sendraw (probably)?
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-----------------------------------------------------------------------------