NCBI C++ ToolKit
reg_view.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: reg_view.cpp 39783 2017-11-03 15:04:54Z katargir $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Mike DiCuccio
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
35 
37 
38 
41 
42 static const string kDecimalDot = ".";
43 
44 /////////////////////////////////////////////////////////////////////////////
45 ///
46 /// CRegistryReadView
47 
49 {
50  if (userField)
51  m_Fields.push_back(CConstRef<objects::CUser_field>(userField));
52 }
53 
54 
56 {
57  m_Fields.insert(m_Fields.end(), rhs.m_Fields.begin(), rhs.m_Fields.end());
58  return *this;
59 }
60 
61 void CRegistryReadView::x_AppendToReadView(CRegistryReadView& view, const string& section) const
62 {
63  ITERATE(TFields, iter, m_Fields) {
64  const CUser_field& obj = **iter;
65  CConstRef<CUser_field> section_obj =
66  obj.GetFieldRef(section);
67  if (section_obj) {
68  view.m_Fields.push_back(section_obj);
69  }
70  }
71 }
72 
73 
75 {
76  CRegistryReadView view;
77  x_AppendToReadView(view, section);
78  return view;
79 }
80 
81 
83  const vector<string>& subsections) const
84 {
85  CRegistryReadView view;
86  string sec(section);
87  if (!sec.empty()) {
88  sec += kDecimalDot;
89  }
90 
91  vector<string>::const_reverse_iterator riter(subsections.end());
92  vector<string>::const_reverse_iterator rend(subsections.begin());
93  for (; riter != rend; ++riter) {
94  string key(*riter);
95  if (!key.empty()) {
96  x_AppendToReadView(view, sec + key);
97  }
98  }
99 
100  return view;
101 }
102 
103 
105 {
106  list< CConstRef<CUser_field> > fields;
108 
109  ITERATE(TFields, iter, m_Fields) {
110  const CUser_field& obj = **iter;
112  if (field)
113  fields.push_back(field);
114 
115  /// access the meta-information for this key, last one takes precedence.
116  field = obj.GetFieldRef(key + "-meta");
117  if (field)
118  meta = field;
119  }
120 
121  return ResolveField(fields, meta);
122 }
123 
124 int CRegistryReadView::GetInt(const objects::CUser_field* field, int default_val)
125 {
126  return (field && field->GetData().IsInt()) ?
127  field->GetData().GetInt() : default_val;
128 }
129 
130 double CRegistryReadView::GetReal(const objects::CUser_field* field, double default_val)
131 {
132  return (field && field->GetData().IsReal()) ?
133  field->GetData().GetReal() : default_val;
134 }
135 
136 bool CRegistryReadView::GetBool(const objects::CUser_field* field, bool default_val)
137 {
138  return (field && field->GetData().IsBool()) ?
139  field->GetData().GetBool() : default_val;
140 }
141 
142 string CRegistryReadView::GetString(const objects::CUser_field* field, const string& default_val)
143 {
144  return (field && field->GetData().IsStr()) ?
145  field->GetData().GetStr() : default_val;
146 }
147 
148 void CRegistryReadView::GetIntVec(const objects::CUser_field* field, vector<int>& val)
149 {
150  val.clear();
151  if (!field) return;
152 
153  if (field->GetData().IsInt()) {
154  val.push_back(field->GetData().GetInt());
155  }
156  else if (field->GetData().IsInts()) {
157  val = field->GetData().GetInts();
158  }
159  else if (field->GetData().IsFields()) {
160  ITERATE(CUser_field::TData::TFields, iter, field->GetData().GetFields()) {
161  const CUser_field& f = **iter;
162  if (f.GetData().IsInt()) {
163  val.push_back(f.GetData().GetInt());
164  }
165  else if (f.GetData().IsInts()) {
166  val.insert(val.end(),
167  f.GetData().GetInts().begin(),
168  f.GetData().GetInts().end());
169  }
170  }
171  }
172 }
173 
174 void CRegistryReadView::GetRealVec(const objects::CUser_field* field, vector<double>& val)
175 {
176  val.clear();
177  if (!field) return;
178 
179  if (field->GetData().IsReal()) {
180  val.push_back(field->GetData().GetReal());
181  }
182  else if (field->GetData().IsReals()) {
183  val = field->GetData().GetReals();
184  }
185  else if (field->GetData().IsFields()) {
186  ITERATE(CUser_field::TData::TFields, iter, field->GetData().GetFields()) {
187  const CUser_field& f = **iter;
188  if (f.GetData().IsReal()) {
189  val.push_back(f.GetData().GetReal());
190  }
191  else if (f.GetData().IsReals()) {
192  val.insert(val.end(),
193  f.GetData().GetReals().begin(),
194  f.GetData().GetReals().end());
195  }
196  }
197  }
198 }
199 
200 void CRegistryReadView::GetStringVec(const objects::CUser_field* field, vector<string>& val)
201 {
202  val.clear();
203  if (!field) return;
204 
205  if (field->GetData().IsStr()) {
206  val.push_back(field->GetData().GetStr());
207  }
208  else if (field->GetData().IsStrs()) {
209  val.insert(val.end(),
210  field->GetData().GetStrs().begin(),
211  field->GetData().GetStrs().end());
212  }
213  else if (field->GetData().IsFields()) {
214  ITERATE(CUser_field::TData::TFields, iter, field->GetData().GetFields()) {
215  const CUser_field& f = **iter;
216  if (f.GetData().IsStr()) {
217  val.push_back(f.GetData().GetStr());
218  }
219  else if (f.GetData().IsStrs()) {
220  val.insert(val.end(),
221  f.GetData().GetStrs().begin(),
222  f.GetData().GetStrs().end());
223  }
224  }
225  }
226 }
227 
228 
229 /// type-specific field accessors
230 int CRegistryReadView::GetInt(const string& key, int default_val) const
231 {
232  return GetInt(GetField(key), default_val);
233 }
234 
235 double CRegistryReadView::GetReal(const string& key, double default_val) const
236 {
237  return GetReal(GetField(key), default_val);
238 }
239 
240 
241 bool CRegistryReadView::GetBool(const string& key, bool default_val) const
242 {
243  return GetBool(GetField(key), default_val);
244 }
245 
246 string CRegistryReadView::GetString(const string& key, const string& default_val) const
247 {
248  return GetString(GetField(key), default_val);
249 }
250 
251 
252 void CRegistryReadView::GetIntVec(const string& key, vector<int>& val) const
253 {
255 }
256 
257 void CRegistryReadView::GetRealVec(const string& key, vector<double>& val) const
258 {
260 }
261 
262 
263 void CRegistryReadView::GetStringVec(const string& key, vector<string>& val) const
264 {
266 }
267 
268 void CRegistryReadView::GetStringList(const string& key, list<string>& val) const
269 {
270  vector<string> v;
272 
273  val.clear();
274  std::copy(v.begin(), v.end(), std::back_inserter(val));
275 }
276 
277 
279 {
280  x_GetKeys(keys, false);
281 }
282 
283 
285 {
286  x_GetKeys(keys, true);
287 }
288 
289 static void s_ExtractKeys(const CUser_field& field,
290  const string& root,
291  CRegistryReadView::TKeys& key_info,
292  bool recurse)
293 {
295  info.key = root;
296  if (!info.key.empty()) {
297  info.key += ".";
298  }
299  info.key += field.GetLabel().GetStr();
300  info.type = field.GetData().Which();
301  key_info.push_back(info);
302 
303  if (recurse) {
304  switch (field.GetData().Which()) {
306  {{
307  string subkey = root;
308  if (!subkey.empty()) {
309  subkey += ".";
310  }
311  subkey += field.GetLabel().GetStr();
313  field.GetData().GetFields()) {
314  s_ExtractKeys(**iter, subkey, key_info, true);
315  }
316  }}
317  break;
318 
319  default:
320  break;
321  }
322  }
323 }
324 
325 void CRegistryReadView::x_GetKeys(TKeys& keys, bool recurse) const
326 {
328  TKeyMap key_map; // used to sort the final list.
329 
330  TFields::const_reverse_iterator riter(m_Fields.rbegin());
331  TFields::const_reverse_iterator rend(m_Fields.rend());
332 
333  for (; riter != rend; ++riter) {
334  const CUser_field& obj = **riter;
335  if (obj.GetData().IsFields()) {
336  TKeys temp;
338  obj.GetData().GetFields()) {
339  s_ExtractKeys(**sub_iter, "", temp, recurse);
340  }
341  ITERATE(TKeys, key_it, temp) {
342  key_map[key_it->key] = *key_it;
343  }
344  }
345  }
346 
347  keys.clear();
348  ITERATE(TKeyMap, iter, key_map)
349  keys.push_back(iter->second);
350 }
351 
352 bool CRegistryReadView::HasField(const string& key) const
353 {
354  ITERATE(TFields, iter, m_Fields) {
355  const CUser_field& obj = **iter;
356  if (obj.HasField(key))
357  return true;
358  }
359  return false;
360 }
361 
362 
364 {
365  return m_Fields.empty();
366 }
367 
369  list< CConstRef<CUser_field> >& fields, const CUser_field* meta)
370 {
371  if (fields.empty())
372  return CConstRef<CUser_field>();
373 
374  if (fields.size() == 1)
375  return fields.front();
376 
377  int merge_policy = 0;
378  if (meta) {
379  CConstRef<CUser_field> merge_field = meta->GetFieldRef("MergePolicy");
380  if (merge_field && merge_field->GetData().IsStr()) {
381  string str = merge_field->GetData().GetStr();
383  if (str == "append") {
384  merge_policy = 1;
385  }
386  else if (str == "prepend") {
387  merge_policy = 2;
388  }
389  }
390  }
391 
392  //
393  // all fields should be objects, so look for sub-fields that
394  // meet the criteria we want
395  //
396  switch (merge_policy) {
397  case 1:
398  {{
399  CRef<CUser_field> field;
400  field.Reset(new CUser_field());
401  ITERATE(list< CConstRef<CUser_field> >, iter, fields) {
403  (const_cast<CUser_field*>(iter->GetPointer()));
404  field->SetData().SetFields().push_back(f);
405  }
406  return CConstRef<CUser_field>(field.Release());
407  }}
408 
409  case 2:
410  {{
411  CRef<CUser_field> field;
412  std::reverse(fields.begin(), fields.end());
413  field.Reset(new CUser_field());
414  ITERATE(list< CConstRef<CUser_field> >, iter, fields) {
416  (const_cast<CUser_field*>(iter->GetPointer()));
417  field->SetData().SetFields().push_back(f);
418  }
419  return CConstRef<CUser_field>(field.Release());
420  }}
421  default:
422  return fields.front();
423  }
424 }
425 
427 {
428  TKeys keys;
429  GetKeys(keys);
430 
431  ostr << keys.size() << " keys:" << endl;
432  ITERATE(TKeys, iter, keys) {
433  const SKeyInfo& key = *iter;
434 
435  ostr << key.key << "|";
436 
437  vector<string> strs;
438  vector<int> ints;
439  vector<double> reals;
440  switch (key.type) {
442  ostr << "bool|" << NStr::BoolToString(GetBool(key.key));
443  break;
445  ostr << "int|" << GetInt(key.key);
446  break;
448  ostr << "ints|";
449  GetIntVec(key.key, ints);
450  copy(ints.begin(), ints.end(), ostream_iterator<int>(ostr, ";"));
451  break;
453  ostr << "real|" << GetReal(key.key);
454  break;
456  ostr << "reals|";
457  GetRealVec(key.key, reals);
458  copy(reals.begin(), reals.end(), ostream_iterator<double>(ostr, ";"));
459  break;
461  ostr << "string|" << GetString(key.key);;
462  break;
464  ostr << "strings|";
465  GetStringVec(key.key, strs);
466  copy(strs.begin(), strs.end(), ostream_iterator<string>(ostr, ";"));
467  break;
469  ostr << "subkey|";
470  break;
471  default:
472  ostr << "unknown|";
473  break;
474  }
475  ostr << endl;
476 
477  }
478 }
479 
480 /////////////////////////////////////////////////////////////////////////////
481 ///
482 /// CRegistryWriteView
483 
485  : m_Section(section), m_RegistryFile(&regFile)
486 {
487 }
488 
489 static const char* kEmptyViewError = "Writing to empty CRegistryWriteView";
490 
492 {
493  if (!m_RegistryFile) {
495  return CRegistryWriteView();
496  }
497 
499 }
500 
501 /// retrieve a writeable field at a particular section and key
503 {
504  if (!m_RegistryFile) {
506  return CRef<CUser_field>(new CUser_field());
507  }
508 
510 }
511 
513 {
514  CRef<CUser_field> section_obj = SetField(key);
515  if (section_obj->GetData().IsFields()) {
516  // field is a place for subkeys, not for a value.
518  "Too few components in key \"" + key + "\"");
519  }
520  return section_obj;
521 }
522 
524 {
525  if (!m_RegistryFile) {
527  return false;
528  }
530 }
531 
532 /// set specific values
533 void CRegistryWriteView::Set(const string& key, int val)
534 {
536  field->SetData().SetInt(val);
537 }
538 
539 void CRegistryWriteView::Set(const string& key, double val)
540 {
542  field->SetData().SetReal(val);
543 }
544 
545 void CRegistryWriteView::Set(const string& key, bool val)
546 {
548  field->SetData().SetBool(val);
549 }
550 
551 void CRegistryWriteView::Set(const string& key, const string& val)
552 {
554  field->SetData().SetStr(val);
555 }
556 
557 void CRegistryWriteView::Set(const string& key, const char* val)
558 {
559  Set(key, string(val));
560 }
561 
562 void CRegistryWriteView::Set(const string& key, const vector<int>& val)
563 {
565  field->SetData().SetInts() = val;
566 }
567 
568 void CRegistryWriteView::Set(const string& key, const vector<double>& val)
569 {
571  field->SetData().SetReals() = val;
572 }
573 
574 void CRegistryWriteView::Set(const string& key, const vector<string>& val)
575 {
577  CUser_field_Base::C_Data::TStrs& dest = field->SetData().SetStrs();
578  dest.clear();
579  ITERATE(vector<string>, v, val) {
580  dest.push_back(*v);
581  }
582 }
583 
584 void CRegistryWriteView::Set(const string& key, const list<string>& val)
585 {
586  vector<string> v;
587  v.reserve(val.size());
588  ITERATE(list<string>, it, val) {
589  v.push_back(*it);
590  }
591  Set(key, v);
592 }
593 
CRef< objects::CUser_field > SetField(const string &key)
Definition: reg_file.cpp:487
bool DeleteField(const string &key)
Definition: reg_file.cpp:493
class CRegistryReadView provides a nested hierarchical view at a particular key.
Definition: reg_view.hpp:58
int GetInt(const string &key, int default_val=0) const
access a named key at this level, with no recursion
Definition: reg_view.cpp:230
double GetReal(const string &key, double default_val=0) const
Definition: reg_view.cpp:235
bool GetBool(const string &key, bool default_val=false) const
Definition: reg_view.cpp:241
void DumpAll(CNcbiOstream &ostr) const
Dump onto the stream all the keys in this view along with their types and data values.
Definition: reg_view.cpp:426
void GetIntVec(const string &key, vector< int > &val) const
Definition: reg_view.cpp:252
void x_GetKeys(TKeys &keys, bool recurse) const
implementing GetTopKeys and GetKeys.
Definition: reg_view.cpp:325
list< SKeyInfo > TKeys
retrieve information about all keys in the registry
Definition: reg_view.hpp:68
void GetTopKeys(TKeys &keys) const
Retrieve information about the top level keys in this view.
Definition: reg_view.cpp:278
void GetRealVec(const string &key, vector< double > &val) const
Definition: reg_view.cpp:257
bool HasField(const string &key) const
Does a field with this section and key exist in this view?
Definition: reg_view.cpp:352
string GetString(const string &key, const string &default_val=kEmptyStr) const
Definition: reg_view.cpp:246
void GetStringList(const string &key, list< string > &val) const
Definition: reg_view.cpp:268
void GetStringVec(const string &key, vector< string > &val) const
Definition: reg_view.cpp:263
CRegistryReadView GetReadView(const string &section) const
Definition: reg_view.cpp:74
list< CConstRef< objects::CUser_field > > TFields
ordered list of subfields to scan
Definition: reg_view.hpp:133
void x_AppendToReadView(CRegistryReadView &view, const string &section) const
Definition: reg_view.cpp:61
CConstRef< objects::CUser_field > GetField(const string &key) const
provide raw field access
Definition: reg_view.cpp:104
bool IsEmpty()
There is nothing in this view.
Definition: reg_view.cpp:363
static CConstRef< objects::CUser_field > ResolveField(list< CConstRef< objects::CUser_field > > &fields, const objects::CUser_field *meta)
Definition: reg_view.cpp:368
CRegistryReadView & operator+=(const CRegistryReadView &rhs)
Definition: reg_view.cpp:55
void GetKeys(TKeys &keys) const
Retrieve information about all keys in this view.
Definition: reg_view.cpp:284
CRegistryWriteView GetWriteView(const string &section)
Definition: reg_view.cpp:491
CRegistryFile * m_RegistryFile
Definition: reg_view.hpp:174
CRef< objects::CUser_field > SetFieldToValue(const string &key)
same as SetField, but complain loudly if the field has subfields in it already.
Definition: reg_view.cpp:512
CRef< objects::CUser_field > SetField(const string &key)
provide raw field access
Definition: reg_view.cpp:502
void Set(const string &key, int val)
access a named key at this level, with no recursion
Definition: reg_view.cpp:533
bool DeleteField(const string &key)
delete the specified field (and any of its subfields) from this view and from its registry.
Definition: reg_view.cpp:523
CConstRef< CUser_field > GetFieldRef(const string &str, const string &delim=".", NStr::ECase use_case=NStr::eCase) const
Return a field reference representing the tokenized key, or a NULL reference if the key doesn't exist...
Definition: User_field.cpp:226
bool HasField(const string &str, const string &delim=".", NStr::ECase use_case=NStr::eCase) const
Verify that a named field exists.
Definition: User_field.cpp:393
Definition: map.hpp:338
static const char * str(char *buf, int n)
Definition: stats.c:84
static FILE * f
Definition: readconf.c:23
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define LOG_POST(message)
This macro is deprecated and it's strongly recomended to move in all projects (except tests) to macro...
Definition: ncbidiag.hpp:226
void Error(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1197
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
TObjectType * Release(void)
Release a reference to the object and return a pointer to the object.
Definition: ncbiobj.hpp:846
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
Definition: ncbistre.hpp:149
static const string BoolToString(bool value)
Convert bool to string.
Definition: ncbistr.cpp:2806
static string & ToLower(string &str)
Convert string to lower case – string& version.
Definition: ncbistr.cpp:405
const TStr & GetStr(void) const
Get the variant data.
const TData & GetData(void) const
Get the Data member data.
const TFields & GetFields(void) const
Get the variant data.
vector< CRef< CUser_field > > TFields
bool IsFields(void) const
Check if variant Fields is selected.
bool IsStr(void) const
Check if variant Str is selected.
const TStr & GetStr(void) const
Get the variant data.
Definition: Object_id_.hpp:297
void SetData(TData &value)
Assign a value to Data data member.
const TLabel & GetLabel(void) const
Get the Label member data.
vector< CStringUTF8 > TStrs
E_Choice Which(void) const
Which variant is currently selected.
static MDB_envinfo info
Definition: mdb_load.c:37
const struct ncbi::grid::netcache::search::fields::KEY key
const struct ncbi::grid::netcache::search::fields::SUBKEY subkey
intr::rbtree< SNCCacheData, intr::base_hook< TKeyMapHook >, intr::constant_time_size< true >, intr::compare< SCacheKeyCompare > > TKeyMap
Definition: nc_storage.cpp:151
void copy(Njn::Matrix< S > *matrix_, const Njn::Matrix< T > &matrix0_)
Definition: njn_matrix.hpp:613
USING_SCOPE(objects)
static const char * kEmptyViewError
Definition: reg_view.cpp:489
static const string kDecimalDot
Definition: reg_view.cpp:42
static void s_ExtractKeys(const CUser_field &field, const string &root, CRegistryReadView::TKeys &key_info, bool recurse)
Definition: reg_view.cpp:289
Modified on Fri Sep 20 14:57:33 2024 by modify_doxy.py rev. 669887