NCBI C++ ToolKit
ncbireg.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef CORELIB___NCBIREG__HPP
2 #define CORELIB___NCBIREG__HPP
3 
4 /* $Id: ncbireg.hpp 87681 2019-09-23 03:58:14Z lavr $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software/database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software/database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Authors: Denis Vakatov, Aaron Ucko
30  *
31  */
32 
33 /// @file ncbireg.hpp
34 /// Process information in the NCBI Registry, including working with
35 /// configuration files.
36 ///
37 /// Classes to perform NCBI Registry operations including:
38 /// - Read and parse configuration file
39 /// - Search, edit, etc. the retrieved configuration information
40 /// - Write information back to configuration file
41 ///
42 /// The Registry is defined as a text file with sections and entries in the
43 /// form of "name=value" strings in each section.
44 ///
45 /// For an explanation of the syntax of the Registry file, see the
46 /// C++ Toolkit documentation.
47 
48 
49 #include <corelib/ncbimtx.hpp>
50 #include <map>
51 
52 
53 /** @addtogroup Registry
54  *
55  * @{
56  */
57 
58 
60 
61 
62 
63 /////////////////////////////////////////////////////////////////////////////
64 ///
65 /// IRegistry --
66 ///
67 /// Base class for organized configuration data.
68 ///
69 /// Does not define a specific in-memory representation, just a
70 /// read-only API and some convenience methods.
71 
73 {
74 public:
75  /// Flags controlling the behavior of registry methods. Please note:
76  /// - Although CNcbiRegistry supports a full complement of layers, other
77  /// derived classes may ignore some or all level-related flags.
78  /// - Most read-only operations consider all layers; the only exception
79  /// is Write, which defaults to fPersistent and fJustCore.
80  /// - The presence or absence of fSectionCase and fEntryCase is relevant
81  /// ONLY when constructing new registry objects.
82  enum EFlags {
83  fTransient = 0x1, ///< Transient -- not saved by default
84  fPersistent = 0x100, ///< Persistent -- saved when file is written
85  fOverride = 0x2, ///< Existing value can be overriden
86  fNoOverride = 0x200, ///< Cannot change existing value
87  fTruncate = 0x4, ///< Leading, trailing blanks can be truncated
88  fNoTruncate = 0x400, ///< Cannot truncate parameter value
89  fJustCore = 0x8, ///< Ignore auxiliary subregistries
90  fNotJustCore = 0x800, ///< Include auxiliary subregistries
91  fIgnoreErrors = 0x10, ///< Continue Read()ing after parse errors
92  fInternalSpaces = 0x20, ///< Allow internal whitespace in names
93  fWithNcbirc = 0x40, ///< Include .ncbirc (used only by CNcbiReg.)
94  fCountCleared = 0x80, ///< Let explicitly cleared entries stand
95  fSectionCase = 0x1000,///< Create with case-sensitive section names
96  fEntryCase = 0x2000,///< Create with case-sensitive entry names
97  fSectionlessEntries = 0x4000,///< Allow empty section names (for test_res framework)
98  fSections = 0x8000,///< Indicates that we want sections from x_Enumerate
99  fPlaintextAllowed = 0x10000,///< @sa GetEncryptedString()
100  fInSectionComments = 0x20000,/**< Indicates that we want in-section
101  comments from x_Enumerate */
102  fInternalCheckedAndLocked = 0x40000, ///< @internal
103  fCoreLayers = fTransient | fPersistent | fJustCore,
104  fAllLayers = fTransient | fPersistent | fNotJustCore,
105  fCaseFlags = fSectionCase | fEntryCase
106  };
107  typedef int TFlags; ///< Binary OR of "EFlags"
108 
109  /// Verify if Registry is empty.
110  /// @param flags
111  /// Layer(s) to check.
112  /// @return
113  /// TRUE if the registry contains no entries.
114  bool Empty(TFlags flags = fAllLayers) const;
115 
116  /// Verify if persistent values have been modified.
117  /// @param flags
118  /// Layer(s) to check.
119  /// @return
120  /// TRUE if the relevant part(s) of the registry were modified since the
121  /// last call to SetModifiedFlag(false).
122  bool Modified(TFlags flags = fPersistent) const;
123 
124  /// Indicate whether any relevant values are out of sync with some
125  /// external resource (typically a configuration file). You
126  /// should normally not need to call this explicitly.
127  /// @param flags
128  /// Relevant layer(s).
129  void SetModifiedFlag(bool modified, TFlags flags = fPersistent);
130 
131  /// Write the registry content to output stream.
132  /// @param os
133  /// Output stream to write the registry to.
134  /// NOTE: if the stream is a file, it must be opened in binary mode!
135  /// @param flags
136  /// Layer(s) to write. By default, only persistent entries are
137  /// written, and only entries from the core layer(s) are written.
138  /// @return
139  /// TRUE if operation is successful.
140  /// @sa
141  /// IRWRegistry::Read()
142  bool Write(CNcbiOstream& os, TFlags flags = 0) const;
143 
144  /// Get the parameter value.
145  ///
146  /// Get the parameter with the specified "name" from the specified
147  /// "section". First, search for the transient parameter value, and if
148  /// cannot find in there, then continue the search in the non-transient
149  /// parameters. If "fPersistent" flag is set in "flags", then don't
150  /// search in the transient parameters at all.
151  /// @param section
152  /// Section name to search under (case-insensitive).
153  /// @param name
154  /// Parameter name to search for (case-insensitive).
155  /// @param flags
156  /// To control search.
157  /// @return
158  /// The parameter value, or empty string if the parameter is not found.
159  /// @sa
160  /// GetString(), GetEncryptedString()
161  virtual
162  const string& Get(const string& section,
163  const string& name,
164  TFlags flags = 0) const;
165 
166  virtual
167  bool HasEntry(const string& section,
168  const string& name = kEmptyStr,
169  TFlags flags = 0) const;
170 
171  /// Get the parameter string value.
172  ///
173  /// Similar to the "Get()", but if the configuration parameter is not
174  /// found, then return 'default_value' rather than empty string.
175  /// @sa
176  /// Get(), GetEncryptedString()
177  virtual
178  string GetString(const string& section,
179  const string& name,
180  const string& default_value,
181  TFlags flags = 0) const;
182 
183  /// Get a value that was (potentially) stored encrypted.
184  ///
185  /// Similar to Get(), but if the value appears to have been
186  /// encrypted, return the corresponding plaintext. Otherwise, unless
187  /// flags contains fPlaintextAllowed, throw an exception to let the
188  /// user know of inappropriate plaintext in the configuration file.
189  /// @param password
190  /// Explicitly supply a password. If absent, will try standard keys,
191  /// honoring any key domain recorded in the value.
192  /// @sa Get(), GetString(), CNcbiEncrypt
193  string GetEncryptedString(const string& section,
194  const string& name,
195  TFlags flags = 0,
196  const string& password = kEmptyStr) const;
197 
198  /// What to do if parameter value is present but cannot be converted into
199  /// the requested type.
200  enum EErrAction {
201  eThrow, ///< Throw an exception if an error occurs
202  eErrPost, ///< Log the error message and return default value
203  eReturn ///< Return default value
204  };
205 
206  /// Get integer value of specified parameter name.
207  ///
208  /// Like "GetString()", plus convert the value into integer.
209  /// @param err_action
210  /// What to do if error encountered in converting parameter value.
211  /// @sa
212  /// GetString()
213  virtual
214  int GetInt(const string& section,
215  const string& name,
216  int default_value,
217  TFlags flags = 0,
218  EErrAction err_action = eThrow) const;
219 
220  /// Get boolean value of specified parameter name.
221  ///
222  /// Like "GetString()", plus convert the value into boolean.
223  /// @param err_action
224  /// What to do if error encountered in converting parameter value.
225  /// @sa
226  /// GetString()
227  virtual
228  bool GetBool(const string& section,
229  const string& name,
230  bool default_value,
231  TFlags flags = 0,
232  EErrAction err_action = eThrow) const;
233 
234  /// Get double value of specified parameter name.
235  ///
236  /// Like "GetString()", plus convert the value into double.
237  /// @param err_action
238  /// What to do if error encountered in converting parameter value.
239  /// @sa
240  /// GetString()
241  virtual
242  double GetDouble(const string& section,
243  const string& name,
244  double default_value,
245  TFlags flags = 0,
246  EErrAction err_action = eThrow) const;
247 
248  /// Overloading of getters for generic programming
249  /// @{
250  string GetValue(const string& section,
251  const string& name,
252  const string& default_value,
253  EErrAction = eReturn,
254  TFlags flags = 0) const
255  {
256  return GetString(section, name, default_value, flags);
257  }
258 
259  int GetValue(const string& section,
260  const string& name,
261  int default_value,
262  EErrAction err_action = eErrPost,
263  TFlags flags = 0) const
264  {
265  return GetInt(section, name, default_value, flags, err_action);
266  }
267 
268  bool GetValue(const string& section,
269  const string& name,
270  bool default_value,
271  EErrAction err_action = eErrPost,
272  TFlags flags = 0) const
273  {
274  return GetBool(section, name, default_value, flags, err_action);
275  }
276 
277  double GetValue(const string& section,
278  const string& name,
279  double default_value,
280  EErrAction err_action = eErrPost,
281  TFlags flags = 0) const
282  {
283  return GetDouble(section, name, default_value, flags, err_action);
284  }
285  /// @}
286 
287  /// Get comment of the registry entry "section:name".
288  ///
289  /// @param section
290  /// Section name.
291  /// If passed empty string, then get the registry comment.
292  /// @param name
293  /// Parameter name.
294  /// If empty string, then get the "section" comment.
295  /// @param flags
296  /// To control search.
297  /// @return
298  /// Comment string. If not found, return an empty string.
299  virtual
300  const string& GetComment(const string& section = kEmptyStr,
301  const string& name = kEmptyStr,
302  TFlags flags = 0) const;
303 
304  /// Enumerate in-section comments.
305  ///
306  /// Write all in-section comments to the "comments" list in
307  /// (registry priority) order. Previous contents of the list are
308  /// erased.
309  /// @param flags
310  /// To control layers if search. Allowed values are fTransient,
311  /// fPersistent, fNotJustCore, fJustCore and their mix using |
312  virtual
313  void EnumerateInSectionComments(const string& section,
314  list<string>* comments,
315  TFlags flags = fAllLayers) const;
316 
317  /// Enumerate section names.
318  ///
319  /// Write all section names to the "sections" list in
320  /// (case-insensitive) order. Previous contents of the list are
321  /// erased.
322  /// @param flags
323  /// To control search.
324  virtual
325  void EnumerateSections(list<string>* sections,
326  TFlags flags = fAllLayers) const;
327 
328  /// Enumerate parameter names for a specified section.
329  ///
330  /// Write all parameter names for specified "section" to the "entries"
331  /// list in order. Previous contents of the list are erased.
332  /// @deprecated Enumerates sections rather than entries if section is
333  /// @deprecated empty and fSectionlessEntries is not set.
334  /// @param flags
335  /// To control search.
336  virtual
337  void EnumerateEntries(const string& section,
338  list<string>* entries,
339  TFlags flags = fAllLayers) const;
340 
341  /// Support for locking. Individual operations already use these
342  /// to ensure atomicity, but the locking mechanism is recursive,
343  /// so users can also make entire sequences of operations atomic.
344  void ReadLock (void);
345  void WriteLock(void);
346  void Unlock (void);
347 
348  /// Check if "str" consists of alphanumeric and '_' only
349  /// Treat the case of set fSectionlessEntries separately
350  static bool IsNameSection(const string& str, TFlags flags);
351 
352  // Check if "str" consists of alphanumeric and '_' only
353  static bool IsNameEntry(const string& str, TFlags flags);
354 
355 
356  /// Entry name for an in-section comment
357  static const char* sm_InSectionCommentName;
358 
359 #ifdef NCBI_COMPILER_ICC
360  /// Work around a compiler bug that can cause memory leaks.
361  virtual ~IRegistry() { }
362 #endif
363 
364 protected:
365  enum EMasks {
366  fLayerFlags = fAllLayers | fJustCore,
367  fTPFlags = fTransient | fPersistent
368  };
369 
370  static void x_CheckFlags(const string& func, TFlags& flags,
371  TFlags allowed);
372  /// Implementations of the fundamental operations above, to be run with
373  /// the lock already acquired and some basic sanity checks performed.
374  virtual bool x_Empty(TFlags flags) const = 0;
375  virtual bool x_Modified(TFlags /* flags */) const { return false; }
376  virtual void x_SetModifiedFlag(bool /* modified */, TFlags /* flags */) {}
377  virtual const string& x_Get(const string& section, const string& name,
378  TFlags flags) const = 0;
379  virtual bool x_HasEntry(const string& section, const string& name,
380  TFlags flags) const = 0;
381  virtual const string& x_GetComment(const string& section,
382  const string& name, TFlags flags)
383  const = 0;
384  // enumerate sections rather than entries if section is empty
385  virtual void x_Enumerate(const string& section, list<string>& entries,
386  TFlags flags) const = 0;
387 
388  typedef void (IRegistry::*FLockAction)(void);
389  virtual void x_ChildLockAction(FLockAction /* action */) {}
390 
391 private:
392  mutable CRWLock m_Lock;
393 };
394 
395 
396 
397 /////////////////////////////////////////////////////////////////////////////
398 ///
399 /// IRWRegistry --
400 ///
401 /// Abstract subclass for modifiable registries.
402 ///
403 /// To avoid confusion, all registry classes that support modification
404 /// should inherit from this class.
405 
407 {
408 public:
409  /// Categories of modifying operations
410  enum EOperation {
413  eSet
414  };
415 
416  /// Indicate which portions of the registry the given operation
417  /// would affect.
418  static TFlags AssessImpact(TFlags flags, EOperation op);
419 
420  /// Reset the registry content.
421  void Clear(TFlags flags = fAllLayers);
422 
423  /// Read and parse the stream "is", and merge its content with current
424  /// Registry entries.
425  ///
426  /// Once the Registry has been initialized by the constructor, it is
427  /// possible to load other parameters from other files using this method.
428  /// @param is
429  /// Input stream to read and parse.
430  /// NOTE: if the stream is a file, it must be opened in binary mode!
431  /// @param flags
432  /// How parameters are stored. The default is for all values to be read
433  /// as persistent with the capability of overriding any previously
434  /// loaded value associated with the same name. The default can be
435  /// modified by specifying "fTransient", "fNoOverride" or
436  /// "fTransient | fNoOverride". If there is a conflict between the old
437  /// and the new (loaded) entry value and if "fNoOverride" flag is set,
438  /// then just ignore the new value; otherwise, replace the old value by
439  /// the new one. If "fTransient" flag is set, then store the newly
440  /// retrieved parameters as transient; otherwise, store them as
441  /// persistent.
442  /// @param path
443  /// Where to look for base registries listed with relative paths.
444  /// @return
445  /// A pointer to a newly created subregistry, if any, directly
446  /// containing the entries loaded from is.
447  /// @sa
448  /// Write()
449  IRWRegistry* Read(CNcbiIstream& is, TFlags flags = 0,
450  const string& path = kEmptyStr);
451 
452  /// Set the configuration parameter value.
453  ///
454  /// @param value
455  /// Value that the parameter is set to.
456  /// @param flags
457  /// To control search.
458  /// Valid flags := { fPersistent, fNoOverride, fTruncate }
459  /// If there was already an entry with the same <section,name> key:
460  /// if "fNoOverride" flag is set then do not override old value
461  /// and return FALSE; else override the old value and return TRUE.
462  /// If "fPersistent" flag is set then store the entry as persistent;
463  /// else store it as transient.
464  /// If "fTruncate" flag is set then truncate the leading and trailing
465  /// spaces -- " \r\t\v" (NOTE: '\n' is not considered a space!).
466  /// @param comment
467  /// Optional comment string describing parameter.
468  /// @return
469  /// TRUE if successful (including replacing a value with itself)
470  bool Set(const string& section,
471  const string& name,
472  const string& value,
473  TFlags flags = 0,
474  const string& comment = kEmptyStr);
475 
476  /// Overloading of setters for generic programming
477  /// @{
478  bool SetValue(const string& section,
479  const string& name,
480  const string& value,
481  TFlags flags = 0,
482  const string& comment = kEmptyStr)
483  {
484  return Set(section, name, value, flags, comment);
485  }
486 
487  bool SetValue(const string& section,
488  const string& name,
489  int value,
490  TFlags flags = 0,
491  const string& comment = kEmptyStr)
492  {
493  return Set(section, name, NStr::IntToString(value), flags, comment);
494  }
495 
496  bool SetValue(const string& section,
497  const string& name,
498  bool value,
499  TFlags flags = 0,
500  const string& comment = kEmptyStr)
501  {
502  return Set(section, name, NStr::BoolToString(value), flags, comment);
503  }
504 
505  bool SetValue(const string& section,
506  const string& name,
507  double value,
508  TFlags flags = 0,
509  const string& comment = kEmptyStr)
510  {
511  return Set(section, name, to_string(value), flags, comment);
512  }
513  /// @}
514 
515  /// Fully unset the configuration parameter value, so that
516  /// HasEntry returns false.
517  /// @return
518  /// TRUE if there had been an existing value.
519  bool Unset(const string& section, const string& name, TFlags flags = 0);
520 
521  /// Set comment "comment" for the registry entry "section:name".
522  ///
523  /// @param comment
524  /// Comment string value.
525  /// Set to kEmptyStr to delete the comment.
526  /// @param section
527  /// Section name.
528  /// If "section" is empty string, then set as the registry comment.
529  /// @param name
530  /// Parameter name.
531  /// If "name" is empty string, then set as the "section" comment.
532  /// @param flags
533  /// How the comment is stored. The default is for comments to be
534  /// stored as persistent with the capability of overriding any
535  /// previously loaded value associated with the same name. The
536  /// default can be modified by specifying "fTransient", "fNoOverride"
537  /// or "fTransient | fNoOverride". If there is a conflict between the
538  /// old and the new comment and if "fNoOverride" flag is set, then
539  /// just ignore the new comment; otherwise, replace the old comment
540  /// by the new one. If "fTransient" flag is set, then store the new
541  /// comment as transient (generally not desired); otherwise, store it
542  /// as persistent.
543  /// @return
544  /// FALSE if "section" and/or "name" do not exist in registry.
545  bool SetComment(const string& comment,
546  const string& section = kEmptyStr,
547  const string& name = kEmptyStr,
548  TFlags flags = 0);
549 
550 #ifdef NCBI_COMPILER_ICC
551  /// Work around a compiler bug that can cause memory leaks.
552  virtual ~IRWRegistry() { }
553 #endif
554 
555 protected:
556  /// Called locked, like the virtual methods inherited from IRegistry.
557  virtual void x_Clear(TFlags flags) = 0;
558  virtual bool x_Set(const string& section, const string& name,
559  const string& value, TFlags flags,
560  const string& comment) = 0;
561  virtual bool x_Unset(const string& section, const string& name,
562  TFlags flags) = 0;
563  virtual bool x_SetComment(const string& comment, const string& section,
564  const string& name, TFlags flags) = 0;
565 
566  /// Most implementations should not override this, but
567  /// CNcbiRegistry must, to handle some special cases properly.
568  virtual IRWRegistry* x_Read(CNcbiIstream& is, TFlags flags,
569  const string& path);
570 
571  // for use by implementations
572  static bool MaybeSet(string& target, const string& value, TFlags flags);
573 };
574 
575 
576 
577 /////////////////////////////////////////////////////////////////////////////
578 ///
579 /// CMemoryRegistry --
580 ///
581 /// Straightforward monolithic modifiable registry.
582 
584 {
585 public:
587  : m_IsModified(false),
588  m_Sections((flags & fSectionCase) == 0 ? NStr::eNocase : NStr::eCase),
589  m_Flags(flags)
590  {}
591 
592 #ifdef NCBI_COMPILER_ICC
593  /// Work around a compiler bug that can cause memory leaks.
594  virtual ~CMemoryRegistry() { }
595 #endif
596 
597 protected:
598  bool x_Empty(TFlags flags) const;
599  bool x_Modified(TFlags) const { return m_IsModified; }
600  void x_SetModifiedFlag(bool modified, TFlags) { m_IsModified = modified; }
601  const string& x_Get(const string& section, const string& name,
602  TFlags flags) const;
603  bool x_HasEntry(const string& section, const string& name, TFlags flags)
604  const;
605  const string& x_GetComment(const string& section, const string& name,
606  TFlags flags) const;
607  void x_Enumerate(const string& section, list<string>& entries,
608  TFlags flags) const;
609 
610  void x_Clear(TFlags flags);
611  bool x_Set(const string& section, const string& name,
612  const string& value, TFlags flags,
613  const string& comment);
614  bool x_Unset(const string& section, const string& name, TFlags flags);
615  bool x_SetComment(const string& comment, const string& section,
616  const string& name, TFlags flags);
617 
618 public: // WorkShop needs these exposed
619  struct SEntry {
620  string value, comment;
621  };
623  struct SSection {
625  : entries((flags & fEntryCase) == 0 ? NStr::eNocase : NStr::eCase),
626  cleared(false)
627  { }
628  string comment;
629  string in_section_comment; //for comments inside section
631  bool cleared;
632  };
634 
635 private:
640 };
641 
642 
643 
644 /////////////////////////////////////////////////////////////////////////////
645 ///
646 /// CCompoundRegistry --
647 ///
648 /// Prioritized read-only collection of sub-registries.
649 ///
650 /// @sa
651 /// CTwoLayerRegistry
652 
654 {
655 public:
656  CCompoundRegistry() : m_CoreCutoff(ePriority_Default) { }
657 
658 #ifdef NCBI_COMPILER_ICC
659  /// Work around a compiler bug that can cause memory leaks.
660  virtual ~CCompoundRegistry() { }
661 #endif
662 
663  /// Priority for sub-registries; entries in higher-priority
664  /// sub-registries take precedence over (identically named) entries
665  /// in lower-priority ones. Ties are broken arbitrarily.
666  enum EPriority {
667  ePriority_Min = kMin_Int,
668  ePriority_Default = 0,
669  ePriority_Max = kMax_Int
670  };
671  typedef int TPriority; ///< Not restricted to ePriority_*.
672 
673  /// Non-empty names must be unique within each compound registry,
674  /// but there is no limit to the number of anonymous sub-registries.
675  /// Sub-registries themselves may not (directly) appear more than once.
676  void Add(const IRegistry& reg,
677  TPriority prio = ePriority_Default,
678  const string& name = kEmptyStr);
679 
680  /// Remove sub-registry "reg".
681  /// Throw an exception if "reg" is not a (direct) sub-registry.
682  void Remove(const IRegistry& reg);
683 
684  /// Subregistries whose priority is less than the core cutoff
685  /// (ePriority_Default by default) will be ignored for fJustCore
686  /// operations, such as Write by default.
687  TPriority GetCoreCutoff(void) const { return m_CoreCutoff; }
688  void SetCoreCutoff(TPriority prio) { m_CoreCutoff = prio; }
689 
690  /// Return a pointer to the sub-registry with the given name, or
691  /// NULL if not found.
692  CConstRef<IRegistry> FindByName(const string& name) const;
693 
694  /// Return a pointer to the highest-priority sub-registry with a
695  /// section named SECTION containing (if ENTRY is non-empty) an entry
696  /// named ENTRY, or NULL if not found.
697  CConstRef<IRegistry> FindByContents(const string& section,
698  const string& entry = kEmptyStr,
699  TFlags flags = 0) const;
700 
701  // allow enumerating sub-registries?
702 
703 protected:
704  // virtual methods of IRegistry
705 
706  /// True iff all sub-registries are empty
707  bool x_Empty(TFlags flags) const;
708 
709  /// True iff any sub-registry is modified
710  bool x_Modified(TFlags flags) const;
711  void x_SetModifiedFlag(bool modified, TFlags flags);
712  const string& x_Get(const string& section, const string& name,
713  TFlags flags) const;
714  bool x_HasEntry(const string& section, const string& name, TFlags flags)
715  const;
716  const string& x_GetComment(const string& section, const string& name,
717  TFlags flags) const;
718  void x_Enumerate(const string& section, list<string>& entries,
719  TFlags flags) const;
720  void x_ChildLockAction(FLockAction action);
721 
722 private:
725 
727  TNameMap m_NameMap; ///< excludes anonymous sub-registries
729 
730  friend class CCompoundRWRegistry;
731 };
732 
733 
734 
735 /////////////////////////////////////////////////////////////////////////////
736 ///
737 /// CTwoLayerRegistry --
738 ///
739 /// Limited to two direct layers (transient above persistent), but
740 /// supports modification.
741 ///
742 /// @sa
743 /// CCompoundRegistry
744 
746 {
747 public:
748  /// Constructor. The transient layer is always a new memory registry,
749  /// and so is the persistent layer by default.
750  CTwoLayerRegistry(IRWRegistry* persistent = 0, TFlags flags = 0);
751 
752 #ifdef NCBI_COMPILER_ICC
753  /// Work around a compiler bug that can cause memory leaks.
754  virtual ~CTwoLayerRegistry() { }
755 #endif
756 
757 protected:
758  bool x_Empty(TFlags flags) const;
759  bool x_Modified(TFlags flags) const;
760  void x_SetModifiedFlag(bool modified, TFlags flags);
761  const string& x_Get(const string& section, const string& name,
762  TFlags flags) const;
763  bool x_HasEntry(const string& section, const string& name,
764  TFlags flags) const;
765  const string& x_GetComment(const string& section, const string& name,
766  TFlags flags) const;
767  void x_Enumerate(const string& section, list<string>& entries,
768  TFlags flags) const;
769  void x_ChildLockAction(FLockAction action);
770 
771  void x_Clear(TFlags flags);
772  bool x_Set(const string& section, const string& name,
773  const string& value, TFlags flags,
774  const string& comment);
775  bool x_Unset(const string& section, const string& name, TFlags flags);
776  bool x_SetComment(const string& comment, const string& section,
777  const string& name, TFlags flags);
778 
779 private:
783 };
784 
785 
786 /////////////////////////////////////////////////////////////////////////////
787 ///
788 /// CCompoundRWRegistry --
789 ///
790 /// Writeable compound registry.
791 ///
792 /// Compound registry whose top layer is a two-layer registry; all
793 /// writes go to the two-layer registry.
794 
796 {
797 public:
798  /// Constructor.
799  CCompoundRWRegistry(TFlags m_Flags = 0);
800 
801  /// Destructor.
803 
804  /// Priority for sub-registries; entries in higher-priority
805  /// sub-registries take precedence over (identically named) entries
806  /// in lower-priority ones. Ties are broken arbitrarily.
807  enum EPriority {
808  ePriority_MinUser = CCompoundRegistry::ePriority_Min,
810  ePriority_MaxUser = CCompoundRegistry::ePriority_Max - 0x10000,
811  ePriority_Reserved ///< Everything greater is for internal use.
812  };
813  typedef int TPriority; ///< Not restricted to ePriority_*.
814 
815  /// Subregistries whose priority is less than the core cutoff
816  /// (ePriority_Reserved by default) will be ignored for fJustCore
817  /// operations, such as Write by default.
818  TPriority GetCoreCutoff(void) const;
819  void SetCoreCutoff(TPriority prio);
820 
821  /// Non-empty names must be unique within each compound registry,
822  /// but there is no limit to the number of anonymous sub-registries.
823  /// Sub-registries themselves may not (directly) appear more than once.
824  void Add(const IRegistry& reg,
825  TPriority prio = ePriority_Default,
826  const string& name = kEmptyStr);
827 
828  /// Remove sub-registry "reg".
829  /// Throw an exception if "reg" is not a (direct) sub-registry.
830  void Remove(const IRegistry& reg);
831 
832  /// Return a pointer to the sub-registry with the given name, or
833  /// NULL if not found.
834  CConstRef<IRegistry> FindByName(const string& name) const;
835 
836  /// Return a pointer to the highest-priority sub-registry with a
837  /// section named SECTION containing (if ENTRY is non-empty) an entry
838  /// named ENTRY, or NULL if not found.
839  CConstRef<IRegistry> FindByContents(const string& section,
840  const string& entry = kEmptyStr,
841  TFlags flags = 0) const;
842 
843  /// Load any base registries listed in [NCBI].Inherits; returns
844  /// true if able to load at least one, false otherwise.
845  /// @param flags
846  /// Registry flags to apply.
847  /// @param metareg_flags
848  /// Metaregistry flags to apply.
849  /// @param path
850  /// Where to look for base registries listed with relative paths.
851  bool LoadBaseRegistries(TFlags flags = 0,
852  int /* CMetaRegistry::TFlags */ metareg_flags = 0,
853  const string& path = kEmptyStr);
854 
855  /// Predefined subregistry's name.
856  static const char* sm_MainRegName;
857  /// Prefix for any base registries' names.
858  static const char* sm_BaseRegNamePrefix;
859 
860 protected:
861  bool x_Empty(TFlags flags) const;
862  bool x_Modified(TFlags flags) const;
863  void x_SetModifiedFlag(bool modified, TFlags flags);
864  const string& x_Get(const string& section, const string& name,
865  TFlags flags) const;
866  bool x_HasEntry(const string& section, const string& name,
867  TFlags flags) const;
868  const string& x_GetComment(const string& section, const string& name,
869  TFlags flags) const;
870  void x_Enumerate(const string& section, list<string>& entries,
871  TFlags flags) const;
872  void x_ChildLockAction(FLockAction action);
873 
874  void x_Clear(TFlags flags);
875  bool x_Set(const string& section, const string& name,
876  const string& value, TFlags flags,
877  const string& comment);
878  bool x_Unset(const string& section, const string& name, TFlags flags);
879  bool x_SetComment(const string& comment, const string& section,
880  const string& name, TFlags flags);
881  IRWRegistry* x_Read(CNcbiIstream& is, TFlags flags, const string& path);
882 
883  /// Add an internal high-priority subregistry.
884  void x_Add(const IRegistry& reg,
885  TPriority prio = ePriority_Default,
886  const string& name = kEmptyStr);
887 
888 private:
890 
896 };
897 
898 
899 class CEnvironmentRegistry; // see <corelib/env_reg.hpp>
900 
901 
902 
903 /////////////////////////////////////////////////////////////////////////////
904 ///
905 /// CNcbiRegistry --
906 ///
907 /// Define the Registry.
908 ///
909 /// Load, access, modify and store runtime information (usually used
910 /// to work with configuration files).
911 
913 {
914 public:
916  eTransient = fTransient,
917  ePersistent = fPersistent,
918  eOverride = fOverride,
919  eNoOverride = fNoOverride,
920  eTruncate = fTruncate,
921  eNoTruncate = fNoTruncate
922  };
923 
924  /// Constructor.
925  CNcbiRegistry(TFlags flags = 0);
926 
927  /// Constructor.
928  ///
929  /// @param is
930  /// Input stream to load the Registry from.
931  /// NOTE: if the stream is a file, it must be opened in binary mode!
932  /// @param flags
933  /// How parameters are stored. The default is to store all parameters as
934  /// persistent unless the "eTransient" flag is set in which case the
935  /// newly retrieved parameters are stored as transient.
936  /// @param path
937  /// Where to look for base registries listed with relative paths.
938  /// @sa
939  /// Read()
940  CNcbiRegistry(CNcbiIstream& is, TFlags flags = 0,
941  const string& path = kEmptyStr);
942 
943  ~CNcbiRegistry();
944 
945  /// Attempt to load a systemwide configuration file (.ncbirc on
946  /// Unix, ncbi.ini on Windows) as a low-priority registry, as long
947  /// as the following conditions all hold:
948  /// - fWithNcbirc is set in FLAGS.
949  /// - The environment variable NCBI_DONT_USE_NCBIRC is NOT set.
950  /// - The registry's existing contents do NOT contain a setting of
951  /// [NCBI]DONT_USE_NCBIRC (case-insensitive).
952  /// @param flags
953  /// Registry flags to be applied when reading the system
954  /// configuration file. Must also contain fWithNcbirc (which
955  /// will be filtered out before calling any other methods) for
956  /// the call to have any effect.
957  /// @return
958  /// TRUE if the system configuration file was successfully read
959  /// and parsed; FALSE otherwise.
960  bool IncludeNcbircIfAllowed(TFlags flags = fWithNcbirc);
961 
962  /// Predefined subregistries' names.
963  static const char* sm_EnvRegName;
964  static const char* sm_FileRegName;
965  static const char* sm_OverrideRegName;
966  static const char* sm_SysRegName;
967 
968 protected:
969  void x_Clear(TFlags flags);
970  IRWRegistry* x_Read(CNcbiIstream& is, TFlags flags, const string& path);
971  const string& x_GetComment(const string& section, const string& name,
972  TFlags flags) const;
973 
974 private:
975  void x_Init(void);
976 
978  ePriority_File = ePriority_Reserved,
981  ePriority_RuntimeOverrides
982  };
983 
990 };
991 
992 
993 
994 /////////////////////////////////////////////////////////////////////////////
995 ///
996 /// CRegistryException --
997 ///
998 /// Define exceptions generated by IRegistry and derived classes.
999 ///
1000 /// CRegistryException inherits its basic functionality from
1001 /// CCParseTemplException<CCoreException> and defines additional error codes
1002 /// for the Registry.
1003 
1005 {
1006 public:
1007  /// Error types that the Registry can generate.
1008  enum EErrCode {
1009  eSection, ///< Section name format error
1010  eEntry, ///< Entry name format error
1011  eValue, ///< General value format error
1012  eUnencrypted, ///< Value should have been encrypted, but wasn't
1013  eDecryptionFailed, ///< Value looked encrypted, but decryption failed
1014  eErr ///< Other error
1015  };
1016 
1017  /// Translate from the error code value to its string representation.
1018  virtual const char* GetErrCodeString(void) const override;
1019 
1020  // Standard exception boilerplate code
1023  std::string::size_type);
1024 };
1025 
1026 
1027 
1028 /////////////////////////////////////////////////////////////////////////////
1029 ///
1030 /// CRegistry{Read,Write}Guard --
1031 ///
1032 /// Guard classes to ensure one-thread-at-a-time access to registries.
1033 
1035  : public CGuard<IRegistry, SSimpleReadLock<IRegistry> >
1036 {
1037 public:
1040  : TParent(const_cast<IRegistry&>(reg))
1041  { }
1042 };
1043 
1045 
1047 
1048 
1049 /* @} */
1050 
1051 #endif /* CORELIB___NCBIREG__HPP */
#define false
Definition: bool.h:36
CCompoundRWRegistry –.
Definition: ncbireg.hpp:796
CCompoundRegistry –.
Definition: ncbireg.hpp:654
CConstRef –.
Definition: ncbiobj.hpp:1266
CEnvironmentRegistry –.
Definition: env_reg.hpp:87
CMemoryRegistry –.
Definition: ncbireg.hpp:584
CNcbiRegistry –.
Definition: ncbireg.hpp:913
CObject –.
Definition: ncbiobj.hpp:180
CParseTemplException –.
Definition: ncbistr.hpp:4396
CRWLock –.
Definition: ncbimtx.hpp:953
CRegistryException –.
Definition: ncbireg.hpp:1005
CRegistry{Read,Write}Guard –.
Definition: ncbireg.hpp:1036
CTwoLayerRegistry –.
Definition: ncbireg.hpp:746
IRWRegistry –.
Definition: ncbireg.hpp:407
IRegistry –.
Definition: ncbireg.hpp:73
NStr –.
Definition: ncbistr.hpp:243
char value[7]
Definition: config.c:431
static uch flags
bool Empty(const CNcbiOstrstream &src)
Definition: fileutil.cpp:523
@ eThrow
@ ePersistent
Definition: grid_cli.hpp:185
void Read(CObjectIStream &in, TObjectPtr object, const CTypeRef &type)
Definition: serial.cpp:60
void Write(CObjectOStream &out, TConstObjectPtr object, const CTypeRef &type)
Definition: serial.cpp:55
#define kMin_Int
Definition: ncbi_limits.h:183
#define kMax_Int
Definition: ncbi_limits.h:184
map< string, CRef< IRegistry > > TNameMap
Definition: ncbireg.hpp:724
int TFlags
Binary OR of "EFlags".
Definition: ncbireg.hpp:107
virtual void x_ChildLockAction(FLockAction)
Definition: ncbireg.hpp:389
int TPriority
Not restricted to ePriority_*.
Definition: ncbireg.hpp:813
void x_SetModifiedFlag(bool modified, TFlags)
Definition: ncbireg.hpp:600
static const char * sm_InSectionCommentName
Entry name for an in-section comment.
Definition: ncbireg.hpp:357
map< string, TFlags > TClearedEntries
Definition: ncbireg.hpp:889
map< string, SEntry, PNocase_Conditional > TEntries
Definition: ncbireg.hpp:622
set< string > m_BaseRegNames
Definition: ncbireg.hpp:894
NCBI_EXCEPTION_DEFAULT2(CRegistryException, CParseTemplException< CCoreException >, std::string::size_type)
multimap< TPriority, CRef< IRegistry > > TPriorityMap
Definition: ncbireg.hpp:723
static const char * sm_SysRegName
Definition: ncbireg.hpp:966
CRef< CTwoLayerRegistry > m_MainRegistry
Definition: ncbireg.hpp:892
virtual bool x_Set(const string &section, const string &name, const string &value, TFlags flags, const string &comment)=0
CMemoryRegistry(TFlags flags=0)
Definition: ncbireg.hpp:586
CRWLock m_Lock
Definition: ncbireg.hpp:392
virtual void x_Enumerate(const string &section, list< string > &entries, TFlags flags) const =0
virtual const string & x_Get(const string &section, const string &name, TFlags flags) const =0
TFlags m_Flags
Definition: ncbireg.hpp:639
SSection(TFlags flags)
Definition: ncbireg.hpp:624
TClearedEntries m_ClearedEntries
Definition: ncbireg.hpp:891
virtual void x_SetModifiedFlag(bool, TFlags)
Definition: ncbireg.hpp:376
TFlags m_Flags
Definition: ncbireg.hpp:989
TSections m_Sections
Definition: ncbireg.hpp:638
virtual bool x_SetComment(const string &comment, const string &section, const string &name, TFlags flags)=0
virtual void x_Clear(TFlags flags)=0
Called locked, like the virtual methods inherited from IRegistry.
bool SetValue(const string &section, const string &name, const string &value, TFlags flags=0, const string &comment=kEmptyStr)
Overloading of setters for generic programming.
Definition: ncbireg.hpp:478
virtual bool x_Empty(TFlags flags) const =0
Implementations of the fundamental operations above, to be run with the lock already acquired and som...
bool GetValue(const string &section, const string &name, bool default_value, EErrAction err_action=eErrPost, TFlags flags=0) const
Definition: ncbireg.hpp:268
TNameMap m_NameMap
excludes anonymous sub-registries
Definition: ncbireg.hpp:727
EPriority
Priority for sub-registries; entries in higher-priority sub-registries take precedence over (identica...
Definition: ncbireg.hpp:666
double GetValue(const string &section, const string &name, double default_value, EErrAction err_action=eErrPost, TFlags flags=0) const
Definition: ncbireg.hpp:277
int GetValue(const string &section, const string &name, int default_value, EErrAction err_action=eErrPost, TFlags flags=0) const
Definition: ncbireg.hpp:259
TPriority m_CoreCutoff
Definition: ncbireg.hpp:728
CRef< IRWRegistry > m_OverrideRegistry
Definition: ncbireg.hpp:986
virtual bool x_Modified(TFlags) const
Definition: ncbireg.hpp:375
static const char * sm_MainRegName
Predefined subregistry's name.
Definition: ncbireg.hpp:856
virtual const string & x_GetComment(const string &section, const string &name, TFlags flags) const =0
CRegistryReadGuard(const IRegistry &reg)
Definition: ncbireg.hpp:1039
virtual bool x_HasEntry(const string &section, const string &name, TFlags flags) const =0
bool x_Modified(TFlags) const
Definition: ncbireg.hpp:599
TPriority GetCoreCutoff(void) const
Subregistries whose priority is less than the core cutoff (ePriority_Default by default) will be igno...
Definition: ncbireg.hpp:687
CRegRef m_Transient
Definition: ncbireg.hpp:781
EFlags
Flags controlling the behavior of registry methods.
Definition: ncbireg.hpp:82
string GetValue(const string &section, const string &name, const string &default_value, EErrAction=eReturn, TFlags flags=0) const
Overloading of getters for generic programming.
Definition: ncbireg.hpp:250
CGuard< IRegistry, SSimpleWriteLock< IRegistry > > CRegistryWriteGuard
Definition: ncbireg.hpp:1044
EErrAction
What to do if parameter value is present but cannot be converted into the requested type.
Definition: ncbireg.hpp:200
CRef< CTwoLayerRegistry > m_FileRegistry
Definition: ncbireg.hpp:985
static const char * sm_EnvRegName
Predefined subregistries' names.
Definition: ncbireg.hpp:963
CRef< CEnvironmentRegistry > m_EnvRegistry
Definition: ncbireg.hpp:984
static const char * sm_FileRegName
Definition: ncbireg.hpp:964
CRegRef m_Persistent
Definition: ncbireg.hpp:782
bool SetValue(const string &section, const string &name, bool value, TFlags flags=0, const string &comment=kEmptyStr)
Definition: ncbireg.hpp:496
EPriority
Priority for sub-registries; entries in higher-priority sub-registries take precedence over (identica...
Definition: ncbireg.hpp:807
virtual bool x_Unset(const string &section, const string &name, TFlags flags)=0
CRef< IRWRegistry > CRegRef
Definition: ncbireg.hpp:780
unsigned int m_RuntimeOverrideCount
Definition: ncbireg.hpp:988
CGuard< IRegistry, SSimpleReadLock< IRegistry > > TParent
Definition: ncbireg.hpp:1038
CRef< IRWRegistry > m_SysRegistry
Definition: ncbireg.hpp:987
static const char * sm_OverrideRegName
Definition: ncbireg.hpp:965
int TPriority
Not restricted to ePriority_*.
Definition: ncbireg.hpp:671
bool SetValue(const string &section, const string &name, int value, TFlags flags=0, const string &comment=kEmptyStr)
Definition: ncbireg.hpp:487
CRef< CCompoundRegistry > m_AllRegistries
Definition: ncbireg.hpp:893
TPriorityMap m_PriorityMap
Definition: ncbireg.hpp:726
string m_RegistryComment
Definition: ncbireg.hpp:637
map< string, SSection, PNocase_Conditional > TSections
Definition: ncbireg.hpp:633
bool SetValue(const string &section, const string &name, double value, TFlags flags=0, const string &comment=kEmptyStr)
Definition: ncbireg.hpp:505
void SetCoreCutoff(TPriority prio)
Definition: ncbireg.hpp:688
EOperation
Categories of modifying operations.
Definition: ncbireg.hpp:410
static const char * sm_BaseRegNamePrefix
Prefix for any base registries' names.
Definition: ncbireg.hpp:858
EErrCode
Error types that the Registry can generate.
Definition: ncbireg.hpp:1008
@ eThrow
Throw an exception if an error occurs.
Definition: ncbireg.hpp:201
@ eErrPost
Log the error message and return default value.
Definition: ncbireg.hpp:202
@ ePriority_Overrides
Definition: ncbireg.hpp:979
@ ePriority_Environment
Definition: ncbireg.hpp:980
@ eValue
General value format error.
Definition: ncbireg.hpp:1011
@ eUnencrypted
Value should have been encrypted, but wasn't.
Definition: ncbireg.hpp:1012
@ eSection
Section name format error.
Definition: ncbireg.hpp:1009
@ eDecryptionFailed
Value looked encrypted, but decryption failed.
Definition: ncbireg.hpp:1013
@ eEntry
Entry name format error.
Definition: ncbireg.hpp:1010
#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
IO_PREFIX::istream CNcbiIstream
Portable alias for istream.
Definition: ncbistre.hpp:146
#define kEmptyStr
Definition: ncbistr.hpp:123
static const string BoolToString(bool value)
Convert bool to string.
Definition: ncbistr.cpp:2813
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5083
#define NCBI_XNCBI_EXPORT
Definition: ncbi_export.h:1283
const TYPE & Get(const CNamedParameterList *param)
Multi-threading – mutexes; rw-locks; semaphore.
static const char * str(char *buf, int n)
Definition: stats.c:84
static wxAcceleratorEntry entries[3]
Modified on Tue Nov 28 02:22:22 2023 by modify_doxy.py rev. 669887