foobar2000 SDK  2015-01-14
cfg_var.h
Go to the documentation of this file.
1 #ifndef _FOOBAR2000_SDK_CFG_VAR_H_
2 #define _FOOBAR2000_SDK_CFG_VAR_H_
3 
4 #define CFG_VAR_ASSERT_SAFEINIT PFC_ASSERT(!core_api::are_services_available());/*imperfect check for nonstatic instantiation*/
5 
6 
8 class NOVTABLE cfg_var_reader {
9 public:
11  cfg_var_reader(const GUID & guid) : m_guid(guid) { CFG_VAR_ASSERT_SAFEINIT; m_next = g_list; g_list = this; }
12  ~cfg_var_reader() { CFG_VAR_ASSERT_SAFEINIT; }
13 
17  virtual void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) = 0;
18 
20  static void config_read_file(stream_reader * p_stream,abort_callback & p_abort);
21 
22  const GUID m_guid;
23 private:
26 
27  PFC_CLASS_NOT_COPYABLE_EX(cfg_var_reader)
28 };
29 
31 class NOVTABLE cfg_var_writer {
32 public:
34  cfg_var_writer(const GUID & guid) : m_guid(guid) { CFG_VAR_ASSERT_SAFEINIT; m_next = g_list; g_list = this;}
35  ~cfg_var_writer() { CFG_VAR_ASSERT_SAFEINIT; }
36 
39  virtual void get_data_raw(stream_writer * p_stream,abort_callback & p_abort) = 0;
40 
42  static void config_write_file(stream_writer * p_stream,abort_callback & p_abort);
43 
44  const GUID m_guid;
45 private:
48 
49  PFC_CLASS_NOT_COPYABLE_EX(cfg_var_writer)
50 };
51 
54 class NOVTABLE cfg_var : public cfg_var_reader, public cfg_var_writer {
55 protected:
57  cfg_var(const GUID & p_guid) : cfg_var_reader(p_guid), cfg_var_writer(p_guid) {}
58 public:
60 };
61 
64 template<typename t_inttype>
65 class cfg_int_t : public cfg_var {
66 private:
67  t_inttype m_val;
68 protected:
69  void get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {p_stream->write_lendian_t(m_val,p_abort);}
70  void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {
71  t_inttype temp;
72  p_stream->read_lendian_t(temp,p_abort);//alter member data only on success, this will throw an exception when something isn't right
73  m_val = temp;
74  }
75 
76 public:
79  explicit inline cfg_int_t(const GUID & p_guid,t_inttype p_default) : cfg_var(p_guid), m_val(p_default) {}
80 
81  inline const cfg_int_t<t_inttype> & operator=(const cfg_int_t<t_inttype> & p_val) {m_val=p_val.m_val;return *this;}
82  inline t_inttype operator=(t_inttype p_val) {m_val=p_val;return m_val;}
83 
84  inline operator t_inttype() const {return m_val;}
85 
86  inline t_inttype get_value() const {return m_val;}
87 };
88 
94 
97 class cfg_string : public cfg_var, public pfc::string8 {
98 protected:
99  void get_data_raw(stream_writer * p_stream,abort_callback & p_abort);
100  void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort);
101 
102 public:
105  explicit inline cfg_string(const GUID & p_guid,const char * p_defaultval) : cfg_var(p_guid), pfc::string8(p_defaultval) {}
106 
107  inline const cfg_string& operator=(const cfg_string & p_val) {set_string(p_val);return *this;}
108  inline const cfg_string& operator=(const char* p_val) {set_string(p_val);return *this;}
109 
110  inline operator const char * () const {return get_ptr();}
111 };
112 
113 
114 class cfg_string_mt : public cfg_var {
115 protected:
116  void get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {
117  insync(m_sync);
118  p_stream->write_object(m_val.get_ptr(),m_val.length(),p_abort);
119  }
120  void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {
122  p_stream->read_string_raw(temp,p_abort);
123  set(temp);
124  }
125 public:
126  cfg_string_mt(const GUID & id, const char * defVal) : cfg_var(id), m_val(defVal) {}
127  void get(pfc::string_base & out) const {
128  insync(m_sync);
129  out = m_val;
130  }
131  void set(const char * val, t_size valLen = ~0) {
132  insync(m_sync);
133  m_val.set_string(val, valLen);
134  }
135 private:
138 };
139 
142 template<typename t_struct>
143 class cfg_struct_t : public cfg_var {
144 private:
145  t_struct m_val;
146 protected:
147 
148  void get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {p_stream->write_object(&m_val,sizeof(m_val),p_abort);}
149  void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {
150  t_struct temp;
151  p_stream->read_object(&temp,sizeof(temp),p_abort);
152  m_val = temp;
153  }
154 public:
156  inline cfg_struct_t(const GUID & p_guid,const t_struct & p_val) : cfg_var(p_guid), m_val(p_val) {}
158  inline cfg_struct_t(const GUID & p_guid,int filler) : cfg_var(p_guid) {memset(&m_val,filler,sizeof(t_struct));}
159 
160  inline const cfg_struct_t<t_struct> & operator=(const cfg_struct_t<t_struct> & p_val) {m_val = p_val.get_value();return *this;}
161  inline const cfg_struct_t<t_struct> & operator=(const t_struct & p_val) {m_val = p_val;return *this;}
162 
163  inline const t_struct& get_value() const {return m_val;}
164  inline t_struct& get_value() {return m_val;}
165  inline operator t_struct() const {return m_val;}
166 };
167 
168 
169 template<typename TObj>
170 class cfg_objList : public cfg_var, public pfc::list_t<TObj> {
171 public:
173  cfg_objList(const GUID& guid) : cfg_var(guid) {}
174  template<typename TSource, unsigned Count> cfg_objList(const GUID& guid, const TSource (& source)[Count]) : cfg_var(guid) {
175  reset(source);
176  }
177  template<typename TSource, unsigned Count> void reset(const TSource (& source)[Count]) {
178  this->set_size(Count); for(t_size walk = 0; walk < Count; ++walk) (*this)[walk] = source[walk];
179  }
180  void get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {
181  stream_writer_formatter<> out(*p_stream,p_abort);
182  out << pfc::downcast_guarded<t_uint32>(this->get_size());
183  for(t_size walk = 0; walk < this->get_size(); ++walk) out << (*this)[walk];
184  }
185  void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {
186  try {
187  stream_reader_formatter<> in(*p_stream,p_abort);
188  t_uint32 count; in >> count;
189  this->set_count(count);
190  for(t_uint32 walk = 0; walk < count; ++walk) in >> (*this)[walk];
191  } catch(...) {
192  this->remove_all();
193  throw;
194  }
195  }
196  template<typename t_in> t_self & operator=(t_in const & source) {this->remove_all(); this->add_items(source); return *this;}
197  template<typename t_in> t_self & operator+=(t_in const & p_source) {this->add_item(p_source); return *this;}
198  template<typename t_in> t_self & operator|=(t_in const & p_source) {this->add_items(p_source); return *this;}
199 };
200 template<typename TList>
201 class cfg_objListEx : public cfg_var, public TList {
202 public:
204  cfg_objListEx(const GUID & guid) : cfg_var(guid) {}
205  void get_data_raw(stream_writer * p_stream, abort_callback & p_abort) {
206  stream_writer_formatter<> out(*p_stream,p_abort);
207  out << pfc::downcast_guarded<t_uint32>(this->get_count());
208  for(typename TList::const_iterator walk = this->first(); walk.is_valid(); ++walk) out << *walk;
209  }
210  void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {
211  this->remove_all();
212  stream_reader_formatter<> in(*p_stream,p_abort);
213  t_uint32 count; in >> count;
214  for(t_uint32 walk = 0; walk < count; ++walk) {
215  typename TList::t_item item; in >> item; this->add_item(item);
216  }
217  }
218  template<typename t_in> t_self & operator=(t_in const & source) {this->remove_all(); this->add_items(source); return *this;}
219  template<typename t_in> t_self & operator+=(t_in const & p_source) {this->add_item(p_source); return *this;}
220  template<typename t_in> t_self & operator|=(t_in const & p_source) {this->add_items(p_source); return *this;}
221 };
222 
223 template<typename TObj>
224 class cfg_obj : public cfg_var, public TObj {
225 public:
226  cfg_obj(const GUID& guid) : cfg_var(guid), TObj() {}
227  template<typename TInitData> cfg_obj(const GUID& guid,const TInitData& initData) : cfg_var(guid), TObj(initData) {}
228 
229  TObj & val() {return *this;}
230  TObj const & val() const {return *this;}
231 
232  void get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {
233  stream_writer_formatter<> out(*p_stream,p_abort);
234  const TObj * ptr = this;
235  out << *ptr;
236  }
237  void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {
238  stream_reader_formatter<> in(*p_stream,p_abort);
239  TObj * ptr = this;
240  in >> *ptr;
241  }
242 };
243 
244 template<typename TObj, typename TImport> class cfg_objListImporter : private cfg_var_reader {
245 public:
247  cfg_objListImporter(TMasterVar & var, const GUID & guid) : m_var(var), cfg_var_reader(guid) {}
248 
249  private:
250  void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {
251  TImport temp;
252  try {
253  stream_reader_formatter<> in(*p_stream,p_abort);
254  t_uint32 count; in >> count;
255  m_var.set_count(count);
256  for(t_uint32 walk = 0; walk < count; ++walk) {
257  in >> temp;
258  m_var[walk] = temp;
259  }
260  } catch(...) {
261  m_var.remove_all();
262  throw;
263  }
264  }
265  TMasterVar & m_var;
266 };
267 template<typename TMap> class cfg_objMap : private cfg_var, public TMap {
268 public:
269  cfg_objMap(const GUID & id) : cfg_var(id) {}
270 private:
271  void get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {
272  stream_writer_formatter<> out(*p_stream, p_abort);
273  out << pfc::downcast_guarded<t_uint32>(this->get_count());
274  for(typename TMap::const_iterator walk = this->first(); walk.is_valid(); ++walk) {
275  out << walk->m_key << walk->m_value;
276  }
277  }
278  void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {
279  this->remove_all();
280  stream_reader_formatter<> in(*p_stream, p_abort);
281  t_uint32 count; in >> count;
282  for(t_uint32 walk = 0; walk < count; ++walk) {
283  typename TMap::t_key key; in >> key; PFC_ASSERT( !this->have_item(key) );
284  try { in >> this->find_or_add( key ); } catch(...) { this->remove(key); throw; }
285  }
286  }
287 };
288 
289 #endif
void get_data_raw(stream_writer *p_stream, abort_callback &p_abort)
Retrieves state of the variable. Called only from main thread, when writing configuration file...
Definition: cfg_var.h:205
cfg_string_mt(const GUID &id, const char *defVal)
Definition: cfg_var.h:126
pfc::string8 m_val
Definition: cfg_var.h:137
void set_string(const char *p_string, t_size p_length=~0)
void get_data_raw(stream_writer *p_stream, abort_callback &p_abort)
Retrieves state of the variable. Called only from main thread, when writing configuration file...
Definition: cfg_var.h:148
t_struct & get_value()
Definition: cfg_var.h:164
void get_data_raw(stream_writer *p_stream, abort_callback &p_abort)
Retrieves state of the variable. Called only from main thread, when writing configuration file...
Definition: cfg_var.h:271
const cfg_struct_t< t_struct > & operator=(const cfg_struct_t< t_struct > &p_val)
Definition: cfg_var.h:160
void set_data_raw(stream_reader *p_stream, t_size p_sizehint, abort_callback &p_abort)
Sets state of the variable. Called only from main thread, when reading configuration file...
Definition: cfg_var.h:149
cfg_objList(const GUID &guid, const TSource(&source)[Count])
Definition: cfg_var.h:174
Definition: pfc.h:53
const GUID m_guid
Definition: cfg_var.h:22
void set(const char *val, t_size valLen=~0)
Definition: cfg_var.h:131
cfg_struct_t(const GUID &p_guid, int filler)
Definition: cfg_var.h:158
t_inttype get_value() const
Definition: cfg_var.h:86
t_inttype operator=(t_inttype p_val)
Definition: cfg_var.h:82
void set_data_raw(stream_reader *p_stream, t_size p_sizehint, abort_callback &p_abort)
Sets state of the variable. Called only from main thread, when reading configuration file...
Definition: cfg_var.h:237
cfg_var_reader * m_next
Definition: cfg_var.h:25
TObj const & val() const
Definition: cfg_var.h:230
cfg_objListImporter(TMasterVar &var, const GUID &guid)
Definition: cfg_var.h:247
void set_data_raw(stream_reader *p_stream, t_size p_sizehint, abort_callback &p_abort)
Sets state of the variable. Called only from main thread, when reading configuration file...
Definition: cfg_var.cpp:56
void set_data_raw(stream_reader *p_stream, t_size p_sizehint, abort_callback &p_abort)
Sets state of the variable. Called only from main thread, when reading configuration file...
Definition: cfg_var.h:278
void set_data_raw(stream_reader *p_stream, t_size p_sizehint, abort_callback &p_abort)
Sets state of the variable. Called only from main thread, when reading configuration file...
Definition: cfg_var.h:250
cfg_int_t(const GUID &p_guid, t_inttype p_default)
Definition: cfg_var.h:79
t_inttype m_val
Definition: cfg_var.h:67
cfg_var(const GUID &p_guid)
Definition: cfg_var.h:57
const t_struct & get_value() const
Definition: cfg_var.h:163
cfg_obj(const GUID &guid, const TInitData &initData)
Definition: cfg_var.h:227
void get_data_raw(stream_writer *p_stream, abort_callback &p_abort)
Retrieves state of the variable. Called only from main thread, when writing configuration file...
Definition: cfg_var.h:180
t_struct m_val
Definition: cfg_var.h:145
string8_t< pfc::alloc_standard > string8
Definition: string_base.h:431
cfg_objListEx< TList > t_self
Definition: cfg_var.h:203
TObj & val()
Definition: cfg_var.h:229
cfg_objMap(const GUID &id)
Definition: cfg_var.h:269
t_self & operator|=(t_in const &p_source)
Definition: cfg_var.h:220
void set_data_raw(stream_reader *p_stream, t_size p_sizehint, abort_callback &p_abort)
Sets state of the variable. Called only from main thread, when reading configuration file...
Definition: cfg_var.h:185
Reader part of cfg_var object. In most cases, you should use cfg_var instead of using cfg_var_reader ...
Definition: cfg_var.h:8
t_self & operator=(t_in const &source)
Definition: cfg_var.h:196
GUID get_guid() const
Definition: cfg_var.h:59
static cfg_var_reader * g_list
Definition: cfg_var.h:24
cfg_int_t< t_uint32 > cfg_uint
Definition: cfg_var.h:90
cfg_int_t< GUID > cfg_guid
Since relevant byteswapping functions also understand GUIDs, this can be abused to declare a cfg_guid...
Definition: cfg_var.h:92
critical_section m_sync
Definition: cfg_var.h:136
size_t t_size
Definition: int_types.h:48
TMasterVar & m_var
Definition: cfg_var.h:265
cfg_obj(const GUID &guid)
Definition: cfg_var.h:226
const cfg_string & operator=(const char *p_val)
Definition: cfg_var.h:108
static cfg_var_writer * g_list
Definition: cfg_var.h:46
Generic integer config variable class. Template parameter can be used to specify integer type to use...
Definition: cfg_var.h:65
cfg_struct_t(const GUID &p_guid, const t_struct &p_val)
Definition: cfg_var.h:156
void get_data_raw(stream_writer *p_stream, abort_callback &p_abort)
Retrieves state of the variable. Called only from main thread, when writing configuration file...
Definition: cfg_var.cpp:52
t_self & operator=(t_in const &source)
Definition: cfg_var.h:218
cfg_objList(const GUID &guid)
Definition: cfg_var.h:173
void set_data_raw(stream_reader *p_stream, t_size p_sizehint, abort_callback &p_abort)
Sets state of the variable. Called only from main thread, when reading configuration file...
Definition: cfg_var.h:120
void get_data_raw(stream_writer *p_stream, abort_callback &p_abort)
Retrieves state of the variable. Called only from main thread, when writing configuration file...
Definition: cfg_var.h:116
String config variable. Stored in the stream with int32 header containing size in bytes...
Definition: cfg_var.h:97
cfg_objList< TObj > t_self
Definition: cfg_var.h:172
t_self & operator+=(t_in const &p_source)
Definition: cfg_var.h:197
const cfg_int_t< t_inttype > & operator=(const cfg_int_t< t_inttype > &p_val)
Definition: cfg_var.h:81
~cfg_var_reader()
Definition: cfg_var.h:12
void reset(const TSource(&source)[Count])
Definition: cfg_var.h:177
void get_data_raw(stream_writer *p_stream, abort_callback &p_abort)
Retrieves state of the variable. Called only from main thread, when writing configuration file...
Definition: cfg_var.h:69
const cfg_string & operator=(const cfg_string &p_val)
Definition: cfg_var.h:107
t_self & operator+=(t_in const &p_source)
Definition: cfg_var.h:219
Struct config variable template. Warning: not endian safe, should be used only for nonportable code...
Definition: cfg_var.h:143
cfg_objListEx(const GUID &guid)
Definition: cfg_var.h:204
void set_data_raw(stream_reader *p_stream, t_size p_sizehint, abort_callback &p_abort)
Sets state of the variable. Called only from main thread, when reading configuration file...
Definition: cfg_var.h:210
cfg_int_t< t_int32 > cfg_int
Definition: cfg_var.h:89
void get_data_raw(stream_writer *p_stream, abort_callback &p_abort)
Retrieves state of the variable. Called only from main thread, when writing configuration file...
Definition: cfg_var.h:232
Writer part of cfg_var object. In most cases, you should use cfg_var instead of using cfg_var_writer ...
Definition: cfg_var.h:31
cfg_int_t< bool > cfg_bool
Definition: cfg_var.h:93
t_self & operator|=(t_in const &p_source)
Definition: cfg_var.h:198
cfg_var_writer(const GUID &guid)
Definition: cfg_var.h:34
void set_data_raw(stream_reader *p_stream, t_size p_sizehint, abort_callback &p_abort)
Sets state of the variable. Called only from main thread, when reading configuration file...
Definition: cfg_var.h:70
Base class for configuration variable classes; provides self-registration mechaisms and methods to se...
Definition: cfg_var.h:54
cfg_var_reader(const GUID &guid)
Definition: cfg_var.h:11
const GUID m_guid
Definition: cfg_var.h:44
string8_t< pfc::alloc_fast_aggressive > string8_fastalloc
Definition: string_base.h:435
cfg_objList< TObj > TMasterVar
Definition: cfg_var.h:246
~cfg_var_writer()
Definition: cfg_var.h:35
const cfg_struct_t< t_struct > & operator=(const t_struct &p_val)
Definition: cfg_var.h:161
uint32_t t_uint32
Definition: int_types.h:5
cfg_var_writer * m_next
Definition: cfg_var.h:47
t_size length() const
For compatibility with old conventions.
Definition: string_base.h:208
cfg_string(const GUID &p_guid, const char *p_defaultval)
Definition: cfg_var.h:105