source: Sophya/trunk/SophyaLib/BaseTools/dvlist.cc@ 754

Last change on this file since 754 was 754, checked in by ansari, 26 years ago

Restruction de Sophya en modules plus petit (TArray , SkyMap, HiStats, ...)

Reza 2/3/2000

File size: 11.9 KB
Line 
1// Classe Dynamic Variable List (DVList) de PEIDA
2// R. Ansari 1997
3// LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA
4
5#include "machdefs.h"
6#include <stdlib.h>
7#include <stdio.h>
8
9#include "dvlist.h"
10#include "strutil.h"
11
12//++
13// Class DVList
14// Lib Outils++
15// include dvlist.h
16//
17// Cette classe permet de gérer une ensemble de variables (ou paramètres)
18// pouvant être définies dynamiquement à l'execution. Le nom des
19// variables ne doit pas contenir de blancs ("<espace>") et est
20// limité à 64 caractères maximum. Cette classe
21// offre la possibilité de sauvegarder l'ensemble
22// des variables (Nom, Type, Valeur) dans un fichier, ou de
23// recréer l'objet DVList et l'ensemble de ses variables à
24// partir d'un fichier (Objet PPersist). Une zone commentaire (max=320 c.)
25// est associée à chaque objet DVList, accessible à travers
26// la méthode "Comment()". Les objets de cette classe sont
27// en particulier destinés à être inclus dans d'autres objets
28// PPersist plus complexes. La classe DVList gère des
29// variables de type entier ("int_8"), réél double précision ("r_8")
30// et de type chaine de caracteres ("string, char*", maxi 30 caracteres ).
31// Une classe intermédiaire (*MuTyV*) est utilisée pour représenter une
32// variable et fournit les services de conversion entre les différents types.
33//--
34//--
35//++
36// Links Parents
37// PPersist
38//--
39
40char MuTyV::myStrBuf[64]; // Declare static ds le .h
41
42static MuTyV ddvdum(-9.e19);
43
44
45//++
46// Titre Constructeurs
47//--
48
49//++
50// DVList()
51// Constructeur par défaut
52// DVList(DVList& cfd)
53// Constructeur par copie. Le nouvel objet est une copie complète de "cfd"
54// DVList(char* flnm)
55// Constructeur avec initialisation à partir du contenu du fichier (PPF)
56// "flnm". Le fichier doit avoir été créé par la méthode "Write()"
57//--
58
59/* --Methode-- */
60DVList::DVList()
61{
62comment = "";
63}
64
65/* --Methode-- */
66DVList::DVList(const DVList& dvl)
67{
68Merge(dvl);
69}
70
71/* --Methode-- */
72DVList::DVList(char *flnm)
73{
74PInPersist s(flnm);
75ObjFileIO<DVList> fiodvl(this);
76fiodvl.Read(s);
77}
78
79
80/* --Methode-- */
81DVList::~DVList()
82{
83}
84
85//++
86// Titre Gestion des variables et opérateurs
87//--
88
89//++
90// void Clear()
91// Supprime la définition de toutes les variables de l'objet.
92// DVList& Merge(const DVList& lv)
93// Fusionne l'objet avec la liste des variables de l'objet "lv"
94// DVList& operator= (const DVList& cofr)
95// Remplace la liste des variables de l'objet par celle de l'objet "cofr".
96//--
97
98/* --Methode-- */
99DVList& DVList::operator= (const DVList& dvl)
100{
101Clear();
102return(Merge(dvl));
103}
104
105
106/* --Methode-- */
107void DVList::Clear()
108{
109mvlist.erase(mvlist.begin(), mvlist.end());
110comment = "";
111}
112
113/* --Methode-- */
114DVList& DVList::Merge(const DVList& dvl)
115{
116ValList::const_iterator it;
117for(it = dvl.mvlist.begin(); it != dvl.mvlist.end(); it++)
118 {
119 switch ((*it).second.elval.typ)
120 {
121 case 'I' :
122 SetI((*it).first, (*it).second.elval.mtv.iv);
123 break;
124 case 'D' :
125 SetD((*it).first, (*it).second.elval.mtv.dv);
126 break;
127 case 'S' :
128 SetS((*it).first, (*it).second.elval.mtv.strv);
129 break;
130 default :
131 break;
132 }
133 }
134comment = comment + "\n" + dvl.comment;
135return(*this);
136}
137
138
139//++
140// int_8 GetI(string const& key, int_8 def=-1)
141// r_8 GetD(string const& key, r_8 def=-9.e19)
142// string GetS(string const& key, char* def="")
143// Retourne la valeur de la variable de nom "key" et de type entier, réél,
144// chaine de caracteres.
145// Si la variable n'existe pas, la valeur par défaut "def" est renvoyée.
146// string GetComment(string const& key)
147// Retourne le commentaire associé à la variable de nom "key".
148//--
149
150/* --Methode-- */
151int_8 DVList::GetI(string const& key, int_8 def)
152{
153ValList::iterator it = mvlist.find(key);
154if (it == mvlist.end()) return(def);
155if ( (*it).second.elval.typ != 'I') return(def);
156return((*it).second.elval.mtv.iv);
157}
158
159/* --Methode-- */
160r_8 DVList::GetD(string const& key, r_8 def)
161{
162ValList::iterator it = mvlist.find(key);
163if (it == mvlist.end()) return(def);
164if ( (*it).second.elval.typ != 'D') return(def);
165return((*it).second.elval.mtv.dv);
166}
167
168/* --Methode-- */
169string DVList::GetS(string const& key, char* def)
170{
171ValList::iterator it = mvlist.find(key);
172if (it == mvlist.end()) return(def);
173if ( (*it).second.elval.typ != 'S') return(def);
174return((*it).second.elval.mtv.strv);
175}
176
177/* --Methode-- */
178string DVList::GetComment(string const& key)
179{
180ValList::iterator it = mvlist.find(key);
181if (it == mvlist.end()) return("");
182return((*it).second.elcomm);
183}
184
185//++
186// void SetI(string const& key, int_8 val)
187// void SetD(string const& key, r_8 val)
188// void SetS(string const& key, char* val)
189// void SetS(string const& key, string val)
190// Crée la variable de nom "key", de type entier, double, string et
191// lui attribue la valeur "val". Si une variable du même nom existe,
192// sa valeur et eventuellement son type sont modifiés. Les noms de
193// variables ne doivent pas contenir de caractères spéciaux,
194// en particulier pas de CR/LF.
195// void SetComment(string const& key, string const& comm)
196// Modifie le commentaire associé à la variable de nom "key", si
197// celle-ci existe. Le texte du commentaire ne doit pas contenir
198// de caractères spéciaux, et en particulier pas de CR/LF.
199//--
200
201/* --Methode-- */
202void DVList::SetI(string const& key, int_8 val)
203{
204Get(key) = (int_8)val;
205}
206
207/* --Methode-- */
208void DVList::SetD(string const& key, r_8 val)
209{
210Get(key) = (r_8)val;
211}
212
213/* --Methode-- */
214void DVList::SetS(string const& key, char const* val)
215{
216MuTyV div(val);
217Get(key) = div;
218}
219
220/* --Methode-- */
221void DVList::SetS(string const& key, string val)
222{
223MuTyV div(val);
224Get(key) = div;
225}
226
227/* --Methode-- */
228void DVList::SetComment(string const& key, string const& comm)
229{
230ValList::iterator it = mvlist.find(key);
231if (it == mvlist.end()) return;
232(*it).second.elcomm = comm;
233}
234
235//++
236// MuTyV& Get(string const& key)
237// Renvoie une référence sur l'objet "MuTyV" de la liste avec le nom "key".
238// Si cet objet (variable) n'existe pas, il est créé.
239// MuTyV& operator() (string const& key)
240// MuTyV& operator[] (string const& key)
241//
242// Renvoie la variable de nom "key". Equivalent à "Get(key)".
243// string& Comment()
244// Renvoie une référence sur le champ commentaire de l'objet.
245//--
246
247/* --Methode-- */
248MuTyV& DVList::Get(string const& key)
249{
250size_t l = key.length();
251if ( (l < 1) || (key.find_first_of(" ") < l) ) return(ddvdum);
252// dvlElement xxx = {(int_8)0 , ""}; marche pas sur mac/CW (!) - cf DY
253dvlElement xxx; xxx.elval = (int_8)0; xxx.elcomm = "";
254ValList::iterator it = mvlist.find(key);
255if (it == mvlist.end()) mvlist[key] = xxx;
256it = mvlist.find(key);
257if (it == mvlist.end()) return(ddvdum);
258else return((*it).second.elval);
259}
260
261//++
262// Titre Entrée-Sortie
263//--
264
265//++
266// void Print()
267// Imprime (sur "cout") la liste des variables et leurs valeurs.
268// void Print(ostream& os)
269// Imprime sur le flot "os" la liste des variables et leurs valeurs.
270// ostream& operator << (ostream& s, DVList& dvl)
271// sortie sur flot "s" (Appel a "Print(s)").
272// void Write(string const& fn)
273// Ecriture d'un fichier PPersist de nom "fn"
274// void Read(string const& fn)
275// Lecture d'un fichier PPersist de nom "fn"
276//--
277
278
279/* --Methode-- */
280void DVList::Print(ostream& os) const
281{
282os << "DVList::Print() - NVar= " << (int)mvlist.size() << "\n";
283if (comment.length() > 0) os << comment << endl;
284char buff[256];
285ValList::const_iterator it;
286for(it = mvlist.begin(); it != mvlist.end(); it++) {
287 switch ((*it).second.elval.typ)
288 {
289 case 'I' :
290 sprintf(buff, "%s = %d (int) %s\n", (*it).first.substr(0,64).c_str(),
291 (*it).second.elval.mtv.iv, (*it).second.elcomm.substr(0,128).c_str());
292 break;
293 case 'D' :
294 sprintf(buff, "%s = %.20g (double) %s\n", (*it).first.substr(0,64).c_str(),
295 (*it).second.elval.mtv.dv, (*it).second.elcomm.substr(0,128).c_str());
296 break;
297 case 'S' :
298 sprintf(buff, "%s = %s (string) %s\n", (*it).first.substr(0,64).c_str(),
299 (*it).second.elval.mtv.strv, (*it).second.elcomm.substr(0,128).c_str());
300 break;
301 default :
302 break;
303 }
304 os << (string)buff;
305 }
306os << endl;
307}
308
309
310//++
311// Titre Exemples
312// Utilisation des objets *MuTyV* :
313//| MuTyV mvu; // Declaration d'une variable
314//| mvu = 60; // mvu est de type entier (= 60)
315//| mvu = 66.6; // et double (= 66.6) maintenant ...
316//| MuTyV mvi(14); // On construit une variable entiere = 14
317//| r_4 x = mvi; // x vaut 14.0
318//| MuTyV mvd(44.4); // Variable double = 44.4
319//| int k = mvd; // k vaut 44
320//| MuTyV mvs("Bonjour, Ca va ?"); // Variable chaine de caracteres
321//| string s = mvs; // s vaut "Bonjour, Ca va ?"
322// Utilisation des *DVList* :
323//| DVList dvl;
324//| dvl("toto") = 14;
325//| dvl("titi") = 25.5;
326//| dvl("tata") = "Bonjour, Ca va ?";
327// Majuscules et minuscules sont differenciees pour les noms, pas de blanc ...
328//| dvl("hello") = 88;
329//| dvl("Hello") = 77.77;
330//| dvl.Comment() = "Test d'objet DVList, avec variables hello, Hello ";
331//| dvl.Write("dvlist.ppf");
332// Plus loin, ou dans un autre programme, on relit le fichier fabrique plus haut
333//| DVList dvlr("dvlist.ppf");
334//| int k = dvlr["toto"] ; // k = 14
335//| r_8 b = dvlr["titi"] ; // b = 25.5
336//| string s = dvlr["tata"] ; // s = "Bonjour, Ca va ?"
337//| r_4 c = dvlr["Hello"] ; // c = 77.77
338//| int l = dvlr["Hello"] ; // l = 77
339//| int m = dvlr["hello"] ; // m = 88
340//--
341
342
343//----------------------------------------------------------
344// Classe pour la gestion de persistance
345// ObjFileIO<DVList>
346//----------------------------------------------------------
347
348/* --Methode-- */
349void ObjFileIO<DVList>::WriteSelf(POutPersist& s) const
350{
351char buf[512];
352
353int lc = dobj->Comment().length();
354if (lc > 511) lc = 511;
355if (lc > 0) {
356 sprintf(buf,"Comment: ( %6d ) ", lc);
357 s.PutLine(buf);
358 s.PutBytes(dobj->Comment().c_str(), lc);
359 }
360s.PutLine("----Variable-List---------------");
361DVList::ValList::const_iterator it;
362for(it = dobj->Begin(); it != dobj->End(); it++) {
363 switch ((*it).second.elval.typ) {
364 case 'I' :
365 sprintf(buf,"I %s %d", (*it).first.substr(0,64).c_str(), (*it).second.elval.mtv.iv );
366 s.PutLine(buf);
367 break;
368 case 'D' :
369 sprintf(buf,"D %s %.20g", (*it).first.substr(0,64).c_str(), (*it).second.elval.mtv.dv );
370 s.PutLine(buf);
371 break;
372 case 'S' :
373 sprintf(buf,"S %s %s", (*it).first.substr(0,64).c_str(), (*it).second.elval.mtv.strv );
374 s.PutLine(buf);
375 break;
376 default :
377 break;
378 }
379// Ecriture eventuelle du commentaire associe
380 if ((*it).second.elcomm.length() > 0) {
381 sprintf(buf,"# %s", (*it).second.elcomm.substr(0,256).c_str());
382 s.PutLine(buf);
383 }
384}
385
386s.PutLine("ZZZZZ--End-of-Varible-List------");
387}
388
389/* --Methode-- */
390void ObjFileIO<DVList>::ReadSelf(PInPersist& s)
391{
392char buf[512];
393int_8 j,iv;
394r_8 dv;
395bool ok=true;
396buf[0] = '\0';
397dobj->Clear();
398
399s.GetLine(buf, 511); // Pour lire les "------- "
400if (buf[0] != '-') { // Il y a un champ commentaire a lire
401 buf[18] ='\0';
402 int lc = atoi(buf+11);
403 if (lc > 511) {
404 cerr << "DVList::ReadSelf() Pb/Bug ?? CommentLength= " << lc << endl;
405 lc = 511;
406 }
407 s.GetBytes(buf, lc);
408 buf[lc] ='\0';
409 dobj->Comment() = buf;
410 }
411
412string key="";
413while(ok) {
414 s.GetLine(buf, 511);
415 buf[511] = '\0';
416 if (strncmp(buf,"ZZZZZ",5) == 0) { ok=false; break; }
417 if (buf[0] == '#') {
418 dobj->SetComment(key, buf+2);
419 continue;
420 }
421 j = posc(buf+2, ' ')+2;
422 buf[j] = '\0';
423 switch (buf[0]) {
424 case 'I' :
425 iv = (int_8)atol(buf+j+1);
426 key = buf+2;
427 dobj->SetI(key, iv);
428 break;
429 case 'D' :
430 dv = atof(buf+j+1);
431 key = buf+2;
432 dobj->SetD(key, dv);
433 break;
434 case 'S' :
435 key = buf+2;
436 dobj->SetS(key, buf+j+1);
437 break;
438 default :
439 break;
440 }
441 }
442}
443
444#ifdef __CXX_PRAGMA_TEMPLATES__
445#pragma define_template ObjFileIO<DVList>
446#endif
447
448#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
449template class ObjFileIO<DVList>;
450#endif
Note: See TracBrowser for help on using the repository browser.