aboutsummaryrefslogtreecommitdiff
path: root/src/ltn12.lua
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2004-02-11 03:31:53 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2004-02-11 03:31:53 +0000
commit390846b640ee7013d51a766b4b2472bdcfbbdfcc (patch)
tree3bedd023a0a84feb714615245b58eab5ffb4309b /src/ltn12.lua
parent0b2542d1a61fc5425ff65ab3dbf7ba7de174763f (diff)
downloadluasocket-390846b640ee7013d51a766b4b2472bdcfbbdfcc.tar.gz
luasocket-390846b640ee7013d51a766b4b2472bdcfbbdfcc.tar.bz2
luasocket-390846b640ee7013d51a766b4b2472bdcfbbdfcc.zip
Added ltn12 module. Modified mime to be stand alone.
Still crashes on invalid input. Dunno why.
Diffstat (limited to 'src/ltn12.lua')
-rw-r--r--src/ltn12.lua171
1 files changed, 171 insertions, 0 deletions
diff --git a/src/ltn12.lua b/src/ltn12.lua
new file mode 100644
index 0000000..548588a
--- /dev/null
+++ b/src/ltn12.lua
@@ -0,0 +1,171 @@
1-- create code namespace inside LuaSocket namespace
2ltn12 = ltn12 or {}
3-- make all module globals fall into mime namespace
4setmetatable(ltn12, { __index = _G })
5setfenv(1, ltn12)
6
7-- sub namespaces
8filter = {}
9source = {}
10sink = {}
11
12-- 2048 seems to be better in windows...
13BLOCKSIZE = 2048
14
15-- returns a high level filter that cycles a cycles a low-level filter
16function filter.cycle(low, ctx, extra)
17 return function(chunk)
18 local ret
19 ret, ctx = low(ctx, chunk, extra)
20 return ret
21 end
22end
23
24-- chains two filters together
25local function chain2(f1, f2)
26 return function(chunk)
27 local ret = f2(f1(chunk))
28 if chunk then return ret
29 else return ret .. f2() end
30 end
31end
32
33-- chains a bunch of filters together
34function filter.chain(...)
35 local f = arg[1]
36 for i = 2, table.getn(arg) do
37 f = chain2(f, arg[i])
38 end
39 return f
40end
41
42-- create an empty source
43function source.empty(err)
44 return function()
45 return nil, err
46 end
47end
48
49-- creates a file source
50function source.file(handle, io_err)
51 if handle then
52 return function()
53 local chunk = handle:read(BLOCKSIZE)
54 if not chunk then handle:close() end
55 return chunk
56 end
57 else source.empty(io_err or "unable to open file") end
58end
59
60-- turns a fancy source into a simple source
61function source.simplify(src)
62 return function()
63 local chunk, err_or_new = src()
64 src = err_or_new or src
65 if not chunk then return nil, err_or_new
66 else return chunk end
67 end
68end
69
70-- creates string source
71function source.string(s)
72 if s then
73 local i = 1
74 return function()
75 local chunk = string.sub(s, i, i+BLOCKSIZE-1)
76 i = i + BLOCKSIZE
77 if chunk ~= "" then return chunk
78 else return nil end
79 end
80 else source.empty() end
81end
82
83-- creates rewindable source
84function source.rewind(src)
85 local t = {}
86 src = source.simplify(src)
87 return function(chunk)
88 if not chunk then
89 chunk = table.remove(t)
90 if not chunk then return src()
91 else return chunk end
92 else
93 table.insert(t, chunk)
94 end
95 end
96end
97
98-- chains a source with a filter
99function source.chain(src, f)
100 src = source.simplify(src)
101 local chain = function()
102 local chunk, err = src()
103 if not chunk then return f(nil), source.empty(err)
104 else return f(chunk) end
105 end
106 return source.simplify(chain)
107end
108
109-- creates a sink that stores into a table
110function sink.table(t)
111 t = t or {}
112 local f = function(chunk, err)
113 if chunk then table.insert(t, chunk) end
114 return 1
115 end
116 return f, t
117end
118
119-- turns a fancy sink into a simple sink
120function sink.simplify(snk)
121 return function(chunk, err)
122 local ret, err_or_new = snk(chunk, err)
123 if not ret then return nil, err_or_new end
124 snk = err_or_new or snk
125 return 1
126 end
127end
128
129-- creates a file sink
130function sink.file(handle, io_err)
131 if handle then
132 return function(chunk, err)
133 if not chunk then
134 handle:close()
135 return nil, err
136 end
137 return handle:write(chunk)
138 end
139 else sink.null() end
140end
141
142-- creates a sink that discards data
143local function null()
144 return 1
145end
146
147function sink.null()
148 return null
149end
150
151-- chains a sink with a filter
152function sink.chain(f, snk)
153 snk = sink.simplify(snk)
154 return function(chunk, err)
155 local r, e = snk(f(chunk))
156 if not r then return nil, e end
157 if not chunk then return snk(nil, err) end
158 return 1
159 end
160end
161
162-- pumps all data from a source to a sink
163function pump(src, snk)
164 snk = sink.simplify(snk)
165 for chunk, src_err in source.simplify(src) do
166 local ret, snk_err = snk(chunk, src_err)
167 if not chunk or not ret then
168 return not src_err and not snk_err, src_err or snk_err
169 end
170 end
171end