aboutsummaryrefslogtreecommitdiff
path: root/src/mime.lua
blob: 0251f6ee4f8f501f9c9cf6822db7c052f43bea98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
-- make sure LuaSocket is loaded
if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end
-- get LuaSocket namespace
local socket = _G[LUASOCKET_LIBNAME] 
if not socket then error('module requires LuaSocket') end
-- create code namespace inside LuaSocket namespace
local mime = socket.mime or {}
socket.mime = mime
-- make all module globals fall into mime namespace
setmetatable(mime, { __index = _G })
setfenv(1, mime)

-- encode, decode and wrap algorithm tables
local et = {}
local dt = {}
local wt = {}

-- creates a function that chooses an algorithm from a given table 
local function choose(table)
    return function(method, ...)
        local f = table[method or "nil"]
        if not f then return nil, "unknown method (" .. tostring(method) .. ")"
        else return f(unpack(arg)) end
    end
end

-- creates a function that cicles a filter with a given initial
-- context and extra arguments
local function cicle(f, ctx, ...)
    return function(chunk)
        local ret
        ret, ctx = f(ctx, chunk, unpack(arg))
        return ret
    end
end

-- function that choose the encoding, decoding or wrap algorithm
encode = choose(et) 
decode = choose(dt)
wrap = choose(wt)

-- define the encoding algorithms
et['base64'] = function()
    return cicle(b64, "")
end

et['quoted-printable'] = function(mode)
    return cicle(qp, "", (mode == "binary") and "=0D=0A" or "\13\10")
end

-- define the decoding algorithms
dt['base64'] = function()
    return cicle(unb64, "")
end

dt['quoted-printable'] = function()
    return cicle(unqp, "")
end

-- define the wrap algorithms
wt['character'] = function(length)
    length = length or 76
    return cicle(fmt, length, length) 
end
wt['base64'] = wt['character']

wt['quoted-printable'] = function(length)
    length = length or 76
    return cicle(qpfmt, length, length) 
end

-- define the end-of-line translation function
function canonic(marker)
    return cicle(eol, "", marker)
end

-- chains several filters together
function chain(...)
    local layers = table.getn(arg)
    return function (chunk)
        if not chunk then
            local parts = {}
            for i = 1, layers do
                for j = i, layers do
                    chunk = arg[j](chunk)
                end
                table.insert(parts, chunk)
                chunk = nil
            end
            return table.concat(parts)
        else
            for j = 1, layers do
                chunk = arg[j](chunk)
            end
            return chunk
        end
    end
end

return code