source: Sophya/trunk/SophyaLib/NTools/dvlist.cc@ 718

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

Ajout commentaire/variable ds DVList - Remplacement float/double par r_4 r_8
Ajout classe XNTuple (importe/adapte depuis PEIDA) - Reza 7 Fev 2000

File size: 11.8 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);
252ValList::iterator it = mvlist.find(key);
253dvlElement xxx = {(int_8)0 , ""};
254if (it == mvlist.end()) mvlist[key] = xxx;
255it = mvlist.find(key);
256if (it == mvlist.end()) return(ddvdum);
257else return((*it).second.elval);
258}
259
260//++
261// Titre Entrée-Sortie
262//--
263
264//++
265// void Print()
266// Imprime (sur "cout") la liste des variables et leurs valeurs.
267// void Print(ostream& os)
268// Imprime sur le flot "os" la liste des variables et leurs valeurs.
269// ostream& operator << (ostream& s, DVList& dvl)
270// sortie sur flot "s" (Appel a "Print(s)").
271// void Write(string const& fn)
272// Ecriture d'un fichier PPersist de nom "fn"
273// void Read(string const& fn)
274// Lecture d'un fichier PPersist de nom "fn"
275//--
276
277
278/* --Methode-- */
279void DVList::Print(ostream& os) const
280{
281os << "DVList::Print() - NVar= " << (int)mvlist.size() << "\n";
282if (comment.length() > 0) os << comment << endl;
283char buff[256];
284ValList::const_iterator it;
285for(it = mvlist.begin(); it != mvlist.end(); it++) {
286 switch ((*it).second.elval.typ)
287 {
288 case 'I' :
289 sprintf(buff, "%s = %d (int) %s\n", (*it).first.substr(0,64).c_str(),
290 (*it).second.elval.mtv.iv, (*it).second.elcomm.substr(0,128).c_str());
291 break;
292 case 'D' :
293 sprintf(buff, "%s = %.20g (double) %s\n", (*it).first.substr(0,64).c_str(),
294 (*it).second.elval.mtv.dv, (*it).second.elcomm.substr(0,128).c_str());
295 break;
296 case 'S' :
297 sprintf(buff, "%s = %s (string) %s\n", (*it).first.substr(0,64).c_str(),
298 (*it).second.elval.mtv.strv, (*it).second.elcomm.substr(0,128).c_str());
299 break;
300 default :
301 break;
302 }
303 os << (string)buff;
304 }
305os << endl;
306}
307
308
309//++
310// Titre Exemples
311// Utilisation des objets *MuTyV* :
312//| MuTyV mvu; // Declaration d'une variable
313//| mvu = 60; // mvu est de type entier (= 60)
314//| mvu = 66.6; // et double (= 66.6) maintenant ...
315//| MuTyV mvi(14); // On construit une variable entiere = 14
316//| r_4 x = mvi; // x vaut 14.0
317//| MuTyV mvd(44.4); // Variable double = 44.4
318//| int k = mvd; // k vaut 44
319//| MuTyV mvs("Bonjour, Ca va ?"); // Variable chaine de caracteres
320//| string s = mvs; // s vaut "Bonjour, Ca va ?"
321// Utilisation des *DVList* :
322//| DVList dvl;
323//| dvl("toto") = 14;
324//| dvl("titi") = 25.5;
325//| dvl("tata") = "Bonjour, Ca va ?";
326// Majuscules et minuscules sont differenciees pour les noms, pas de blanc ...
327//| dvl("hello") = 88;
328//| dvl("Hello") = 77.77;
329//| dvl.Comment() = "Test d'objet DVList, avec variables hello, Hello ";
330//| dvl.Write("dvlist.ppf");
331// Plus loin, ou dans un autre programme, on relit le fichier fabrique plus haut
332//| DVList dvlr("dvlist.ppf");
333//| int k = dvlr["toto"] ; // k = 14
334//| r_8 b = dvlr["titi"] ; // b = 25.5
335//| string s = dvlr["tata"] ; // s = "Bonjour, Ca va ?"
336//| r_4 c = dvlr["Hello"] ; // c = 77.77
337//| int l = dvlr["Hello"] ; // l = 77
338//| int m = dvlr["hello"] ; // m = 88
339//--
340
341
342//----------------------------------------------------------
343// Classe pour la gestion de persistance
344// ObjFileIO<DVList>
345//----------------------------------------------------------
346
347/* --Methode-- */
348void ObjFileIO<DVList>::WriteSelf(POutPersist& s) const
349{
350char buf[512];
351
352int lc = dobj->Comment().length();
353if (lc > 511) lc = 511;
354if (lc > 0) {
355 sprintf(buf,"Comment: ( %6d ) ", lc);
356 s.PutLine(buf);
357 s.PutBytes(dobj->Comment().c_str(), lc);
358 }
359s.PutLine("----Variable-List---------------");
360DVList::ValList::const_iterator it;
361for(it = dobj->Begin(); it != dobj->End(); it++) {
362 switch ((*it).second.elval.typ) {
363 case 'I' :
364 sprintf(buf,"I %s %d", (*it).first.substr(0,64).c_str(), (*it).second.elval.mtv.iv );
365 s.PutLine(buf);
366 break;
367 case 'D' :
368 sprintf(buf,"D %s %.20g", (*it).first.substr(0,64).c_str(), (*it).second.elval.mtv.dv );
369 s.PutLine(buf);
370 break;
371 case 'S' :
372 sprintf(buf,"S %s %s", (*it).first.substr(0,64).c_str(), (*it).second.elval.mtv.strv );
373 s.PutLine(buf);
374 break;
375 default :
376 break;
377 }
378// Ecriture eventuelle du commentaire associe
379 if ((*it).second.elcomm.length() > 0) {
380 sprintf(buf,"# %s", (*it).second.elcomm.substr(0,256).c_str());
381 s.PutLine(buf);
382 }
383}
384
385s.PutLine("ZZZZZ--End-of-Varible-List------");
386}
387
388/* --Methode-- */
389void ObjFileIO<DVList>::ReadSelf(PInPersist& s)
390{
391char buf[512];
392int_8 j,iv;
393r_8 dv;
394bool ok=true;
395buf[0] = '\0';
396dobj->Clear();
397
398s.GetLine(buf, 511); // Pour lire les "------- "
399if (buf[0] != '-') { // Il y a un champ commentaire a lire
400 buf[18] ='\0';
401 int lc = atoi(buf+11);
402 if (lc > 511) {
403 cerr << "DVList::ReadSelf() Pb/Bug ?? CommentLength= " << lc << endl;
404 lc = 511;
405 }
406 s.GetBytes(buf, lc);
407 buf[lc] ='\0';
408 dobj->Comment() = buf;
409 }
410
411string key="";
412while(ok) {
413 s.GetLine(buf, 511);
414 buf[511] = '\0';
415 if (strncmp(buf,"ZZZZZ",5) == 0) { ok=false; break; }
416 if (buf[0] == '#') {
417 dobj->SetComment(key, buf+2);
418 continue;
419 }
420 j = posc(buf+2, ' ')+2;
421 buf[j] = '\0';
422 switch (buf[0]) {
423 case 'I' :
424 iv = (int_8)atol(buf+j+1);
425 key = buf+2;
426 dobj->SetI(key, iv);
427 break;
428 case 'D' :
429 dv = atof(buf+j+1);
430 key = buf+2;
431 dobj->SetD(key, dv);
432 break;
433 case 'S' :
434 key = buf+2;
435 dobj->SetS(key, buf+j+1);
436 break;
437 default :
438 break;
439 }
440 }
441}
442
443#ifdef __CXX_PRAGMA_TEMPLATES__
444#pragma define_template ObjFileIO<DVList>
445#endif
446
447#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
448template class ObjFileIO<DVList>;
449#endif
Note: See TracBrowser for help on using the repository browser.