lsnes rr2-β24
[lsnes.git] / src / library / urirewrite.cpp
blob22beea9e4aa0af7595e240f8a1d90a942ad3c116
1 #include "directory.hpp"
2 #include "urirewrite.hpp"
3 #include "string.hpp"
4 #include "zip.hpp"
5 #include <sstream>
6 #include <fstream>
8 namespace urirewrite
10 std::set<std::string> rewriter::get_schemes()
12 threads::alock h(mlock);
13 std::set<std::string> ret;
14 for(auto& i : rewrites)
15 ret.insert(i.first);
16 return ret;
19 void rewriter::delete_rewrite(const std::string& scheme)
21 threads::alock h(mlock);
22 rewrites.erase(scheme);
25 void rewriter::set_rewrite(const std::string& scheme, const std::string& pattern)
27 threads::alock h(mlock);
28 if(!regex_match("[A-Za-z][A-Za-z0-9+.-]*", scheme))
29 throw std::runtime_error("Invalid scheme name");
30 rewrites[scheme] = pattern;
33 std::string rewriter::get_rewrite(const std::string& scheme)
35 threads::alock h(mlock);
36 if(!rewrites.count(scheme))
37 throw std::runtime_error("No such scheme known");
38 return rewrites[scheme];
41 std::string rewriter::operator()(const std::string& uri)
43 threads::alock h(mlock);
44 regex_results r = regex("([A-Za-z][A-Za-z0-9+.-]*):(.*)", uri);
45 if(!r || !rewrites.count(r[1])) return uri; //No rewrite.
46 std::string pattern = rewrites[r[1]];
47 std::string argument = r[2];
49 //Strip spaces.
50 size_t start = argument.find_first_not_of(" \t");
51 size_t end = argument.find_last_not_of(" \t");
52 if(start < argument.length())
53 argument = argument.substr(start, end - start + 1);
54 else
55 argument = "";
57 bool esc = false;
58 bool placed = false;
59 std::ostringstream out;
60 for(size_t i = 0; i < pattern.length(); i++) {
61 if(esc) {
62 if(pattern[i] == '0') {
63 out << argument;
64 placed = true;
65 } else
66 out << pattern[i];
67 esc = false;
68 } else if(pattern[i] == '$')
69 esc = true;
70 else
71 out << pattern[i];
73 if(!placed) out << argument;
74 return out.str();
77 void rewriter::save(const std::string& filename)
79 std::string tmpfile = filename + ".tmp";
81 std::ofstream x(tmpfile);
82 threads::alock h(mlock);
83 for(auto& i : rewrites)
84 x << i.first << "=" << i.second << std::endl;
85 if(!x)
86 throw std::runtime_error("Error writing rewriter settings");
88 directory::rename_overwrite(tmpfile.c_str(), filename.c_str());
91 void rewriter::load(const std::string& filename)
93 std::map<std::string, std::string> tmp;
95 std::ifstream x(filename);
96 threads::alock h(mlock);
97 std::string line;
98 while(std::getline(x, line)) {
99 istrip_CR(line);
100 regex_results r = regex("([A-Za-z][A-Za-z0-9+.-]*)=(.*)", line);
101 if(!r) continue;
102 tmp[r[1]] = r[2];
104 std::swap(rewrites, tmp);