aboutsummaryrefslogtreecommitdiff
path: root/src/ltn12.lua
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2004-11-28 00:59:12 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2004-11-28 00:59:12 +0000
commit05e8f243851049cebda6c5b690d3cde0f1e2c874 (patch)
tree9799a322fee3aefb07eaafa00875f214ad2b7ea6 /src/ltn12.lua
parent50da56dbeeec0cc7856ac06057cb778b502e087b (diff)
downloadluasocket-05e8f243851049cebda6c5b690d3cde0f1e2c874.tar.gz
luasocket-05e8f243851049cebda6c5b690d3cde0f1e2c874.tar.bz2
luasocket-05e8f243851049cebda6c5b690d3cde0f1e2c874.zip
New LTN12 test procedures (still short, but growing)
LTN12 avoids coroutines.
Diffstat (limited to 'src/ltn12.lua')
-rw-r--r--src/ltn12.lua131
1 files changed, 57 insertions, 74 deletions
diff --git a/src/ltn12.lua b/src/ltn12.lua
index 43c2755..5216ff6 100644
--- a/src/ltn12.lua
+++ b/src/ltn12.lua
@@ -35,64 +35,40 @@ function filter.cycle(low, ctx, extra)
35 end 35 end
36end 36end
37 37
38--[[ 38-- chains a bunch of filters together
39local function chain2(f1, f2) 39-- (thanks to Wim Couwenberg)
40 local ff1, ff2 = "", "" 40function filter.chain(...)
41 local n = table.getn(arg)
42 local top, index = 1, 1
41 return function(chunk) 43 return function(chunk)
42 local rf1 = chunk and "" 44 while true do
43 local rf2 = ff1 and "" 45 if index == top then
44 -- if f2 still has pending data, get it and return it 46 chunk = arg[index](chunk)
45 if ff2 ~= rf2 then 47 if chunk == "" or top == n then
46 ff2 = f2(rf2) 48 return chunk
47 if ff2 ~= "" then return ff2 end 49 elseif chunk then
48 end 50 index = index + 1
49 -- here we know f2 needs more data 51 else
50 -- we try to get it from f1 52 top = top+1
51 ff1 = f1(chunk) 53 index = top
52 while 1 do 54 end
53 -- if f1 can't produce data, we need more data from the user 55 else
54 if ff1 == "" then return "" end 56 local original = chunk
55 -- otherwise we pass new data to f2 until it produces something 57 chunk = arg[index](original or "")
56 -- or f1 runs out of data too 58 if chunk == "" then
57 ff2 = f2(ff1) 59 index = index - 1
58 if ff2 ~= "" then return ff2 end 60 chunk = original and chunk
59 ff1 = f1(rf1) 61 elseif chunk then
60 end 62 if index == n then return chunk
61 end 63 else index = index + 1 end
62end 64 else
63]] 65 base.error("filter returned inappropriate nil")
64 66 end
65local function chain2(f1, f2)
66 local co = coroutine.create(function(chunk)
67 while true do
68 local filtered1 = f1(chunk)
69 local filtered2 = f2(filtered1)
70 local done2 = filtered1 and ""
71 while true do
72 if filtered2 == "" or filtered2 == nil then break end
73 coroutine.yield(filtered2)
74 filtered2 = f2(done2)
75 end 67 end
76 if filtered1 == "" then chunk = coroutine.yield(filtered1)
77 elseif filtered1 == nil then return nil
78 else chunk = chunk and "" end
79 end 68 end
80 end)
81 return function(chunk)
82 local _, res = coroutine.resume(co, chunk)
83 return res
84 end 69 end
85end 70end
86 71
87-- chains a bunch of filters together
88function filter.chain(...)
89 local f = arg[1]
90 for i = 2, table.getn(arg) do
91 f = chain2(f, arg[i])
92 end
93 return f
94end
95
96----------------------------------------------------------------------------- 72-----------------------------------------------------------------------------
97-- Source stuff 73-- Source stuff
98----------------------------------------------------------------------------- 74-----------------------------------------------------------------------------
@@ -165,23 +141,28 @@ end
165-- chains a source with a filter 141-- chains a source with a filter
166function source.chain(src, f) 142function source.chain(src, f)
167 base.assert(src and f) 143 base.assert(src and f)
168 local co = coroutine.create(function() 144 local last_in, last_out = "", ""
169 while true do 145 return function()
170 local chunk, err = src() 146 if last_out == "" then
171 if err then return nil, err end
172 local filtered = f(chunk)
173 local done = chunk and ""
174 while true do 147 while true do
175 coroutine.yield(filtered) 148 local err
176 if filtered == done then break end 149 last_in, err = src()
177 filtered = f(done) 150 if err then return nil, err end
151 last_out = f(last_in)
152 if last_out ~= "" then return last_out end
153 if not last_in then
154 error('filter returned inappropriate ""')
155 end
178 end 156 end
157 elseif last_out then
158 last_out = f(last_in and "")
159 if last_in and not last_out then
160 error('filter returned inappropriate nil')
161 end
162 return last_out
163 else
164 base.error("source is empty", 2)
179 end 165 end
180 end)
181 return function()
182 local ret, a, b = coroutine.resume(co)
183 if ret then return a, b
184 else return nil, a end
185 end 166 end
186end 167end
187 168
@@ -260,14 +241,16 @@ end
260function sink.chain(f, snk) 241function sink.chain(f, snk)
261 base.assert(f and snk) 242 base.assert(f and snk)
262 return function(chunk, err) 243 return function(chunk, err)
263 local filtered = f(chunk) 244 if chunk ~= "" then
264 local done = chunk and "" 245 local filtered = f(chunk)
265 while true do 246 local done = chunk and ""
266 local ret, snkerr = snk(filtered, err) 247 while true do
267 if not ret then return nil, snkerr end 248 local ret, snkerr = snk(filtered, err)
268 if filtered == done then return 1 end 249 if not ret then return nil, snkerr end
269 filtered = f(done) 250 if filtered == done then return 1 end
270 end 251 filtered = f(done)
252 end
253 else return 1 end
271 end 254 end
272end 255end
273 256