Lua: Don't lua_error() out of context with pending dtors
[lsnes.git] / src / library / filelist.cpp
blobac721b5c188112ae2d0e9c460e7a16533535551d
1 #include "filelist.hpp"
2 #include <fstream>
3 #include <string>
4 #include "filelist.hpp"
5 #include "directory.hpp"
6 #include "zip.hpp"
7 #include "string.hpp"
9 filelist::filelist(const std::string& _backingfile, const std::string& _directory)
10 : backingfile(_backingfile), directory(_directory)
14 filelist::~filelist()
18 std::set<std::string> filelist::enumerate()
20 auto contents = readfile();
21 check_stale(contents);
22 writeback(contents);
23 std::set<std::string> ret;
24 for(auto i : contents)
25 if(i.second != 0)
26 ret.insert(i.first);
27 return ret;
30 void filelist::add(const std::string& filename)
32 auto contents = readfile();
33 int64_t ts = directory::mtime(directory + "/" + filename);
34 contents[filename] = ts;
35 writeback(contents);
38 void filelist::remove(const std::string& filename)
40 auto contents = readfile();
41 //FIXME: Do something with this?
42 //int64_t ts = directory::mtime(directory + "/" + filename);
43 contents.erase(filename);
44 writeback(contents);
47 void filelist::rename(const std::string& oldname, const std::string& newname)
49 auto contents = readfile();
50 contents[newname] = contents[oldname];
51 contents.erase(oldname);
52 writeback(contents);
55 std::map<std::string, int64_t> filelist::readfile()
57 std::map<std::string, int64_t> contents;
58 std::ifstream strm(backingfile);
59 std::string line;
60 while(std::getline(strm, line)) {
61 regex_results r = regex("([0-9]+) (.*)", line);
62 if(!r) continue;
63 int64_t ts;
64 try { ts = parse_value<int64_t>(r[1]); } catch(...) { continue; }
65 contents[r[2]] = ts;
67 return contents;
70 void filelist::check_stale(std::map<std::string, int64_t>& data)
72 for(auto& i : data) {
73 int64_t ts = directory::mtime(directory + "/" + i.first);
74 //If file timestamp does not match, mark the file as stale.
75 if(i.second != ts)
76 i.second = 0;
80 void filelist::writeback(const std::map<std::string, int64_t>& data)
82 std::string backingtmp = backingfile + ".new";
83 std::ofstream strm(backingtmp);
84 if(!strm)
85 return;
86 for(auto& i : data)
87 if(i.second != 0)
88 strm << i.second << " " << i.first << std::endl;
89 strm.close();
90 directory::rename_overwrite(backingtmp.c_str(), backingfile.c_str());