From 4964552718b81dba2c36fc08494aefae89a799f4 Mon Sep 17 00:00:00 2001 From: Diego Nehab Date: Tue, 12 Oct 2004 22:35:20 +0000 Subject: [PATCH] My own ltn12.filter.chain is done. Implemented part of DB's suggestion for ftp. Mimetest.lua generates the test file for base64 instead of loading from disk. --- TODO | 2 +- src/ftp.lua | 9 +++++--- src/ltn12.lua | 58 +++++++++++++++++++++++------------------------ test/mimetest.lua | 37 ++++++++++++++++++++---------- 4 files changed, 61 insertions(+), 45 deletions(-) diff --git a/TODO b/TODO index 557c0db..26ce419 100644 --- a/TODO +++ b/TODO @@ -4,7 +4,6 @@ new scheme to choose family/protocol of object to create change ltn13 to make sure drawbacks are obvious - check discussion make sure errors not thrown by try() are not caught by protect() -use wim's filter.chain or something better use mike's "don't set to blocking before closing unless needed" patch? take a look at DB's smtp patch (add "extra argument" table) move wsocket.c:sock_send kludge to buffer.c:sendraw (probably)? @@ -24,6 +23,7 @@ testar os options! - proteger ou atomizar o conjunto (timedout, receive), (timedout, send) - inet_ntoa também é uma merda. +*use wim's filter.chain or something better *fix PROXY in http.lua *use new distribution scheme *create the getstats method. diff --git a/src/ftp.lua b/src/ftp.lua index 43c62c2..9902c88 100644 --- a/src/ftp.lua +++ b/src/ftp.lua @@ -125,8 +125,10 @@ function metat.__index:send(sendt) if string.find(code, "1..") then self.try(self.tp:check("2..")) end -- done with data connection self.data:close() + -- find out how many bytes were sent + local sent = socket.skip(1, self.data:getstats()) self.data = nil - return 1 + return sent end function metat.__index:receive(recvt) @@ -186,9 +188,10 @@ local function tput(putt) f:login(putt.user, putt.password) if putt.type then f:type(putt.type) end f:pasv() - f:send(putt) + local sent = f:send(putt) f:quit() - return f:close() + f:close() + return sent end local default = { diff --git a/src/ltn12.lua b/src/ltn12.lua index 6c5ea28..9917ce8 100644 --- a/src/ltn12.lua +++ b/src/ltn12.lua @@ -31,40 +31,40 @@ function filter.cycle(low, ctx, extra) end end --- chains a bunch of filters together --- by Wim Couwenberg -function filter.chain(...) - local current = 1 - local bottom = 1 - local top = table.getn(arg) - local retry = "" +local function chain2(f1, f2) + local ff1, ff2 = "", "" return function(chunk) - if chunk ~= retry then - current = bottom - retry = chunk and retry + local rf1 = chunk and "" + local rf2 = ff1 and "" + -- if f2 still has pending data, get it and return it + if ff2 ~= rf2 then + ff2 = f2(rf2) + if ff2 ~= "" then return ff2 end + end + -- here we know f2 needs more data + -- we try to get it from f1 + ff1 = f1(chunk) + while 1 do + -- if f1 can't produce data, we need more data from the user + if ff1 == "" then return "" end + -- otherwise we pass new data to f2 until it produces something + -- or f1 runs out of data too + ff2 = f2(ff1) + if ff2 ~= "" then return ff2 end + ff1 = f1(rf1) end - repeat - if current == bottom then - chunk = arg[current](chunk) - if chunk == "" or bottom == top then return chunk - elseif chunk then current = current + 1 - else - bottom = bottom + 1 - current = bottom - end - else - chunk = arg[current](chunk or "") - if chunk == "" then - chunk = retry - current = current - 1 - elseif current == top then return chunk - else current = current + 1 - end - end - until false end end +-- chains a bunch of filters together +function filter.chain(...) + local f = arg[1] + for i = 2, table.getn(arg) do + f = chain2(f, arg[i]) + end + return f +end + ----------------------------------------------------------------------------- -- Source stuff ----------------------------------------------------------------------------- diff --git a/test/mimetest.lua b/test/mimetest.lua index d9bb772..89926d8 100644 --- a/test/mimetest.lua +++ b/test/mimetest.lua @@ -8,13 +8,10 @@ local qptest = "qptest.bin" local eqptest = "qptest.bin2" local dqptest = "qptest.bin3" -local b64test = "lsocket.2.0.dylib" -local eb64test = "b64test.bin" -local db64test = "b64test.bin2" +local b64test = "b64test.bin" +local eb64test = "b64test.bin2" +local db64test = "b64test.bin3" --- make sure test file exists -local f = assert(io.open(b64test, "r")) -f:close() -- from Machado de Assis, "A Mão e a Rosa" local mao = [[ @@ -86,6 +83,7 @@ local function named(f, name) end end ]] + local function named(f) return f end @@ -188,6 +186,19 @@ local function cleanup_qptest() os.remove(dqptest) end +-- create test file +function create_b64test() + local f = assert(io.open(b64test, "wb")) + local t = {} + for j = 1, 100 do + for i = 1, 100 do + t[i] = math.random(0, 255) + end + f:write(string.char(unpack(t))) + end + f:close() +end + local function encode_b64test() local e1 = mime.encode("base64") local e2 = mime.encode("base64") @@ -212,6 +223,7 @@ local function decode_b64test() end local function cleanup_b64test() + os.remove(b64test) os.remove(eb64test) os.remove(db64test) end @@ -221,12 +233,12 @@ local function compare_b64test() end local function identity_test() - local chain = ltn12.filter.chain( - mime.encode("quoted-printable"), - mime.encode("base64"), - mime.decode("base64"), - mime.decode("quoted-printable") - ) + local chain = named(ltn12.filter.chain( + named(mime.encode("quoted-printable"), "1 eq"), + named(mime.encode("base64"), "2 eb"), + named(mime.decode("base64"), "3 db"), + named(mime.decode("quoted-printable"), "4 dq") + ), "chain") transform(b64test, eb64test, chain) compare(b64test, eb64test) os.remove(eb64test) @@ -271,6 +283,7 @@ end local t = socket.gettime() identity_test() +create_b64test() encode_b64test() decode_b64test() compare_b64test()