| 1 |
#ifndef H_SETTING /* -*- mode: c++ -*- */ |
| 2 |
/* |
| 3 |
* Copyright (C) 2009-2016 TSUBAKIMOTO Hiroya <z0rac@users.sourceforge.jp> |
| 4 |
* |
| 5 |
* This software comes with ABSOLUTELY NO WARRANTY; for details of |
| 6 |
* the license terms, see the LICENSE.txt file included with the program. |
| 7 |
*/ |
| 8 |
#define H_SETTING |
| 9 |
|
| 10 |
#include <list> |
| 11 |
#include <memory> |
| 12 |
#include <string> |
| 13 |
|
| 14 |
using namespace std; |
| 15 |
|
| 16 |
class setting { |
| 17 |
class _repository { |
| 18 |
public: |
| 19 |
class _storage { |
| 20 |
public: |
| 21 |
virtual ~_storage() {} |
| 22 |
virtual string get(const char* key) const = 0; |
| 23 |
virtual void put(const char* key, const char* value) = 0; |
| 24 |
virtual void erase(const char* key) = 0; |
| 25 |
virtual list<string> keys() const = 0; |
| 26 |
}; |
| 27 |
public: |
| 28 |
_repository(); |
| 29 |
virtual ~_repository() {} |
| 30 |
virtual _storage* storage(const string& name) const = 0; |
| 31 |
virtual list<string> storages() const = 0; |
| 32 |
virtual void erase(const string& name) = 0; |
| 33 |
virtual const char* invalidchars() const = 0; |
| 34 |
}; |
| 35 |
shared_ptr<_repository::_storage> _st; |
| 36 |
setting(_repository::_storage* st) : _st(st) {} |
| 37 |
public: |
| 38 |
typedef _repository repository; |
| 39 |
typedef _repository::_storage storage; |
| 40 |
setting(setting const& s) : _st(s._st) {} |
| 41 |
public: |
| 42 |
struct _str { |
| 43 |
const char* c_str; |
| 44 |
_str(const char* s) : c_str(s) {} |
| 45 |
_str(const string& s) : c_str(s.c_str()) {} |
| 46 |
operator const char*() const { return c_str; } |
| 47 |
}; |
| 48 |
public: |
| 49 |
// tuple - use for separated output parameters. |
| 50 |
// Example: |
| 51 |
// setting::preferences()("windowpos", setting::tuple(x)(y)(w)(h)); |
| 52 |
class tuple { |
| 53 |
string _s; |
| 54 |
char _sep; |
| 55 |
tuple& add(const string& s); |
| 56 |
static string digit(long i); |
| 57 |
public: |
| 58 |
tuple(const string& v, char sep = ',') : _s(v), _sep(sep) {} |
| 59 |
template<typename _Ty> |
| 60 |
tuple(_Ty v, char sep = ',') : _s(digit(v)), _sep(sep) {} |
| 61 |
tuple& operator()(const string& v) { return add(v); } |
| 62 |
template<typename _Ty> |
| 63 |
tuple& operator()(_Ty v) { return add(digit(v)); } |
| 64 |
const string& row() const { return _s; } |
| 65 |
operator const string&() const { return _s; } |
| 66 |
}; |
| 67 |
setting& operator()(_str key, const string& value) |
| 68 |
{ _st->put(key, value.c_str()); return *this; } |
| 69 |
setting& operator()(_str key, const char* value) |
| 70 |
{ _st->put(key, value); return *this; } |
| 71 |
setting& operator()(_str key, long value) |
| 72 |
{ return operator()(key, tuple(value)); } |
| 73 |
|
| 74 |
// manip - use for separated input parameters. |
| 75 |
// Examples: |
| 76 |
// s = setting::preferences()["title"]; |
| 77 |
// setting::preferences()["windowpos"](x)(y)(w)(h); |
| 78 |
class manip { |
| 79 |
string _s; |
| 80 |
string::size_type _next; |
| 81 |
char _sep; |
| 82 |
bool avail() const { return _next < _s.size(); } |
| 83 |
string next(); |
| 84 |
bool next(int& v); |
| 85 |
public: |
| 86 |
manip(const string& s); |
| 87 |
manip& operator()() { next(); return *this; } |
| 88 |
manip& operator()(string& v); |
| 89 |
template<typename _Ty> manip& operator()(_Ty& v) |
| 90 |
{ int i = int(v); next(i), v = _Ty(i); return *this; } |
| 91 |
template<typename _Ty, typename _Tz> manip& operator()(_Ty& v, _Tz& e) |
| 92 |
{ int i = int(v); e = _Tz(next(i)), v = _Ty(i); return *this; } |
| 93 |
manip& operator()(int& v) { next(v); return *this; } |
| 94 |
template<typename _Tz> manip& operator()(int& v, _Tz& e) |
| 95 |
{ e = _Tz(next(v)); return *this; } |
| 96 |
const string& row() const { return _s; } |
| 97 |
operator const string&() const { return _s; } |
| 98 |
manip& sep(char sep) { _sep = sep; return *this; } |
| 99 |
list<string> split(); |
| 100 |
|
| 101 |
template<typename _Ty> |
| 102 |
list<_Ty> split() |
| 103 |
{ |
| 104 |
list<_Ty> l; |
| 105 |
for (int i; next(i);) l.push_back(static_cast<_Ty>(i)); |
| 106 |
return l; |
| 107 |
} |
| 108 |
}; |
| 109 |
manip operator[](_str key) const { return manip(_st->get(key)); } |
| 110 |
public: |
| 111 |
static setting preferences(); |
| 112 |
static setting preferences(_str name); |
| 113 |
static list<string> mailboxes(); |
| 114 |
static setting mailbox(const string& id); |
| 115 |
static void mailboxclear(const string& id); |
| 116 |
static list<string> cache(const string& key); |
| 117 |
static void cache(const string& key, const list<string>& data); |
| 118 |
static void cacheclear(); |
| 119 |
static const char* invalidchars(); |
| 120 |
public: |
| 121 |
string cipher(_str key); |
| 122 |
setting& cipher(_str key, const string& value); |
| 123 |
setting& erase(_str key) { _st->erase(key); return *this; } |
| 124 |
}; |
| 125 |
|
| 126 |
class registory : public setting::repository { |
| 127 |
void* _key; |
| 128 |
public: |
| 129 |
registory(const char* key); |
| 130 |
~registory(); |
| 131 |
setting::storage* storage(const string& name) const; |
| 132 |
list<string> storages() const; |
| 133 |
void erase(const string& name); |
| 134 |
const char* invalidchars() const { return "\\"; } |
| 135 |
}; |
| 136 |
|
| 137 |
class profile : public setting::repository { |
| 138 |
const char* _path; |
| 139 |
public: |
| 140 |
profile(const char* path) : _path(path) {} |
| 141 |
~profile(); |
| 142 |
setting::storage* storage(const string& name) const; |
| 143 |
list<string> storages() const; |
| 144 |
void erase(const string& name); |
| 145 |
const char* invalidchars() const { return "]"; } |
| 146 |
}; |
| 147 |
|
| 148 |
#endif |