任意のnsaファイルに含まれるファイルのリストを作る

タイトル通り。オリスク等で使うことを想定しているので、ファイル名は取れてもファイルの大きさや実データ等は取れないようになっている。
スクリプトは後述。

説明

list_from_nsa(file)
nsaファイルのファイル名(例:arc.nsa)を与えたら、その中に含まれるファイルのリストを返す。
table_from_nsa(file)
nsaファイルのファイル名(例:arc.nsa)を与えたら、その中に含まれるファイルのテーブルを返す。

あるファイルが存在しているかどうかを調べるには、table_from_nsaでテーブルを取得し、そのテーブルにキーがあるかどうかを調べるのがよい。

local file_table = table_from_nsa(file) -- テーブルの形で取得しておく。
if file_table[question] then
	NSOkBox(question.." は存在します。", "ファイル存在")
else
	NSOkBox(question.." は存在しません。", "ファイル存在")
end

スクリプト

function list_from_nsa(file)
	local fh = io.open(file, "rb") -- バイトモードで開く
	if io.type(fh) ~= "file" then return nil end
	fh:seek("set", 0) -- 念のため、最初に巻き戻す。
	local filelist = {} -- 返す物
	local file_num = 0 -- そのnsaに入っているファイルの数
	for i = 1, 2 do file_num = file_num * 256 + fh:read(1):byte() end
	for i = 1, file_num do -- ファイルの数だけ繰り返す。
		fh:read(4) -- ファイルサイズ領域を飛ばす。
		-- ファイル名の取得
		local name = ""
		local letter
		while true do
			letter = fh:read(1)
			if letter:byte() == 0 then break end
			name = name .. letter
		end
		fh:read(5) -- 必ず置いてある余白
		fh:read(4) -- 展開後のファイルサイズ領域を飛ばす。
		filelist[1+#filelist] = name -- 登録
	end
	return filelist
end

function table_fron_nsa(file)
	local list = list_from_nsa(file)
	if type(list) == "nil" then return nil end
	local res = {}
	for i, v in ipairs(list) do res[v] = true end
	return res
end