summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Lua/luasocket/src/ltn12.lua')
-rw-r--r--3rdParty/Lua/luasocket/src/ltn12.lua292
1 files changed, 292 insertions, 0 deletions
diff --git a/3rdParty/Lua/luasocket/src/ltn12.lua b/3rdParty/Lua/luasocket/src/ltn12.lua
new file mode 100644
index 0000000..b42689a
--- /dev/null
+++ b/3rdParty/Lua/luasocket/src/ltn12.lua
@@ -0,0 +1,292 @@
+-----------------------------------------------------------------------------
+-- LTN12 - Filters, sources, sinks and pumps.
+-- LuaSocket toolkit.
+-- Author: Diego Nehab
+-- RCS ID: $Id: ltn12.lua,v 1.31 2006/04/03 04:45:42 diego Exp $
+-----------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+-- Declare module
+-----------------------------------------------------------------------------
+local string = require("string")
+local table = require("table")
+local base = _G
+module("ltn12")
+
+filter = {}
+source = {}
+sink = {}
+pump = {}
+
+-- 2048 seems to be better in windows...
+BLOCKSIZE = 2048
+_VERSION = "LTN12 1.0.1"
+
+-----------------------------------------------------------------------------
+-- Filter stuff
+-----------------------------------------------------------------------------
+-- returns a high level filter that cycles a low-level filter
+function filter.cycle(low, ctx, extra)
+ base.assert(low)
+ return function(chunk)
+ local ret
+ ret, ctx = low(ctx, chunk, extra)
+ return ret
+ end
+end
+
+-- chains a bunch of filters together
+-- (thanks to Wim Couwenberg)
+function filter.chain(...)
+ local n = table.getn(arg)
+ local top, index = 1, 1
+ local retry = ""
+ return function(chunk)
+ retry = chunk and retry
+ while true do
+ if index == top then
+ chunk = arg[index](chunk)
+ if chunk == "" or top == n then return chunk
+ elseif chunk then index = index + 1
+ else
+ top = top+1
+ index = top
+ end
+ else
+ chunk = arg[index](chunk or "")
+ if chunk == "" then
+ index = index - 1
+ chunk = retry
+ elseif chunk then
+ if index == n then return chunk
+ else index = index + 1 end
+ else base.error("filter returned inappropriate nil") end
+ end
+ end
+ end
+end
+
+-----------------------------------------------------------------------------
+-- Source stuff
+-----------------------------------------------------------------------------
+-- create an empty source
+local function empty()
+ return nil
+end
+
+function source.empty()
+ return empty
+end
+
+-- returns a source that just outputs an error
+function source.error(err)
+ return function()
+ return nil, err
+ end
+end
+
+-- creates a file source
+function source.file(handle, io_err)
+ if handle then
+ return function()
+ local chunk = handle:read(BLOCKSIZE)
+ if not chunk then handle:close() end
+ return chunk
+ end
+ else return source.error(io_err or "unable to open file") end
+end
+
+-- turns a fancy source into a simple source
+function source.simplify(src)
+ base.assert(src)
+ return function()
+ local chunk, err_or_new = src()
+ src = err_or_new or src
+ if not chunk then return nil, err_or_new
+ else return chunk end
+ end
+end
+
+-- creates string source
+function source.string(s)
+ if s then
+ local i = 1
+ return function()
+ local chunk = string.sub(s, i, i+BLOCKSIZE-1)
+ i = i + BLOCKSIZE
+ if chunk ~= "" then return chunk
+ else return nil end
+ end
+ else return source.empty() end
+end
+
+-- creates rewindable source
+function source.rewind(src)
+ base.assert(src)
+ local t = {}
+ return function(chunk)
+ if not chunk then
+ chunk = table.remove(t)
+ if not chunk then return src()
+ else return chunk end
+ else
+ table.insert(t, chunk)
+ end
+ end
+end
+
+function source.chain(src, f)
+ base.assert(src and f)
+ local last_in, last_out = "", ""
+ local state = "feeding"
+ local err
+ return function()
+ if not last_out then
+ base.error('source is empty!', 2)
+ end
+ while true do
+ if state == "feeding" then
+ last_in, err = src()
+ if err then return nil, err end
+ last_out = f(last_in)
+ if not last_out then
+ if last_in then
+ base.error('filter returned inappropriate nil')
+ else
+ return nil
+ end
+ elseif last_out ~= "" then
+ state = "eating"
+ if last_in then last_in = "" end
+ return last_out
+ end
+ else
+ last_out = f(last_in)
+ if last_out == "" then
+ if last_in == "" then
+ state = "feeding"
+ else
+ base.error('filter returned ""')
+ end
+ elseif not last_out then
+ if last_in then
+ base.error('filter returned inappropriate nil')
+ else
+ return nil
+ end
+ else
+ return last_out
+ end
+ end
+ end
+ end
+end
+
+-- creates a source that produces contents of several sources, one after the
+-- other, as if they were concatenated
+-- (thanks to Wim Couwenberg)
+function source.cat(...)
+ local src = table.remove(arg, 1)
+ return function()
+ while src do
+ local chunk, err = src()
+ if chunk then return chunk end
+ if err then return nil, err end
+ src = table.remove(arg, 1)
+ end
+ end
+end
+
+-----------------------------------------------------------------------------
+-- Sink stuff
+-----------------------------------------------------------------------------
+-- creates a sink that stores into a table
+function sink.table(t)
+ t = t or {}
+ local f = function(chunk, err)
+ if chunk then table.insert(t, chunk) end
+ return 1
+ end
+ return f, t
+end
+
+-- turns a fancy sink into a simple sink
+function sink.simplify(snk)
+ base.assert(snk)
+ return function(chunk, err)
+ local ret, err_or_new = snk(chunk, err)
+ if not ret then return nil, err_or_new end
+ snk = err_or_new or snk
+ return 1
+ end
+end
+
+-- creates a file sink
+function sink.file(handle, io_err)
+ if handle then
+ return function(chunk, err)
+ if not chunk then
+ handle:close()
+ return 1
+ else return handle:write(chunk) end
+ end
+ else return sink.error(io_err or "unable to open file") end
+end
+
+-- creates a sink that discards data
+local function null()
+ return 1
+end
+
+function sink.null()
+ return null
+end
+
+-- creates a sink that just returns an error
+function sink.error(err)
+ return function()
+ return nil, err
+ end
+end
+
+-- chains a sink with a filter
+function sink.chain(f, snk)
+ base.assert(f and snk)
+ return function(chunk, err)
+ if chunk ~= "" then
+ local filtered = f(chunk)
+ local done = chunk and ""
+ while true do
+ local ret, snkerr = snk(filtered, err)
+ if not ret then return nil, snkerr end
+ if filtered == done then return 1 end
+ filtered = f(done)
+ end
+ else return 1 end
+ end
+end
+
+-----------------------------------------------------------------------------
+-- Pump stuff
+-----------------------------------------------------------------------------
+-- pumps one chunk from the source to the sink
+function pump.step(src, snk)
+ local chunk, src_err = src()
+ local ret, snk_err = snk(chunk, src_err)
+ if chunk and ret then return 1
+ else return nil, src_err or snk_err end
+end
+
+-- pumps all data from a source to a sink, using a step function
+function pump.all(src, snk, step)
+ base.assert(src and snk)
+ step = step or pump.step
+ while true do
+ local ret, err = step(src, snk)
+ if not ret then
+ if err then return nil, err
+ else return 1 end
+ end
+ end
+end
+