Parent: [cecd1b] (diff)

Download this file

dynconf.h    176 lines (158 with data), 5.7 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* Copyright (C) 2004-2017 J.F.Dockes
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _DYNCONF_H_INCLUDED_
#define _DYNCONF_H_INCLUDED_
/**
* Dynamic configuration storage
*
* This used to be called "history" because of the initial usage.
* Used to store some parameters which would fit neither in recoll.conf,
* basically because they change a lot, nor in the QT preferences file, mostly
* because they are specific to a configuration directory.
* Examples:
* - History of documents selected for preview
* - Active and inactive external databases (depend on the
* configuration directory)
* - ...
*
* The storage is performed in a ConfSimple file, with subkeys and
* encodings which depend on the data stored. Under each section, the keys
* are sequential numeric, so this basically manages a set of lists.
*
* The code ensures that a a given value (as defined by the
* DynConfEntry::equal() method) is only stored once. If this is
* undesirable, equal() should always return false.
*/
#include <string>
#include <list>
#include <vector>
#include "conftree.h"
#include "base64.h"
/** Interface for a stored object. */
class DynConfEntry {
public:
virtual ~DynConfEntry() {}
/** Decode object-as-string coming out from storage */
virtual bool decode(const std::string &value) = 0;
/** Encode object state into state for storing */
virtual bool encode(std::string& value) = 0;
/** Compare objects */
virtual bool equal(const DynConfEntry &other) = 0;
};
/** Stored object specialization for generic string storage */
class RclSListEntry : public DynConfEntry {
public:
RclSListEntry() {}
virtual ~RclSListEntry() {}
RclSListEntry(const std::string& v)
: value(v) {
}
virtual bool decode(const std::string &enc) {
base64_decode(enc, value);
return true;
}
virtual bool encode(std::string& enc) {
base64_encode(value, enc);
return true;
}
virtual bool equal(const DynConfEntry& other) {
const RclSListEntry& e = dynamic_cast<const RclSListEntry&>(other);
return e.value == value;
}
std::string value;
};
/** The dynamic configuration class */
class RclDynConf {
public:
RclDynConf(const std::string &fn);
bool ro() {
return m_data.getStatus() == ConfSimple::STATUS_RO;
}
bool rw() {
return m_data.getStatus() == ConfSimple::STATUS_RW;
}
bool ok() {
return m_data.getStatus() != ConfSimple::STATUS_ERROR;
}
std::string getFilename() {
return m_data.getFilename();
}
// Generic methods
bool eraseAll(const std::string& sk);
/** Insert new entry for section sk
* @param sk section this is for
* @param n new entry
* @param s a scratch entry used for decoding and comparisons,
* avoiding templating the routine for the actual entry type.
*/
bool insertNew(const std::string& sk, DynConfEntry &n, DynConfEntry &s,
int maxlen = -1);
// General method to extract entries. Maybe there would be a way to
// express the fact that Type should derive from DynConfEntry, not
// too sure how. We are just certain (further down) that it does
// have a decode() method. It's up to the user that they call
// insertNew() and getEntries() for the same type...
template <template <class, class> class Container, class Type>
Container<Type, std::allocator<Type>> getEntries(const std::string& sk);
// Specialized methods for simple strings
bool enterString(const std::string sk, const std::string value,
int maxlen = -1);
template <template <class, class> class Container>
Container<std::string, std::allocator<std::string>>
getStringEntries(const std::string& sk);
private:
unsigned int m_mlen;
ConfSimple m_data;
};
template <template <class, class> class Container, class Type>
Container<Type, std::allocator<Type>>
RclDynConf::getEntries(const std::string& sk)
{
Container<Type, std::allocator<Type>> out;
Type entry;
std::vector<std::string> names = m_data.getNames(sk);
for (const auto& name : names) {
std::string value;
if (m_data.get(name, value, sk)) {
if (!entry.decode(value))
continue;
out.push_back(entry);
}
}
return out;
}
template <template <class, class> class Container>
Container<std::string, std::allocator<std::string>>
RclDynConf::getStringEntries(const std::string& sk)
{
std::vector<RclSListEntry> el = getEntries<std::vector, RclSListEntry>(sk);
Container<std::string, std::allocator<std::string>> sl;
for (const auto& entry : el) {
sl.push_back(entry.value);
}
return sl;
}
// Defined subkeys. Values in dynconf.cpp
// History
extern const std::string docHistSubKey;
// All external indexes
extern const std::string allEdbsSk;
// Active external indexes
extern const std::string actEdbsSk;
// Advanced search history
extern const std::string advSearchHistSk;
#endif /* _DYNCONF_H_INCLUDED_ */