-- vim: ft=terra
local knowntypes = {
html = {
ext = 'html', kind = 'markup', unsafe = true, id = {
'text/html';
'application/xhtml+xml';
'application/vnd.wap.xhtml+xml';
};
};
flash = { ext = 'swf', kind = 'vm_prog', id = 'application/x-shockwave-flash', unsafe = true, binary = true };
java = { ext = 'java', kind = 'vm_prog', id = 'application/java', unsafe = true, binary = true };
css = { ext = 'css', kind = 'lang', id = 'text/css'};
text = { ext = 'txt', kind = 'text', id = 'text/plain' };
c = { ext = 'c', kind = 'prog_lang', id = 'text/csrc' };
xml = { ext = 'xml', kind = 'markup', unsafe = true, id = 'text/xml' };
lua = { ext = 'lua', kind = 'prog_lang', id = 'text/x-lua' };
ansi = { ext = 'ans', kind = 'text', id = 'text/x-ansi', doc = true, binary = true};
mkdown = { ext = 'md', kind = 'text', doc = true; id = 'text/markdown';
formatter = 'smackdown';
};
json = {
ext = 'json', kind = 'lang', id = {
'application/json';
'application/activity+json';
'application/ld+json';
'application/jrd+json';
};
};
svg = { ext = 'svg', kind = 'image', id = 'image/svg+xml' };
webp = { ext = 'webp', kind = 'image', id = 'image/webp', binary = true };
png = { ext = 'png', kind = 'image', id = 'image/png', binary = true };
jpeg = { ext = 'jpg', kind = 'image', id = 'image/jpeg', binary = true };
-- wildcard
none = { id = '*/*' };
}
local idcache = {}
local pstr = lib.str.t
local filekind = lib.enum [[none image text lang prog_lang markup vm_prog]]
local struct mime {
key: pstr
canonical: pstr
safe: bool
binary: bool
ext: pstr
kind: filekind.t
output: lib.http.mime.t
}
local typestore = {}
for typecode, ty in pairs(knowntypes) do
ty.key = typecode
if type(ty.id) == 'string' then ty.id = {ty.id} end
for i, mime in ipairs(ty.id) do
idcache[mime] = ty
end
local op = lib.http.mime[typecode]
if op == nil then op = lib.http.mime.none end
print(typecode,op)
ty.offset = #typestore
typestore[#typestore + 1] = `mime {
key = typecode;
canonical = [ty.id[1]];
safe = [not ty.unsafe];
ext = [ty.ext or `pstr{nil,0}];
kind = [ty.kind and filekind[ty.kind] or filekind.none];
binary = [ty.binary or false];
output = [op];
}
end
local typedex = global(`array([typestore]))
local struct mimemapping {
string: pstr
type: &mime
}
local typemap_l = {}
for mime, ty in pairs(idcache) do
typemap_l[#typemap_l + 1] = `mimemapping {
string = mime;
type = &typedex[ [ty.offset] ];
}
end
local typemap = global(`array([typemap_l]));
return {
type = mime;
types = knowntypes;
tbl = idcache;
typedex = typedex;
lookup = terra(m: pstr): &mime
for i=0, [#typemap_l] do
if m:cmp(typemap[i].string) then
lib.io.fmt('returning type %s %u\n', typemap[i].type.key, typemap[i].type.output)
return typemap[i].type
end
end
return nil
end;
}