KaliVeda  1.13/01
Heavy-Ion Analysis Toolkit
KVNameValueList.cpp
Go to the documentation of this file.
1 //Created by KVClassFactory on Tue Jun 29 14:44:22 2010
2 //Author: bonnet
3 
4 #include "KVClassFactory.h"
5 #include "KVNameValueList.h"
6 #include "Riostream.h"
7 #include <KVEnv.h>
8 #include <TROOT.h>
9 
10 using namespace std;
11 
13 
14 //______________________________________________
15 
16 
20  : fList(), fIgnoreBool(kFALSE)
21 {
22  // Default constructor
23  fList.SetOwner(kTRUE);
24 }
25 
26 
27 
37 
38 KVNameValueList::KVNameValueList(std::initializer_list<KVNamedParameter> l)
39 {
40  // Constructor using an initializer list for a given set of KVNamedParameter objects,
41  // i.e. this contructor makes it possible to do:
42  //
43  //~~~~{.cpp}
44  //KVNameValueList list{{"A",1.234},{"B",false},{"C","hello"}};
45  //
46  //KVNameValueList list2 = {{"A",1.234},{"B",false},{"C","hello"}};
47  //~~~~
48 
49  for (auto& p : l) SetValue(p);
50 }
51 
52 
53 
59 
61  : TNamed(name, title), fList(), fIgnoreBool(kFALSE)
62 {
63  // Ctor with name & title
64  //
65  // if name contains a comma-separated list of parameter/value pairs,
66  // it will be used to initialise the list (no name set)
68 
69  if (Set(name)) SetName("");
70 }
71 
72 
73 
76 
78 {
79  // Copy constructor
80  NVL.Copy(*this);
82 }
83 
84 
85 
88 
90 {
91  // Destructor
92  fList.Clear();// will delete objects in list if owner
93 }
94 
95 
96 
98 
100 {
101  if (&o != this) o.Copy(*this);
102  return (*this);
103 }
104 
105 
106 
130 
132 {
133  // If list contains a comma-separated list of parameter/value pairs
134  //
135  //~~~~~~~~~~~~~~~~~~~
136  //list = "param1=val1,param2=val2,..."
137  //~~~~~~~~~~~~~~~~~~~
138  //
139  // then use it to initialise the parameters of the list, and return true (any existing parameters will be removed).
140  //
141  // If list does not contain at least one '=' character, do nothing and return false.
142  //
143  // ### Note on deduction of parameter types
144  //
145  // The type of each parameter is deduced from the given values, using the following methods
146  // in the following order:
147  //
148  // + string in single quotes => string parameter (e.g. val="'7 9'")
149  // + KVString::IsDigit(val) => integer parameter if true (e.g. val="3" _or_ val="7 9")
150  // + KVString::IsFloat(val) => double parameter if true (e.g. val="3.14e+03")
151  // + all other cases => string parameter
152  //
153  // Note that in the case of the quoted string, the parameter is stored without the
154  // enclosing quotes (i.e. for val="'7 9'" the stored string is "7 9")
155 
156  if (!list.Contains("=")) return false;
157 
158  Clear();
159  list.Begin(",");
160  while (!list.End()) {
161  KVString pair = list.Next(kTRUE);
162  pair.Begin("=");
163  KVString parname = pair.Next(kTRUE);
164  KVString parval = pair.Next(kTRUE);
165  if (parval.BeginsWith("'") && parval.EndsWith("'")) {
166  // quoted string
167  parval.Remove(parval.Length() - 1);
168  parval.Remove(0, 1);
169  SetValue(parname, parval);
170  }
171  else if (parval.IsDigit()) {
172  // integer number
173  SetValue(parname, parval.Atoi());
174  }
175  else if (parval.IsFloat()) {
176  // real number
177  SetValue(parname, parval.Atof());
178  }
179  else {
180  // string
181  SetValue(parname, parval);
182  }
183  }
184  return true;
185 }
186 
187 
188 
197 
199 {
200  // Fill and return a string containing a comma-separated list of the parameter/value pairs
201  //
202  //~~~~~~~~~~~~~~~~~~~
203  //"param1=val1,param2=val2,..."
204  //~~~~~~~~~~~~~~~~~~~
205  //
206  // Such a string can be used with method Set() in order to initialize a copy of this list.
207 
208  KVString list;
209  for (auto& par : *this) {
210  if (list.Length()) list += ",";
211  list += Form("%s=", par.GetName());
212  if (par.IsString())
213  list += par.GetString();
214  else if (par.IsDouble())
215  list += Form("%g", par.GetDouble());
216  else if (par.IsInt())
217  list += Form("%d", par.GetInt());
218  }
219  return list;
220 }
221 
222 
223 
227 
229 {
230  //return the pointeur of the KVHashList where
231  //parameters are stored with their values
232  return (KVHashList*)&fList;
233 }
234 
235 
236 
240 
242 {
243  // Copy this to the nvl object.
244  // Any existing parameters will be destroyed
245 
246  TNamed::Copy(nvl);
247  KVNameValueList& _obj = (KVNameValueList&)nvl;
248  fList.Copy(_obj.fList);
249  _obj.fIgnoreBool = fIgnoreBool;
250 }
251 
252 
253 
257 
259 {
260  //Clear all the stored parameters
261  //Deletes the parameter objects if owner & opt!="nodelete"
262  fList.Clear(opt);
263 }
264 
265 
266 
272 
274 {
275  // Remove from list all parameters whose name matches the regular expression
276  // Examples:
277  // remove all parameters starting with "toto": TRegexp sel("^toto")
278  // remove all parameters with "toto" in name: TRegexp sel("toto")
279 
280  TList toBeRemoved;
281  Int_t np1 = GetNpar();
282  for (Int_t ii = 0; ii < np1; ii += 1) {
283  TString name = GetParameter(ii)->GetName();
284  if (name.Contains(sel)) toBeRemoved.Add(new TNamed(name.Data(), ""));
285  }
286  if (toBeRemoved.GetEntries()) {
287  TIter next(&toBeRemoved);
288  TNamed* tbr;
289  while ((tbr = (TNamed*)next())) RemoveParameter(tbr->GetName());
290  toBeRemoved.Delete();
291  }
292 }
293 
294 
295 
300 
301 void KVNameValueList::Print(Option_t* option) const
302 {
303  // Print stored parameters (name, and value)
304  // Option can be used to select type of parameters to print:
305  // option = "int", "double", or "string"
306 
307  if (!GetNpar()) return;
308 
310  cout << "KVNameValueList::" << GetName() << " : " << GetTitle() << " (" << this << ")" << endl;
312  for (Int_t ii = 0; ii < GetNpar(); ii += 1) {
313  GetParameter(ii)->ls(option);
314  }
316 }
317 
318 
319 
321 
323 {
324  if (TString(GetName()) != "") cout << GetName();
325  else cout << "KVNameValueList";
326  cout << " : ";
327  for (int i = 0; i < GetNpar(); ++i) {
328  cout << GetParameter(i)->GetName() << "=";
329  switch (GetParameter(i)->GetType()) {
331  cout << GetParameter(i)->GetDouble();
332  break;
334  cout << GetParameter(i)->GetInt();
335  break;
337  cout << GetParameter(i)->GetString();
338  break;
340  cout << boolalpha << GetParameter(i)->GetBool();
341  break;
342  }
343  if (i < GetNpar() - 1) cout << ",";
344  }
345  cout << endl;
346 }
347 
348 
349 
353 
355 {
356  //set if the KVNameValueList owns its objects or not
357  //by default it is owner
358  fList.SetOwner(enable);
359 }
360 
361 
362 
366 
368 {
369  //return kTRUE if the list owns its objects
370  //kFALSE if not
371  return fList.IsOwner();
372 }
373 
374 
375 
379 
381 {
382  // Compare the contents of two KVNameValueList
383  // Returns the number of same parameters (name and value)
384 
385  KVNameValueList* nvl = (KVNameValueList*)obj;
386  Int_t neq = 0;
387  Int_t np1 = GetNpar();
388  Int_t np2 = nvl->GetNpar();
389  for (Int_t ii = 0; ii < np1; ii += 1) {
390  for (Int_t jj = 0; jj < np2; jj += 1) {
391 
392  if (*(GetParameter(ii)) == *(GetParameter(jj))) neq += 1;
393  }
394  }
395  return neq;
396 
397 }
398 
399 
400 
403 
405 {
406  // add (or replace) a parameter with the same name, type & value as 'p'
407 
409  par ? par->Set(p.GetName(), p) : fList.Add(new KVNamedParameter(p));
410 
411 }
412 
413 
414 
418 
420 {
421  // Store a 64-bit integer in the list as two 32-bit parameters with
422  // names 'name_up' and 'name_lo'
423 
424  TString parname = name;
425  parname += "_hi";
426  SetValue(parname, (Int_t)(x >> 32));
427  parname = name;
428  parname += "_lo";
429  SetValue(parname, (Int_t)((x << 32) >> 32));
430 }
431 
432 
433 
437 
439 {
440  // Return a 64-bit integer stored as two 32-bit parameters with
441  // names 'name_up' and 'name_lo'
442 
443  ULong64_t lo, hi;
444  TString parname = name;
445  parname += "_lo";
446  lo = (UInt_t)GetIntValue(parname);
447  parname = name;
448  parname += "_hi";
449  hi = (UInt_t)GetIntValue(parname);
450  ULong64_t x = (ULong64_t)((hi << 32) + lo);
451  return x;
452 }
453 
454 
455 
459 
461 {
462  // Returns kTRUE if 'name' is stored as a 64-bit value i.e. if
463  // integer parameters 'name_lo' and 'name_hi' are defined
464 
465  TString parname_hi = name;
466  parname_hi += "_hi";
467  TString parname_lo = name;
468  parname_lo += "_lo";
469  return (HasIntParameter(parname_hi) && HasIntParameter(parname_lo));
470 }
471 
472 
473 
479 
481 {
482  // if a parameter with the same name & type as 'p' exists,
483  // add numerical value of p to value of parameter in list,
484  // or for strings we add to a comma-separated list of strings.
485  // otherwise, add a copy of p to list
486 
488  par ? par->Add(p) : fList.Add(new KVNamedParameter(p));
489 }
490 
491 
492 
495 
497 {
498  //return the parameter object with the asking name
499  return (KVNamedParameter*)fList.FindObject(name);
500 }
501 
502 
503 
506 
508 {
509  //return the parameter object with index idx
510  return (KVNamedParameter*)fList.At(idx);
511 }
512 
513 
514 
518 
520 {
521  //remove parameter from the list,
522  //Warning the TNamed object associated is deleted
523 
524  KVNamedParameter* par = FindParameter(name);
525  if (par) {
526  fList.Remove(par);
527  delete par;
528  }
529 }
530 
531 
532 
538 
540 {
541  //Check if there is a parameter with the asked name
542  //in the list
543  //kTRUE, parameter already present
544  //kFALSE, if not
545  return (FindParameter(name) != nullptr);
546 }
547 
548 
549 
554 
556 {
557  //return the position in the list of a given parameter
558  //using its name
559  //return -1 if no parameter with such name are present
560 
561  TObject* par = 0;
562  Int_t idx = 0;
563  TIter next(&fList);
564  while ((par = next())) {
565  if (!strcmp(par->GetName(), name)) return idx;
566  idx++;
567  }
568  Error("GetNameIndex", "Parameter \"%s\" not found, -1 returned", name);
569  return -1;
570 }
571 
572 
573 
579 
581 {
582  //return the name of the parameter store at the idx position
583  //in the list
584  //if the idx is greater than the number of stored parameters
585  //return empty string
586 
587  if (idx >= GetNpar()) {
588  Error("GetNameAt", "index has to be less than %d, empty string is returned", GetNpar());
589  return "";
590  }
591  return fList.At(idx)->GetName();
592 }
593 
594 
595 
600 
602 {
603  //return the value in TString format
604  //for a parameter using its name
605  //return string "-1" if no parameter with such name are present
606 
607  KVNamedParameter* par = FindParameter(name);
608  if (!par) {
609  Error("GetStringValue(const Char_t*)", "\"%s\" does not correspond to an existing parameter, default value \"-1\" is returned", name);
610  return "-1";
611  }
612  return par->GetTString();
613 }
614 
615 
616 
619 
621 {
622  //return the number of stored parameters
623  return fList.GetEntries();
624 }
625 
626 
627 
632 
634 {
635  //return the value in string format
636  //for a parameter using its position
637  //return -1 idx is greater than the number of stored parameters
638  static TString tmp("-1");
639  if (idx >= GetNpar()) {
640  Error("GetStringValue(Int_t)", "index has to be less than %d, \"-1\" is returned\n", GetNpar());
641  return tmp;
642  }
643  return GetParameter(idx)->GetTString();
644 }
645 
646 
647 
664 
666 {
667  // Read all name-value pairs in the TEnv format file and store in list.
668  // Clears any previously stored values.
669  //
670  // values are read as strings from the TEnv and we use
671  // TString::IsDigit, TString::IsFloat to decide whether to store
672  // them as integers, floats, or strings.
673  // booleans are recognized as: TRUE, FALSE, ON, OFF, YES, NO, OK, NOT
674  // (to disable this feature and read such values as strings, call
675  // SetIgnoreBool(kTRUE))
676  //
677  // Special case:
678  // if the parameter name contains the string NumberList
679  // then we store the value string as is, as in this case
680  // it is assumed to be the string representation of a
681  // KVNumberList (easily confused with floating point numbers)
682 
683  Clear();
684  KVEnv env_file;
685  Int_t status = env_file.ReadFile(filename, kEnvAll);
686  if (status == -1) {
687  Error("ReadEnvFile", "The file %s does not exist", filename);
688  return;
689  }
690  THashList* name_value_list = env_file.GetTable();
691  TIter next_nv(name_value_list);
692  TEnvRec* nv_pair;
693  while ((nv_pair = (TEnvRec*)next_nv())) {
694  TString parname(nv_pair->GetName());
695  if (parname == "KVNameValueList.Name") SetName(nv_pair->GetValue());
696  else if (parname == "KVNameValueList.Title") SetTitle(nv_pair->GetValue());
697  else if (parname.Contains("NumberList")) SetValue(parname, nv_pair->GetValue());
698  else {
699  TString parval(nv_pair->GetValue());
700  if (parval.IsDigit()) SetValue(parname, parval.Atoi());
701  else if (parval.IsFloat()) SetValue(parname, parval.Atof());
702  else {
703  TString PARVAL(parval);
704  PARVAL.ToUpper();
705  if (!fIgnoreBool && (PARVAL == "TRUE" || PARVAL == "FALSE" || PARVAL == "ON" || PARVAL == "OFF"
706  || PARVAL == "YES" || PARVAL == "NO" || PARVAL == "OK" || PARVAL == "NOT"))
707  SetValue(parname, (Bool_t)env_file.GetValue(parname, 0));
708  else SetValue(parname, parval);
709  }
710  }
711  }
712 }
713 
714 
715 
719 
721 {
722  // Put all name-value pairs in this list as a TEnv format.
723  // delete after use
724  KVEnv* envfile = new KVEnv();
725  envfile->SetValue("KVNameValueList.Name", GetName());
726  envfile->SetValue("KVNameValueList.Title", GetTitle());
727  WriteToEnv(envfile);
728  return envfile;
729 }
730 
731 
732 
735 
737 {
738  // Write all name-value pairs in this list as a TEnv format file.
739  KVEnv* envfile = ProduceEnvFile();
740  envfile->SetRcName(filename);
741  envfile->Save();
742  delete envfile;
743 }
744 
745 
746 
747 
749 
751 {
752  TIter it(nvl.GetList());
753  KVNamedParameter* par = 0;
754  while ((par = (KVNamedParameter*)it())) SetValue(*par);
755  return *this;
756 }
757 
758 
759 
764 
765 void KVNameValueList::WriteClass(const Char_t* classname, const Char_t* classdesc, const Char_t* base_class)
766 {
767  // Generate a class with member variables and Get/Set methods corresponding
768  // to the names and types of the parameters in the list
769  // For booleans we use Isxxxx/SetIsxxx
770 
771  KVClassFactory cf(classname, classdesc, base_class);
772  cf.AddGetSetMethods(*this);
773  cf.GenerateCode();
774 }
775 
776 
777 
783 
784 void KVNameValueList::SetFromEnv(TEnv* tenv, const TString& prefix)
785 {
786  // Update the values of any parameters in the KVNameValueList which are found
787  // in the TEnv, optionally using the given prefix.
788  // Example: if KVNameValueList contains a parameter "Legs" and if prefix="Large",
789  // then if the TEnv contains a value "Large.Legs", it will be used to update "Legs"
790 
791  for (int i = 0; i < GetNpar(); ++i) GetParameter(i)->Set(tenv, prefix);
792 }
793 
794 
795 
796 
800 
801 void KVNameValueList::WriteToEnv(TEnv* tenv, const TString& prefix)
802 {
803  // Write the values of all parameters in the KVNameValueList in the TEnv,
804  // optionally using the given prefix.
805 
806  for (int i = 0; i < GetNpar(); ++i) GetParameter(i)->WriteToEnv(tenv, prefix);
807 }
808 
809 
810 
815 
817 {
818  // Merge other list into this one.
819  // Any parameters in 'other' which do not exist in this one are added.
820  // Any parameters which exist in both have their values summed.
821 
822  for (int i = 0; i < other.GetNpar(); ++i) {
823  KVNamedParameter* np_other = other.GetParameter(i);
824  AddValue(*np_other);
825  }
826 }
827 
828 
829 
830 
831 
832 
833 
834 
835 
836 
837 
838 
int Int_t
unsigned int UInt_t
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
char Char_t
const Bool_t kFALSE
bool Bool_t
const Bool_t kTRUE
const char Option_t
kEnvAll
float type_of_call hi(const int &, const int &)
char * Form(const char *fmt,...)
Factory class for generating skeleton files for new classes.
void GenerateCode()
Generate header and implementation file for currently-defined class.
void AddGetSetMethods(const KVNameValueList &)
For each named parameter in the list, we add protected member variables with the name and type of the...
Extension of TEnv to allow the writing of comments in the file.
Definition: KVEnv.h:16
Extended version of ROOT THashList.
Definition: KVHashList.h:28
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
virtual void Print(Option_t *opt="") const
KVNamedParameter * GetParameter(Int_t idx) const
return the parameter object with index idx
virtual void ls(Option_t *opt="") const
Int_t GetIntValue(const Char_t *name) const
Bool_t HasValue64bit(const Char_t *name) const
void SetValue(const Char_t *name, value_type value)
virtual ~KVNameValueList()
Destructor.
Bool_t fIgnoreBool
do not convert "yes", "false", "on", etc. in TEnv file to boolean
Bool_t IsOwner() const
void RemoveParameter(const Char_t *name)
Int_t Compare(const TObject *nvl) const
void SetValue64bit(const Char_t *name, ULong64_t)
void SetFromEnv(TEnv *tenv, const TString &prefix="")
virtual void Clear(Option_t *opt="")
const Char_t * GetNameAt(Int_t idx) const
Int_t GetNpar() const
return the number of stored parameters
virtual void ReadEnvFile(const Char_t *filename)
virtual void WriteEnvFile(const Char_t *filename)
Write all name-value pairs in this list as a TEnv format file.
Int_t GetNameIndex(const Char_t *name) const
void Merge(const KVNameValueList &)
KVNameValueList()
Default constructor.
KVNamedParameter * FindParameter(const Char_t *name) const
return the parameter object with the asking name
KVNameValueList operator+=(const KVNameValueList &nvl)
KVNameValueList & operator=(const KVNameValueList &)
KVHashList fList
list of KVNamedParameter objects
Bool_t HasIntParameter(const Char_t *name) const
void SetOwner(Bool_t enable=kTRUE)
virtual KVEnv * ProduceEnvFile()
void WriteClass(const Char_t *classname, const Char_t *classdesc, const Char_t *base_class="")
ULong64_t GetValue64bit(const Char_t *name) const
KVString Get() const
bool Set(const KVString &)
Bool_t HasParameter(const Char_t *name) const
void AddValue(const KVNamedParameter &p)
KVHashList * GetList() const
TString GetTStringValue(const Char_t *name) const
void Copy(TObject &nvl) const
virtual void ClearSelection(TRegexp &)
void WriteToEnv(TEnv *tenv, const TString &prefix="")
A generic named parameter storing values of different types.
const Char_t * GetString() const
void Set(const char *, const char *)
Int_t GetInt() const
void Add(const KVNamedParameter &p)
Double_t GetDouble() const
virtual void ls(Option_t *opt="") const
void WriteToEnv(TEnv *, const TString &p="")
Write parameter in TEnv, using optional prefix p as "p.[name]".
TString GetTString() const
Bool_t GetBool() const
virtual void Copy(TObject &obj) const
virtual void SetOwner(Bool_t enable=kTRUE)
virtual void Clear(Option_t *option="")
virtual TObject * At(Int_t idx) const
virtual void Add(TObject *obj)
virtual TObject * Remove(TObject *obj)
Remove object from list.
virtual TObject * FindObject(const char *name) const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:72
void Begin(TString delim) const
Definition: KVString.cpp:565
Bool_t End() const
Definition: KVString.cpp:634
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition: KVString.cpp:695
virtual Int_t GetEntries() const
Bool_t IsOwner() const
const char * GetName() const
const char * GetValue() const
virtual const char * GetValue(const char *name, const char *dflt) const
virtual void SetRcName(const char *name)
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=nullptr)
virtual void Save()
THashList * GetTable() const
virtual void Add(TObject *obj)
virtual void Delete(Option_t *option="")
virtual const char * GetName() const
virtual void Copy(TObject &named) const
virtual void SetTitle(const char *title="")
virtual const char * GetTitle() const
virtual void SetName(const char *name)
virtual const char * GetName() const
virtual void Error(const char *method, const char *msgfmt,...) const
static Int_t IncreaseDirLevel()
static void IndentLevel()
static Int_t DecreaseDirLevel()
Ssiz_t Length() const
Int_t Atoi() const
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Double_t Atof() const
Bool_t IsFloat() const
Bool_t IsDigit() const
void ToUpper()
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
const char * Data() const
TString & Remove(EStripType s, char c)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
unsigned long long ULong64_t
Double_t x[n]
Type GetType(const std::string &Name)
auto * l