aboutsummaryrefslogtreecommitdiff
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
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.
-rw-r--r--TODO6
-rw-r--r--doc/reference.html2
-rw-r--r--etc/eol.lua4
-rw-r--r--etc/qp.lua4
-rw-r--r--src/ltn12.lua171
-rw-r--r--src/luasocket.c2
-rw-r--r--src/mime.c84
-rw-r--r--src/mime.lua74
-rw-r--r--src/wsocket.c8
-rw-r--r--src/wsocket.h1
-rw-r--r--test/ltn12test.lua3
-rw-r--r--test/mimetest.lua93
12 files changed, 291 insertions, 161 deletions
diff --git a/TODO b/TODO
index 9e9923c..7479cfc 100644
--- a/TODO
+++ b/TODO
@@ -19,10 +19,16 @@
19* Separar as classes em arquivos 19* Separar as classes em arquivos
20* Retorno de sendto em datagram sockets pode ser refused 20* Retorno de sendto em datagram sockets pode ser refused
21 21
22unify filter and send/receive callback. new sink/source/pump idea.
23get rid of aux_optlstring
24wrap sink and sources with a function that performs the replacement
25get rid of unpack in mime.lua
22 26
23check garbage collection in test*.lua 27check garbage collection in test*.lua
24pop3??? 28pop3???
25 29
30break chain into a simpler binary chain and a complex (recursive) one.
31
26add socket.TIMEOUT to be default timeout? 32add socket.TIMEOUT to be default timeout?
27 33
28manual 34manual
diff --git a/doc/reference.html b/doc/reference.html
index e6efb6e..6e14891 100644
--- a/doc/reference.html
+++ b/doc/reference.html
@@ -126,7 +126,7 @@
126<a href="mime.html">MIME (socket.mime) </a> 126<a href="mime.html">MIME (socket.mime) </a>
127<blockquote> 127<blockquote>
128<a href="mime.html#high">high-level</a>: 128<a href="mime.html#high">high-level</a>:
129<a href="mime.html#decode">canonic</a>, 129<a href="mime.html#normalize">normalize</a>,
130<a href="mime.html#chain">chain</a>, 130<a href="mime.html#chain">chain</a>,
131<a href="mime.html#decode">decode</a>, 131<a href="mime.html#decode">decode</a>,
132<a href="mime.html#encode">encode</a>, 132<a href="mime.html#encode">encode</a>,
diff --git a/etc/eol.lua b/etc/eol.lua
index fea5da9..6b2a8a9 100644
--- a/etc/eol.lua
+++ b/etc/eol.lua
@@ -1,9 +1,9 @@
1marker = {['-u'] = '\10', ['-d'] = '\13\10'} 1marker = {['-u'] = '\10', ['-d'] = '\13\10'}
2arg = arg or {'-u'} 2arg = arg or {'-u'}
3marker = marker[arg[1]] or marker['-u'] 3marker = marker[arg[1]] or marker['-u']
4local convert = socket.mime.canonic(marker) 4local convert = socket.mime.normalize(marker)
5while 1 do 5while 1 do
6 local chunk = io.read(4096) 6 local chunk = io.read(1)
7 io.write(convert(chunk)) 7 io.write(convert(chunk))
8 if not chunk then break end 8 if not chunk then break end
9end 9end
diff --git a/etc/qp.lua b/etc/qp.lua
index 23c834a..1ca0ae2 100644
--- a/etc/qp.lua
+++ b/etc/qp.lua
@@ -2,10 +2,10 @@ local convert
2arg = arg or {} 2arg = arg or {}
3local mode = arg and arg[1] or "-et" 3local mode = arg and arg[1] or "-et"
4if mode == "-et" then 4if mode == "-et" then
5 local canonic = socket.mime.canonic() 5 local normalize = socket.mime.normalize()
6 local qp = socket.mime.encode("quoted-printable") 6 local qp = socket.mime.encode("quoted-printable")
7 local wrap = socket.mime.wrap("quoted-printable") 7 local wrap = socket.mime.wrap("quoted-printable")
8 convert = socket.mime.chain(canonic, qp, wrap) 8 convert = socket.mime.chain(normalize, qp, wrap)
9elseif mode == "-eb" then 9elseif mode == "-eb" then
10 local qp = socket.mime.encode("quoted-printable", "binary") 10 local qp = socket.mime.encode("quoted-printable", "binary")
11 local wrap = socket.mime.wrap("quoted-printable") 11 local wrap = socket.mime.wrap("quoted-printable")
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
diff --git a/src/luasocket.c b/src/luasocket.c
index e99fcdf..47696cb 100644
--- a/src/luasocket.c
+++ b/src/luasocket.c
@@ -72,6 +72,7 @@ static int mod_open(lua_State *L, const luaL_reg *mod)
72{ 72{
73 for (; mod->name; mod++) mod->func(L); 73 for (; mod->name; mod++) mod->func(L);
74#ifdef LUASOCKET_COMPILED 74#ifdef LUASOCKET_COMPILED
75#include "ltn12.lch"
75#include "auxiliar.lch" 76#include "auxiliar.lch"
76#include "concat.lch" 77#include "concat.lch"
77#include "url.lch" 78#include "url.lch"
@@ -81,6 +82,7 @@ static int mod_open(lua_State *L, const luaL_reg *mod)
81#include "ftp.lch" 82#include "ftp.lch"
82#include "http.lch" 83#include "http.lch"
83#else 84#else
85 lua_dofile(L, "ltn12.lua");
84 lua_dofile(L, "auxiliar.lua"); 86 lua_dofile(L, "auxiliar.lua");
85 lua_dofile(L, "concat.lua"); 87 lua_dofile(L, "concat.lua");
86 lua_dofile(L, "url.lua"); 88 lua_dofile(L, "url.lua");
diff --git a/src/mime.c b/src/mime.c
index 9fc4f51..ae4084d 100644
--- a/src/mime.c
+++ b/src/mime.c
@@ -9,8 +9,6 @@
9#include <lua.h> 9#include <lua.h>
10#include <lauxlib.h> 10#include <lauxlib.h>
11 11
12#include "luasocket.h"
13#include "auxiliar.h"
14#include "mime.h" 12#include "mime.h"
15 13
16/*=========================================================================*\ 14/*=========================================================================*\
@@ -83,12 +81,10 @@ static UC b64unbase[256];
83\*-------------------------------------------------------------------------*/ 81\*-------------------------------------------------------------------------*/
84int mime_open(lua_State *L) 82int mime_open(lua_State *L)
85{ 83{
86 lua_pushstring(L, LUASOCKET_LIBNAME);
87 lua_gettable(L, LUA_GLOBALSINDEX);
88 lua_pushstring(L, "mime"); 84 lua_pushstring(L, "mime");
89 lua_newtable(L); 85 lua_newtable(L);
90 luaL_openlib(L, NULL, func, 0); 86 luaL_openlib(L, NULL, func, 0);
91 lua_settable(L, -3); 87 lua_settable(L, LUA_GLOBALSINDEX);
92 lua_pop(L, 1); 88 lua_pop(L, 1);
93 /* initialize lookup tables */ 89 /* initialize lookup tables */
94 qpsetup(qpclass, qpunbase); 90 qpsetup(qpclass, qpunbase);
@@ -110,7 +106,7 @@ static int mime_global_wrp(lua_State *L)
110{ 106{
111 size_t size = 0; 107 size_t size = 0;
112 int left = (int) luaL_checknumber(L, 1); 108 int left = (int) luaL_checknumber(L, 1);
113 const UC *input = (UC *) aux_optlstring(L, 2, NULL, &size); 109 const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size);
114 const UC *last = input + size; 110 const UC *last = input + size;
115 int length = (int) luaL_optnumber(L, 3, 76); 111 int length = (int) luaL_optnumber(L, 3, 76);
116 luaL_Buffer buffer; 112 luaL_Buffer buffer;
@@ -261,7 +257,7 @@ static int mime_global_b64(lua_State *L)
261 luaL_buffinit(L, &buffer); 257 luaL_buffinit(L, &buffer);
262 while (input < last) 258 while (input < last)
263 asize = b64encode(*input++, atom, asize, &buffer); 259 asize = b64encode(*input++, atom, asize, &buffer);
264 input = (UC *) aux_optlstring(L, 2, NULL, &isize); 260 input = (UC *) luaL_optlstring(L, 2, NULL, &isize);
265 if (input) { 261 if (input) {
266 last = input + isize; 262 last = input + isize;
267 while (input < last) 263 while (input < last)
@@ -289,7 +285,7 @@ static int mime_global_unb64(lua_State *L)
289 luaL_buffinit(L, &buffer); 285 luaL_buffinit(L, &buffer);
290 while (input < last) 286 while (input < last)
291 asize = b64decode(*input++, atom, asize, &buffer); 287 asize = b64decode(*input++, atom, asize, &buffer);
292 input = (UC *) aux_optlstring(L, 2, NULL, &isize); 288 input = (UC *) luaL_optlstring(L, 2, NULL, &isize);
293 if (input) { 289 if (input) {
294 last = input + isize; 290 last = input + isize;
295 while (input < last) 291 while (input < last)
@@ -426,14 +422,14 @@ static int mime_global_qp(lua_State *L)
426 422
427 size_t asize = 0, isize = 0; 423 size_t asize = 0, isize = 0;
428 UC atom[3]; 424 UC atom[3];
429 const UC *input = (UC *) aux_optlstring(L, 1, NULL, &isize); 425 const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize);
430 const UC *last = input + isize; 426 const UC *last = input + isize;
431 const char *marker = luaL_optstring(L, 3, CRLF); 427 const char *marker = luaL_optstring(L, 3, CRLF);
432 luaL_Buffer buffer; 428 luaL_Buffer buffer;
433 luaL_buffinit(L, &buffer); 429 luaL_buffinit(L, &buffer);
434 while (input < last) 430 while (input < last)
435 asize = qpencode(*input++, atom, asize, marker, &buffer); 431 asize = qpencode(*input++, atom, asize, marker, &buffer);
436 input = (UC *) aux_optlstring(L, 2, NULL, &isize); 432 input = (UC *) luaL_optlstring(L, 2, NULL, &isize);
437 if (input) { 433 if (input) {
438 last = input + isize; 434 last = input + isize;
439 while (input < last) 435 while (input < last)
@@ -495,13 +491,13 @@ static int mime_global_unqp(lua_State *L)
495 491
496 size_t asize = 0, isize = 0; 492 size_t asize = 0, isize = 0;
497 UC atom[3]; 493 UC atom[3];
498 const UC *input = (UC *) aux_optlstring(L, 1, NULL, &isize); 494 const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize);
499 const UC *last = input + isize; 495 const UC *last = input + isize;
500 luaL_Buffer buffer; 496 luaL_Buffer buffer;
501 luaL_buffinit(L, &buffer); 497 luaL_buffinit(L, &buffer);
502 while (input < last) 498 while (input < last)
503 asize = qpdecode(*input++, atom, asize, &buffer); 499 asize = qpdecode(*input++, atom, asize, &buffer);
504 input = (UC *) aux_optlstring(L, 2, NULL, &isize); 500 input = (UC *) luaL_optlstring(L, 2, NULL, &isize);
505 if (input) { 501 if (input) {
506 last = input + isize; 502 last = input + isize;
507 while (input < last) 503 while (input < last)
@@ -525,7 +521,7 @@ static int mime_global_qpwrp(lua_State *L)
525{ 521{
526 size_t size = 0; 522 size_t size = 0;
527 int left = (int) luaL_checknumber(L, 1); 523 int left = (int) luaL_checknumber(L, 1);
528 const UC *input = (UC *) aux_optlstring(L, 2, NULL, &size); 524 const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size);
529 const UC *last = input + size; 525 const UC *last = input + size;
530 int length = (int) luaL_optnumber(L, 3, 76); 526 int length = (int) luaL_optnumber(L, 3, 76);
531 luaL_Buffer buffer; 527 luaL_Buffer buffer;
@@ -576,54 +572,52 @@ static int mime_global_qpwrp(lua_State *L)
576* probably other more obscure conventions. 572* probably other more obscure conventions.
577\*-------------------------------------------------------------------------*/ 573\*-------------------------------------------------------------------------*/
578#define eolcandidate(c) (c == CR || c == LF) 574#define eolcandidate(c) (c == CR || c == LF)
579static size_t eolconvert(UC c, UC *input, size_t size, 575static size_t eolprocess(int c, int ctx, const char *marker,
580 const char *marker, luaL_Buffer *buffer) 576 luaL_Buffer *buffer)
581{ 577{
582 input[size++] = c; 578 if (eolcandidate(ctx)) {
583 /* deal with all characters we can deal */
584 if (eolcandidate(input[0])) {
585 if (size < 2) return size;
586 luaL_addstring(buffer, marker); 579 luaL_addstring(buffer, marker);
587 if (eolcandidate(input[1])) { 580 if (eolcandidate(c)) {
588 if (input[0] == input[1]) luaL_addstring(buffer, marker); 581 if (c == ctx)
589 } else luaL_putchar(buffer, input[1]); 582 luaL_addstring(buffer, marker);
590 return 0; 583 return 0;
584 } else {
585 luaL_putchar(buffer, c);
586 return 0;
587 }
591 } else { 588 } else {
592 luaL_putchar(buffer, input[0]); 589 if (!eolcandidate(c)) {
593 return 0; 590 luaL_putchar(buffer, c);
591 return 0;
592 } else
593 return c;
594 } 594 }
595} 595}
596 596
597/*-------------------------------------------------------------------------*\ 597/*-------------------------------------------------------------------------*\
598* Converts a string to uniform EOL convention. 598* Converts a string to uniform EOL convention.
599* A, B = eol(C, D, marker) 599* A, n = eol(o, B, marker)
600* A is the converted version of the largest prefix of C .. D that 600* A is the converted version of the largest prefix of B that can be
601* can be converted without doubts. 601* converted unambiguously. 'o' is the context returned by the previous
602* B has the remaining bytes of C .. D, *without* convertion. 602* call. 'n' is the new context.
603\*-------------------------------------------------------------------------*/ 603\*-------------------------------------------------------------------------*/
604static int mime_global_eol(lua_State *L) 604static int mime_global_eol(lua_State *L)
605{ 605{
606 size_t asize = 0, isize = 0; 606 int ctx = luaL_checkint(L, 1);
607 UC atom[2]; 607 size_t isize = 0;
608 const UC *input = (UC *) aux_optlstring(L, 1, NULL, &isize); 608 const char *input = luaL_optlstring(L, 2, NULL, &isize);
609 const UC *last = input + isize; 609 const char *last = input + isize;
610 const char *marker = luaL_optstring(L, 3, CRLF); 610 const char *marker = luaL_optstring(L, 3, CRLF);
611 luaL_Buffer buffer; 611 luaL_Buffer buffer;
612 luaL_buffinit(L, &buffer); 612 luaL_buffinit(L, &buffer);
613 while (input < last) 613 while (input < last)
614 asize = eolconvert(*input++, atom, asize, marker, &buffer); 614 ctx = eolprocess(*input++, ctx, marker, &buffer);
615 input = (UC *) aux_optlstring(L, 2, NULL, &isize); 615 /* if the last character was a candidate, we output a new line */
616 if (input) { 616 if (!input) {
617 last = input + isize; 617 if (eolcandidate(ctx)) luaL_addstring(&buffer, marker);
618 while (input < last) 618 ctx = 0;
619 asize = eolconvert(*input++, atom, asize, marker, &buffer);
620 /* if there is something in atom, it's one character, and it
621 * is a candidate. so we output a new line */
622 } else if (asize > 0) {
623 luaL_addstring(&buffer, marker);
624 asize = 0;
625 } 619 }
626 luaL_pushresult(&buffer); 620 luaL_pushresult(&buffer);
627 lua_pushlstring(L, (char *) atom, asize); 621 lua_pushnumber(L, ctx);
628 return 2; 622 return 2;
629} 623}
diff --git a/src/mime.lua b/src/mime.lua
index 369567f..4df0388 100644
--- a/src/mime.lua
+++ b/src/mime.lua
@@ -1,11 +1,6 @@
1-- make sure LuaSocket is loaded 1if not ltn12 then error('This module requires LTN12') end
2if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end 2-- create mime namespace
3-- get LuaSocket namespace 3mime = mime or {}
4local socket = _G[LUASOCKET_LIBNAME]
5if not socket then error('module requires LuaSocket') end
6-- create code namespace inside LuaSocket namespace
7local mime = socket.mime or {}
8socket.mime = mime
9-- make all module globals fall into mime namespace 4-- make all module globals fall into mime namespace
10setmetatable(mime, { __index = _G }) 5setmetatable(mime, { __index = _G })
11setfenv(1, mime) 6setfenv(1, mime)
@@ -15,80 +10,61 @@ local et = {}
15local dt = {} 10local dt = {}
16local wt = {} 11local wt = {}
17 12
18-- creates a function that chooses a filter from a given table 13-- creates a function that chooses a filter by name from a given table
19local function choose(table) 14local function choose(table)
20 return function(filter, ...) 15 return function(name, opt)
21 local f = table[filter or "nil"] 16 local f = table[name or "nil"]
22 if not f then error("unknown filter (" .. tostring(filter) .. ")", 3) 17 if not f then error("unknown filter (" .. tostring(name) .. ")", 3)
23 else return f(unpack(arg)) end 18 else return f(opt) end
24 end 19 end
25end 20end
26 21
27-- define the encoding filters 22-- define the encoding filters
28et['base64'] = function() 23et['base64'] = function()
29 return socket.cicle(b64, "") 24 return ltn12.filter.cycle(b64, "")
30end 25end
31 26
32et['quoted-printable'] = function(mode) 27et['quoted-printable'] = function(mode)
33 return socket.cicle(qp, "", (mode == "binary") and "=0D=0A" or "\13\10") 28 return ltn12.filter.cycle(qp, "",
29 (mode == "binary") and "=0D=0A" or "\13\10")
34end 30end
35 31
36-- define the decoding filters 32-- define the decoding filters
37dt['base64'] = function() 33dt['base64'] = function()
38 return socket.cicle(unb64, "") 34 return ltn12.filter.cycle(unb64, "")
39end 35end
40 36
41dt['quoted-printable'] = function() 37dt['quoted-printable'] = function()
42 return socket.cicle(unqp, "") 38 return ltn12.filter.cycle(unqp, "")
43end 39end
44 40
45-- define the line-wrap filters 41-- define the line-wrap filters
46wt['text'] = function(length) 42wt['text'] = function(length)
47 length = length or 76 43 length = length or 76
48 return socket.cicle(wrp, length, length) 44 return ltn12.filter.cycle(wrp, length, length)
49end 45end
50wt['base64'] = wt['text'] 46wt['base64'] = wt['text']
51 47
52wt['quoted-printable'] = function() 48wt['quoted-printable'] = function()
53 return socket.cicle(qpwrp, 76, 76) 49 return ltn12.filter.cycle(qpwrp, 76, 76)
54end 50end
55 51
56-- function that choose the encoding, decoding or wrap algorithm 52-- function that choose the encoding, decoding or wrap algorithm
57encode = choose(et) 53encode = choose(et)
58decode = choose(dt) 54decode = choose(dt)
59-- there is a default wrap filter 55-- there is different because there is a default wrap filter
60local cwt = choose(wt) 56local cwt = choose(wt)
61function wrap(...) 57function wrap(mode_or_length, length)
62 if type(arg[1]) ~= "string" then table.insert(arg, 1, "text") end 58 if type(mode_or_length) ~= "string" then
63 return cwt(unpack(arg)) 59 length = mode_or_length
64end 60 mode_or_length = "text"
65 61 end
66-- define the end-of-line translation filter 62 return cwt(mode_or_length, length)
67function canonic(marker)
68 return socket.cicle(eol, "", marker)
69end 63end
70 64
71-- chains several filters together 65-- define the end-of-line normalization filter
72function chain(...) 66function normalize(marker)
73 local layers = table.getn(arg) 67 return ltn12.filter.cycle(eol, 0, marker)
74 return function (chunk)
75 if not chunk then
76 local parts = {}
77 for i = 1, layers do
78 for j = i, layers do
79 chunk = arg[j](chunk)
80 end
81 table.insert(parts, chunk)
82 chunk = nil
83 end
84 return table.concat(parts)
85 else
86 for j = 1, layers do
87 chunk = arg[j](chunk)
88 end
89 return chunk
90 end
91 end
92end 68end
93 69
94return mime 70return mime
diff --git a/src/wsocket.c b/src/wsocket.c
index fcd2fff..2993c35 100644
--- a/src/wsocket.c
+++ b/src/wsocket.c
@@ -191,7 +191,7 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent,
191 int timeout) 191 int timeout)
192{ 192{
193 t_sock sock = *ps; 193 t_sock sock = *ps;
194 ssize_t put; 194 int put;
195 int ret; 195 int ret;
196 /* avoid making system calls on closed sockets */ 196 /* avoid making system calls on closed sockets */
197 if (sock == SOCK_INVALID) return IO_CLOSED; 197 if (sock == SOCK_INVALID) return IO_CLOSED;
@@ -227,7 +227,7 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,
227 SA *addr, socklen_t addr_len, int timeout) 227 SA *addr, socklen_t addr_len, int timeout)
228{ 228{
229 t_sock sock = *ps; 229 t_sock sock = *ps;
230 ssize_t put; 230 int put;
231 int ret; 231 int ret;
232 /* avoid making system calls on closed sockets */ 232 /* avoid making system calls on closed sockets */
233 if (sock == SOCK_INVALID) return IO_CLOSED; 233 if (sock == SOCK_INVALID) return IO_CLOSED;
@@ -262,7 +262,7 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,
262int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) 262int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout)
263{ 263{
264 t_sock sock = *ps; 264 t_sock sock = *ps;
265 ssize_t taken; 265 int taken;
266 if (sock == SOCK_INVALID) return IO_CLOSED; 266 if (sock == SOCK_INVALID) return IO_CLOSED;
267 taken = recv(sock, data, (int) count, 0); 267 taken = recv(sock, data, (int) count, 0);
268 if (taken <= 0) { 268 if (taken <= 0) {
@@ -288,7 +288,7 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got,
288 SA *addr, socklen_t *addr_len, int timeout) 288 SA *addr, socklen_t *addr_len, int timeout)
289{ 289{
290 t_sock sock = *ps; 290 t_sock sock = *ps;
291 ssize_t taken; 291 int taken;
292 if (sock == SOCK_INVALID) return IO_CLOSED; 292 if (sock == SOCK_INVALID) return IO_CLOSED;
293 taken = recvfrom(sock, data, (int) count, 0, addr, addr_len); 293 taken = recvfrom(sock, data, (int) count, 0, addr, addr_len);
294 if (taken <= 0) { 294 if (taken <= 0) {
diff --git a/src/wsocket.h b/src/wsocket.h
index d77841e..c048c58 100644
--- a/src/wsocket.h
+++ b/src/wsocket.h
@@ -13,7 +13,6 @@
13#include <winsock.h> 13#include <winsock.h>
14 14
15typedef int socklen_t; 15typedef int socklen_t;
16typedef int ssize_t;
17typedef SOCKET t_sock; 16typedef SOCKET t_sock;
18typedef t_sock *p_sock; 17typedef t_sock *p_sock;
19 18
diff --git a/test/ltn12test.lua b/test/ltn12test.lua
new file mode 100644
index 0000000..1c1f3f2
--- /dev/null
+++ b/test/ltn12test.lua
@@ -0,0 +1,3 @@
1sink = ltn12.sink.file(io.open("lixo", "w"))
2source = ltn12.source.file(io.open("luasocket", "r"))
3ltn12.pump(source, sink)
diff --git a/test/mimetest.lua b/test/mimetest.lua
index 5a461fa..1a7e427 100644
--- a/test/mimetest.lua
+++ b/test/mimetest.lua
@@ -1,4 +1,4 @@
1dofile("noglobals.lua") 1dofile("testsupport.lua")
2 2
3local qptest = "qptest.bin" 3local qptest = "qptest.bin"
4local eqptest = "qptest.bin2" 4local eqptest = "qptest.bin2"
@@ -31,26 +31,13 @@ local mao = [[
31 assim, nem tudo o que dava exprimia grande confiança. 31 assim, nem tudo o que dava exprimia grande confiança.
32]] 32]]
33 33
34local fail = function(s)
35 s = s or "failed"
36 assert(nil, s)
37end
38
39local readfile = function(name)
40 local f = io.open(name, "r")
41 if not f then return nil end
42 local s = f:read("*a")
43 f:close()
44 return s
45end
46
47local function transform(input, output, filter) 34local function transform(input, output, filter)
48 local fi, err = io.open(input, "rb") 35 local fi, err = io.open(input, "rb")
49 if not fi then fail(err) end 36 if not fi then fail(err) end
50 local fo, err = io.open(output, "wb") 37 local fo, err = io.open(output, "wb")
51 if not fo then fail(err) end 38 if not fo then fail(err) end
52 while 1 do 39 while 1 do
53 local chunk = fi:read(math.random(0, 256)) 40 local chunk = fi:read(math.random(0, 1024))
54 fo:write(filter(chunk)) 41 fo:write(filter(chunk))
55 if not chunk then break end 42 if not chunk then break end
56 end 43 end
@@ -58,17 +45,10 @@ local function transform(input, output, filter)
58 fo:close() 45 fo:close()
59end 46end
60 47
61local function compare(input, output)
62 local original = readfile(input)
63 local recovered = readfile(output)
64 if original ~= recovered then fail("recovering failed")
65 else print("ok") end
66end
67
68local function encode_qptest(mode) 48local function encode_qptest(mode)
69 local encode = socket.mime.encode("quoted-printable", mode) 49 local encode = mime.encode("quoted-printable", mode)
70 local split = socket.mime.wrap("quoted-printable") 50 local split = mime.wrap("quoted-printable")
71 local chain = socket.mime.chain(encode, split) 51 local chain = ltn12.filter.chain(encode, split)
72 transform(qptest, eqptest, chain) 52 transform(qptest, eqptest, chain)
73end 53end
74 54
@@ -77,7 +57,7 @@ local function compare_qptest()
77end 57end
78 58
79local function decode_qptest() 59local function decode_qptest()
80 local decode = socket.mime.decode("quoted-printable") 60 local decode = mime.decode("quoted-printable")
81 transform(eqptest, dqptest, decode) 61 transform(eqptest, dqptest, decode)
82end 62end
83 63
@@ -151,24 +131,24 @@ local function cleanup_qptest()
151end 131end
152 132
153local function encode_b64test() 133local function encode_b64test()
154 local e1 = socket.mime.encode("base64") 134 local e1 = mime.encode("base64")
155 local e2 = socket.mime.encode("base64") 135 local e2 = mime.encode("base64")
156 local e3 = socket.mime.encode("base64") 136 local e3 = mime.encode("base64")
157 local e4 = socket.mime.encode("base64") 137 local e4 = mime.encode("base64")
158 local sp4 = socket.mime.wrap() 138 local sp4 = mime.wrap()
159 local sp3 = socket.mime.wrap(59) 139 local sp3 = mime.wrap(59)
160 local sp2 = socket.mime.wrap("base64", 30) 140 local sp2 = mime.wrap("base64", 30)
161 local sp1 = socket.mime.wrap(27) 141 local sp1 = mime.wrap(27)
162 local chain = socket.mime.chain(e1, sp1, e2, sp2, e3, sp3, e4, sp4) 142 local chain = ltn12.filter.chain(e1, sp1, e2, sp2, e3, sp3, e4, sp4)
163 transform(b64test, eb64test, chain) 143 transform(b64test, eb64test, chain)
164end 144end
165 145
166local function decode_b64test() 146local function decode_b64test()
167 local d1 = socket.mime.decode("base64") 147 local d1 = mime.decode("base64")
168 local d2 = socket.mime.decode("base64") 148 local d2 = mime.decode("base64")
169 local d3 = socket.mime.decode("base64") 149 local d3 = mime.decode("base64")
170 local d4 = socket.mime.decode("base64") 150 local d4 = mime.decode("base64")
171 local chain = socket.mime.chain(d1, d2, d3, d4) 151 local chain = ltn12.filter.chain(d1, d2, d3, d4)
172 transform(eb64test, db64test, chain) 152 transform(eb64test, db64test, chain)
173end 153end
174 154
@@ -182,11 +162,11 @@ local function compare_b64test()
182end 162end
183 163
184local function identity_test() 164local function identity_test()
185 local chain = socket.mime.chain( 165 local chain = ltn12.filter.chain(
186 socket.mime.encode("quoted-printable"), 166 mime.encode("quoted-printable"),
187 socket.mime.encode("base64"), 167 mime.encode("base64"),
188 socket.mime.decode("base64"), 168 mime.decode("base64"),
189 socket.mime.decode("quoted-printable") 169 mime.decode("quoted-printable")
190 ) 170 )
191 transform(b64test, eb64test, chain) 171 transform(b64test, eb64test, chain)
192 compare(b64test, eb64test) 172 compare(b64test, eb64test)
@@ -195,8 +175,8 @@ end
195 175
196 176
197local function padcheck(original, encoded) 177local function padcheck(original, encoded)
198 local e = (socket.mime.b64(original)) 178 local e = (mime.b64(original))
199 local d = (socket.mime.unb64(encoded)) 179 local d = (mime.unb64(encoded))
200 if e ~= encoded then fail("encoding failed") end 180 if e ~= encoded then fail("encoding failed") end
201 if d ~= original then fail("decoding failed") end 181 if d ~= original then fail("decoding failed") end
202end 182end
@@ -206,8 +186,8 @@ local function chunkcheck(original, encoded)
206 for i = 0, len do 186 for i = 0, len do
207 local a = string.sub(original, 1, i) 187 local a = string.sub(original, 1, i)
208 local b = string.sub(original, i+1) 188 local b = string.sub(original, i+1)
209 local e, r = socket.mime.b64(a, b) 189 local e, r = mime.b64(a, b)
210 local f = (socket.mime.b64(r)) 190 local f = (mime.b64(r))
211 if (e .. f ~= encoded) then fail(e .. f) end 191 if (e .. f ~= encoded) then fail(e .. f) end
212 end 192 end
213end 193end
@@ -231,6 +211,13 @@ end
231 211
232local t = socket.time() 212local t = socket.time()
233 213
214identity_test()
215encode_b64test()
216decode_b64test()
217compare_b64test()
218cleanup_b64test()
219padding_b64test()
220
234create_qptest() 221create_qptest()
235encode_qptest() 222encode_qptest()
236decode_qptest() 223decode_qptest()
@@ -240,12 +227,4 @@ decode_qptest()
240compare_qptest() 227compare_qptest()
241cleanup_qptest() 228cleanup_qptest()
242 229
243encode_b64test()
244decode_b64test()
245compare_b64test()
246cleanup_b64test()
247padding_b64test()
248
249identity_test()
250
251print(string.format("done in %.2fs", socket.time() - t)) 230print(string.format("done in %.2fs", socket.time() - t))