-- vim: ft=terra
local m={}
local pstr = lib.mem.ptr(int8)

terra m.sanitize(txt: pstr, quo: bool)
	if txt.ptr == nil then return pstr.null() end
	if txt.ct == 0 then txt.ct = lib.str.sz(txt.ptr) end
	var a: lib.str.acc a:init(txt.ct*1.3)
	for i=0,txt.ct do
		if txt(i) == @'<' then a:lpush('&lt;')
		elseif txt(i) == @'>' then a:lpush('&gt;')
		elseif txt(i) == @'&' then a:lpush('&amp;')
		elseif quo and txt(i) == @'"' then a:lpush('&quot;')
		else a:push(&txt(i),1) end
	end
	return a:finalize()
end

terra m.hexdgt(i: uint8)
	if i >= 10 then
		return @'A' + (i - 10)
	else return 0x30 + i end
end

terra m.hexbyte(i: uint8): int8[2]
	return arrayof(int8,
		m.hexdgt(i / 0x10),
		m.hexdgt(i % 0x10))
end

terra m.urlenc(txt: pstr, qparam: bool)
	if txt.ptr == nil then return pstr.null() end
	if txt.ct == 0 then txt.ct = lib.str.sz(txt.ptr) end
	var a: lib.str.acc a:init(txt.ct*1.3)
	for i=0,txt.ct do
		if txt(i) == @' ' then a:lpush('+')
		elseif txt(i) == @'&' and not qparam then a:lpush('&amp;')
		elseif (txt(i) < 0x2c or
			(txt(i) > @';'  and txt(i) < @'@') or
			(txt(i) > @'Z'  and txt(i) < @'a') or
			(txt(i) >= 0x7b and txt(i) <= 0x7f)) and
			 txt(i) ~= @'_' and (qparam == true or txt(i) ~= @'=') then
			var str = m.hexbyte(txt(i))
			a:lpush('%'):push(&str[0], 2)
		else a:push(&txt(i),1) end
	end
	return a:finalize()
end

return m
