aboutsummaryrefslogtreecommitdiff
path: root/src/ltn12.lua
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2004-03-16 06:42:53 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2004-03-16 06:42:53 +0000
commitbcc0c2a9f0be2ca796ef5206a78e283fe15e6186 (patch)
tree65c269d4854aa5ff4a0b2c8eede5cdb18d716033 /src/ltn12.lua
parentb6edaac2841137cf0ef5105f75358bbab4570d87 (diff)
downloadluasocket-bcc0c2a9f0be2ca796ef5206a78e283fe15e6186.tar.gz
luasocket-bcc0c2a9f0be2ca796ef5206a78e283fe15e6186.tar.bz2
luasocket-bcc0c2a9f0be2ca796ef5206a78e283fe15e6186.zip
New filter scheme.
ltn12 and mime updated. smtp/ftp broken.
Diffstat (limited to 'src/ltn12.lua')
-rw-r--r--src/ltn12.lua75
1 files changed, 54 insertions, 21 deletions
diff --git a/src/ltn12.lua b/src/ltn12.lua
index 548588a..de7103d 100644
--- a/src/ltn12.lua
+++ b/src/ltn12.lua
@@ -1,6 +1,6 @@
1-- create code namespace inside LuaSocket namespace 1-- create module namespace
2ltn12 = ltn12 or {} 2ltn12 = ltn12 or {}
3-- make all module globals fall into mime namespace 3-- make all globals fall into ltn12 namespace
4setmetatable(ltn12, { __index = _G }) 4setmetatable(ltn12, { __index = _G })
5setfenv(1, ltn12) 5setfenv(1, ltn12)
6 6
@@ -12,6 +12,14 @@ sink = {}
12-- 2048 seems to be better in windows... 12-- 2048 seems to be better in windows...
13BLOCKSIZE = 2048 13BLOCKSIZE = 2048
14 14
15local function second(a, b)
16 return b
17end
18
19local function skip(a, b, c)
20 return b, c
21end
22
15-- returns a high level filter that cycles a cycles a low-level filter 23-- returns a high level filter that cycles a cycles a low-level filter
16function filter.cycle(low, ctx, extra) 24function filter.cycle(low, ctx, extra)
17 return function(chunk) 25 return function(chunk)
@@ -24,9 +32,7 @@ end
24-- chains two filters together 32-- chains two filters together
25local function chain2(f1, f2) 33local function chain2(f1, f2)
26 return function(chunk) 34 return function(chunk)
27 local ret = f2(f1(chunk)) 35 return f2(f1(chunk))
28 if chunk then return ret
29 else return ret .. f2() end
30 end 36 end
31end 37end
32 38
@@ -83,7 +89,6 @@ end
83-- creates rewindable source 89-- creates rewindable source
84function source.rewind(src) 90function source.rewind(src)
85 local t = {} 91 local t = {}
86 src = source.simplify(src)
87 return function(chunk) 92 return function(chunk)
88 if not chunk then 93 if not chunk then
89 chunk = table.remove(t) 94 chunk = table.remove(t)
@@ -97,13 +102,38 @@ end
97 102
98-- chains a source with a filter 103-- chains a source with a filter
99function source.chain(src, f) 104function source.chain(src, f)
100 src = source.simplify(src) 105 local co = coroutine.create(function()
101 local chain = function() 106 while true do
102 local chunk, err = src() 107 local chunk, err = src()
103 if not chunk then return f(nil), source.empty(err) 108 local filtered = f(chunk)
104 else return f(chunk) end 109 local done = chunk and ""
110 while true do
111 coroutine.yield(filtered)
112 if filtered == done then break end
113 filtered = f(done)
114 end
115 if not chunk then return nil, err end
116 end
117 end)
118 return function()
119 return skip(coroutine.resume(co))
105 end 120 end
106 return source.simplify(chain) 121end
122
123-- creates a source that produces contents of several files one after the
124-- other, as if they were concatenated
125function source.cat(...)
126 local co = coroutine.create(function()
127 local i = 1
128 while i <= table.getn(arg) do
129 local chunk = arg[i]:read(2048)
130 if chunk then coroutine.yield(chunk)
131 else i = i + 1 end
132 end
133 end)
134 return source.simplify(function()
135 return second(coroutine.resume(co))
136 end)
107end 137end
108 138
109-- creates a sink that stores into a table 139-- creates a sink that stores into a table
@@ -150,22 +180,25 @@ end
150 180
151-- chains a sink with a filter 181-- chains a sink with a filter
152function sink.chain(f, snk) 182function sink.chain(f, snk)
153 snk = sink.simplify(snk)
154 return function(chunk, err) 183 return function(chunk, err)
155 local r, e = snk(f(chunk)) 184 local filtered = f(chunk)
156 if not r then return nil, e end 185 local done = chunk and ""
157 if not chunk then return snk(nil, err) end 186 while true do
158 return 1 187 local ret, snkerr = snk(filtered, err)
188 if not ret then return nil, snkerr end
189 if filtered == done then return 1 end
190 filtered = f(done)
191 end
159 end 192 end
160end 193end
161 194
162-- pumps all data from a source to a sink 195-- pumps all data from a source to a sink
163function pump(src, snk) 196function pump(src, snk)
164 snk = sink.simplify(snk) 197 while true do
165 for chunk, src_err in source.simplify(src) do 198 local chunk, src_err = src()
166 local ret, snk_err = snk(chunk, src_err) 199 local ret, snk_err = snk(chunk, src_err)
167 if not chunk or not ret then 200 if not chunk or not ret then
168 return not src_err and not snk_err, src_err or snk_err 201 return not src_err and not snk_err, src_err or snk_err
169 end 202 end
170 end 203 end
171end 204end