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

Last change on this file since 1386 was 1386, checked in by ansari, 25 years ago

Correction erreur introduite par DY - Reza 17/1/2000

File size: 17.6 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 SysTools
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
40
41static MuTyV ddvdum(-9.e19);
42
43
44/*!
45 \class SOPHYA::DVList
46 \ingroup SysTools
47 This class can be used to construct list of values associated with names.
48 Variables names should not contain space characters and is limited to 64
49 characters. The DVList class uses \b SOPHYA::MuTyV objects to hold values
50 of type string, integer (\b int_8) or float (\b r_8). A comment string
51 can be associated with each variable name. A global comment string
52 can be attached to the DVList object. DVList objects can conveniently be
53 used to represent FITS headers. The class \b SOPHYA::ObjFileIO<DVList>
54 handles serialisation for DVList. (See SOPHYA::PPersist ).
55
56 // ------- Using DVList objects ------
57 DVList dvl;
58 dvl("toto") = 14; // Integer type value (=14) named toto
59 dvl("titi") = 25.5; // float type value (=25.5) named titi
60 dvl("tata") = "Bonjour !"; // string type value (="Bonjour !") named tata
61 // Upper and lower case letters are distinguished
62 dvl("hello") = 88;
63 dvl("Hello") = 77.77;
64 dvl.Comment() = "DVList test object, with values named hello, Hello ";
65 // Saving the dvl object into a PPF file
66 POutStream os("dvl.ppf");
67 os << dvl;
68 // later on ...
69 DVList dvlr;
70 PInStream is("dvl.ppf");
71 is << dvlr;
72 int k = dvlr["toto"] ; // k = 14
73 r_8 b = dvlr["titi"] ; // b = 25.5
74 string s = dvlr["tata"] ; // s = "Bonjour !"
75 int m = dvlr["hello"] ; // m = 88
76
77 \endcode
78 \sa SOPHYA::ObjFileIO<DVList>
79*/
80
81//++
82// Titre Constructeurs
83//--
84
85//++
86// DVList()
87// Constructeur par défaut
88// DVList(DVList& cfd)
89// Constructeur par copie. Le nouvel objet est une copie complète de "cfd"
90// DVList(char* flnm)
91// Constructeur avec initialisation à partir du contenu du fichier (PPF)
92// "flnm". Le fichier doit avoir été créé par la méthode "Write()"
93//--
94
95/* --Methode-- */
96/*! Default constructor */
97DVList::DVList()
98{
99comment = "";
100}
101
102/* --Methode-- */
103/*! copy constructor */
104DVList::DVList(const DVList& dvl)
105{
106Merge(dvl);
107}
108
109/* --Methode-- */
110/*! Copy constructor - Object initialized using the PPF file \b flnm */
111DVList::DVList(char *flnm)
112{
113PInPersist s(flnm);
114ObjFileIO<DVList> fiodvl(this);
115fiodvl.Read(s);
116}
117
118
119/* --Methode-- */
120DVList::~DVList()
121{
122}
123
124//++
125// Titre Gestion des variables et opérateurs
126//--
127
128//++
129// void Clear()
130// Supprime la définition de toutes les variables de l'objet.
131// DVList& Merge(const DVList& lv)
132// Fusionne l'objet avec la liste des variables de l'objet "lv"
133// DVList& operator= (const DVList& cofr)
134// Remplace la liste des variables de l'objet par celle de l'objet "cofr".
135//--
136
137/* --Methode-- */
138/*! Copy operator - Replaces the variables list with the list from \b dvl */
139DVList& DVList::operator= (const DVList& dvl)
140{
141Clear();
142return(Merge(dvl));
143}
144
145
146/* --Methode-- */
147/*! Resets the object and clears the variable list and global comment */
148void DVList::Clear()
149{
150mvlist.erase(mvlist.begin(), mvlist.end());
151comment = "";
152}
153
154/* --Methode-- */
155/*! Appends the values from the object \b dvl to the objects list */
156DVList& DVList::Merge(const DVList& dvl)
157{
158ValList::const_iterator it;
159for(it = dvl.mvlist.begin(); it != dvl.mvlist.end(); it++)
160 {
161 switch ((*it).second.elval.Type())
162 {
163 case MuTyV::MTVInteger :
164 SetI((*it).first, (*it).second.elval.iv);
165 break;
166 case MuTyV::MTVFloat :
167 SetD((*it).first, (*it).second.elval.dv);
168 break;
169 case MuTyV::MTVComplex :
170 SetZ((*it).first, complex<r_8>((*it).second.elval.dv, (*it).second.elval.dv_im));
171 break;
172 case MuTyV::MTVString :
173 SetS((*it).first, *((*it).second.elval.strv));
174 break;
175 default :
176 break;
177 }
178 SetComment((*it).first, (*it).second.elcomm);
179 }
180comment = comment + "\n" + dvl.comment;
181return(*this);
182}
183
184
185//++
186// int_8 GetI(string const& key, int_8 def=-1)
187// r_8 GetD(string const& key, r_8 def=-9.e19)
188// string GetS(string const& key, char* def="")
189// Retourne la valeur de la variable de nom "key" et de type entier, réél,
190// chaine de caracteres.
191// Si la variable n'existe pas, la valeur par défaut "def" est renvoyée.
192// string GetComment(string const& key)
193// Retourne le commentaire associé à la variable de nom "key".
194//--
195
196/* --Methode-- */
197/*! Returns the value corresponding to name \b key, converted to integer
198 Default value \b def is returned if name \b key not found */
199int_8 DVList::GetI(string const& key, int_8 def) const
200{
201ValList::const_iterator it = mvlist.find(key);
202if (it == mvlist.end()) return(def);
203return( (int_8)((*it).second.elval) );
204}
205
206/* --Methode-- */
207/*! Returns the value corresponding to name \b key, converted to double
208 Default value \b def is returned if name \b key not found */
209r_8 DVList::GetD(string const& key, r_8 def) const
210{
211ValList::const_iterator it = mvlist.find(key);
212if (it == mvlist.end()) return(def);
213return( (r_8)((*it).second.elval) );
214}
215
216/* --Methode-- */
217/*! Returns the value corresponding to name \b key, converted to complex
218 Default value \b def is returned if name \b key not found */
219complex<r_8> DVList::GetZ(string const& key, complex<r_8> def) const
220{
221ValList::const_iterator it = mvlist.find(key);
222if (it == mvlist.end()) return(def);
223#if defined(__GNUG__)
224complex<r_8> z;
225z = (*it).second.elval;
226return(z);
227#else
228return( (complex<r_8>)(*it).second.elval );
229#endif
230}
231
232/* --Methode-- */
233/*! Returns the value corresponding to name \b key, converted to string
234 Default value \b def is returned if name \b key not found */
235string DVList::GetS(string const& key, char* def) const
236{
237ValList::const_iterator it = mvlist.find(key);
238if (it == mvlist.end()) return(def);
239return( (string)((*it).second.elval) );
240}
241
242/* --Methode-- */
243/*! Returns the comment associated with name \b key */
244string DVList::GetComment(string const& key) const
245{
246ValList::const_iterator it = mvlist.find(key);
247if (it == mvlist.end()) return("");
248return((*it).second.elcomm);
249}
250
251//++
252// void SetI(string const& key, int_8 val)
253// void SetD(string const& key, r_8 val)
254// void SetZ(string const& key, complex<r_8> val)
255// void SetS(string const& key, char* val)
256// void SetS(string const& key, string val)
257// Crée la variable de nom "key", de type entier, double, complexe, string et
258// lui attribue la valeur "val". Si une variable du même nom existe,
259// sa valeur et eventuellement son type sont modifiés. Les noms de
260// variables ne doivent pas contenir de caractères spéciaux,
261// en particulier pas de CR/LF.
262// void SetComment(string const& key, string const& comm)
263// Modifie le commentaire associé à la variable de nom "key", si
264// celle-ci existe. Le texte du commentaire ne doit pas contenir
265// de caractères spéciaux, et en particulier pas de CR/LF.
266//--
267
268/* --Methode-- */
269/*! Removes the definition and value associated with the name \b key.
270 Return \c true if the \b key is found in the list, \c false otherwise. */
271bool DVList::DeleteKey(string const& key)
272{
273ValList::iterator it = mvlist.find(key);
274if (it == mvlist.end()) return(false);
275mvlist.erase(it);
276return(true);
277}
278
279/* --Methode-- */
280/*! Return \c true if the \b key is found in the list, \c false otherwise. */
281bool DVList::HasKey(string const& key) const
282{
283ValList::const_iterator it = mvlist.find(key);
284if (it == mvlist.end()) return(false);
285return(true);
286}
287
288
289/* --Methode-- */
290/*! Appends or sets the integer value \b val in the list with name \b key */
291void DVList::SetI(string const& key, int_8 val)
292{
293Get(key) = (int_8)val;
294}
295
296/* --Methode-- */
297void DVList::SetD(string const& key, r_8 val)
298/*! Appends or sets the double value \b val in the list with name \b key */
299{
300Get(key) = (r_8)val;
301}
302
303/* --Methode-- */
304void DVList::SetZ(string const& key, complex<r_8> val)
305/*! Appends or sets the complex value \b val in the list with name \b key */
306{
307Get(key) = val;
308}
309
310/* --Methode-- */
311/*! Appends or sets the string value \b val in the list with name \b key */
312void DVList::SetS(string const& key, char const* val)
313{
314MuTyV div(val);
315Get(key) = div;
316}
317
318/* --Methode-- */
319/*! Appends or sets the string value \b val in the list with name \b key */
320void DVList::SetS(string const& key, string const& val)
321{
322MuTyV div(val);
323Get(key) = div;
324}
325
326/* --Methode-- */
327/*! Assigns the comment \b comm with the name \b key .
328 Does nothing if the entry with name is not present in the list */
329void DVList::SetComment(string const& key, string const& comm)
330{
331ValList::iterator it = mvlist.find(key);
332if (it == mvlist.end()) return;
333(*it).second.elcomm = comm;
334}
335
336//++
337// MuTyV& Get(string const& key)
338// Renvoie une référence sur l'objet "MuTyV" de la liste avec le nom "key".
339// Si cet objet (variable) n'existe pas, il est créé.
340// MuTyV& operator() (string const& key)
341// MuTyV& operator[] (string const& key)
342//
343// Renvoie la variable de nom "key". Equivalent à "Get(key)".
344// string& Comment()
345// Renvoie une référence sur le champ commentaire de l'objet.
346//--
347
348/* --Methode-- */
349/*! Return the MuTyV value associated with name \b key .
350 Integer 0 is returned if \b key is not present in the list */
351MuTyV DVList::Get(string const& key) const
352{
353ValList::const_iterator it = mvlist.find(key);
354if (it == mvlist.end()) return(MuTyV( (int_8) 0));
355else return((*it).second.elval);
356}
357
358/* --Methode-- */
359/*! Return the MuTyV value associated with name \b key .
360 Adds an entry of type integer in the list if \b key is not present in the list */
361MuTyV& DVList::Get(string const& key)
362{
363size_t l = key.length();
364if ( (l < 1) || (key.find_first_of(" ") < l) ) return(ddvdum);
365// dvlElement xxx = {(int_8)0 , ""}; marche pas sur mac/CW (!) - cf DY
366dvlElement xxx; xxx.elval = (int_8)0; xxx.elcomm = "";
367ValList::iterator it = mvlist.find(key);
368if (it == mvlist.end()) mvlist[key] = xxx;
369it = mvlist.find(key);
370if (it == mvlist.end()) return(ddvdum);
371else return((*it).second.elval);
372}
373
374//++
375// Titre Entrée-Sortie
376//--
377
378//++
379// void Print()
380// Imprime (sur "cout") la liste des variables et leurs valeurs.
381// void Print(ostream& os)
382// Imprime sur le flot "os" la liste des variables et leurs valeurs.
383// ostream& operator << (ostream& s, DVList& dvl)
384// sortie sur flot "s" (Appel a "Print(s)").
385//--
386
387/* --Methode-- */
388/*! Prints a brief description of object on on the output stream \b os */
389void DVList::Show(ostream& os) const
390{
391os << "DVList::Show() - NVar= " << (int)mvlist.size() << "\n";
392os << comment << endl;
393}
394
395/* --Methode-- */
396/*! Prints the list of variables on the output stream \b os */
397void DVList::Print(ostream& os) const
398{
399os << "DVList::Print() - NVar= " << (int)mvlist.size() << "\n";
400if (comment.length() > 0) os << comment << endl;
401char buff[1024];
402ValList::const_iterator it;
403for(it = mvlist.begin(); it != mvlist.end(); it++) {
404 switch ((*it).second.elval.Type())
405 {
406 case MuTyV::MTVInteger :
407 sprintf(buff, "%s = %ld (int) %s\n", (*it).first.substr(0,64).c_str(),
408 (long)((*it).second.elval.iv), (*it).second.elcomm.substr(0,128).c_str());
409 break;
410 case MuTyV::MTVFloat :
411 sprintf(buff, "%s = %.20g (double) %s\n", (*it).first.substr(0,64).c_str(),
412 (*it).second.elval.dv, (*it).second.elcomm.substr(0,128).c_str());
413 break;
414 case MuTyV::MTVComplex :
415 sprintf(buff, "%s = %.20g %.20g i (complex) %s\n", (*it).first.substr(0,64).c_str(),
416 (*it).second.elval.dv, (*it).second.elval.dv_im, (*it).second.elcomm.substr(0,128).c_str());
417 break;
418 case MuTyV::MTVString :
419 sprintf(buff, "%s = %s (string) %s\n", (*it).first.substr(0,64).c_str(),
420 (*it).second.elval.strv->substr(0,800).c_str(), (*it).second.elcomm.substr(0,128).c_str());
421 break;
422 default :
423 break;
424 }
425 os << (string)buff;
426 }
427os << endl;
428}
429
430
431//++
432// Titre Exemples
433// Utilisation des objets *MuTyV* :
434//| MuTyV mvu; // Declaration d'une variable
435//| mvu = 60; // mvu est de type entier (= 60)
436//| mvu = 66.6; // et double (= 66.6) maintenant ...
437//| MuTyV mvi(14); // On construit une variable entiere = 14
438//| r_4 x = mvi; // x vaut 14.0
439//| MuTyV mvd(44.4); // Variable double = 44.4
440//| int k = mvd; // k vaut 44
441//| MuTyV mvs("Bonjour, Ca va ?"); // Variable chaine de caracteres
442//| string s = mvs; // s vaut "Bonjour, Ca va ?"
443// Utilisation des *DVList* :
444//| DVList dvl;
445//| dvl("toto") = 14;
446//| dvl("titi") = 25.5;
447//| dvl("tata") = "Bonjour, Ca va ?";
448// Majuscules et minuscules sont differenciees pour les noms, pas de blanc ...
449//| dvl("hello") = 88;
450//| dvl("Hello") = 77.77;
451//| dvl.Comment() = "Test d'objet DVList, avec variables hello, Hello ";
452//| dvl.Write("dvlist.ppf");
453// Plus loin, ou dans un autre programme, on relit le fichier fabrique plus haut
454//| DVList dvlr("dvlist.ppf");
455//| int k = dvlr["toto"] ; // k = 14
456//| r_8 b = dvlr["titi"] ; // b = 25.5
457//| string s = dvlr["tata"] ; // s = "Bonjour, Ca va ?"
458//| r_4 c = dvlr["Hello"] ; // c = 77.77
459//| int l = dvlr["Hello"] ; // l = 77
460//| int m = dvlr["hello"] ; // m = 88
461//--
462
463
464//----------------------------------------------------------
465// Classe pour la gestion de persistance
466// ObjFileIO<DVList>
467//----------------------------------------------------------
468
469/* --Methode-- */
470void ObjFileIO<DVList>::WriteSelf(POutPersist& s) const
471{
472char buf[1024];
473string sfw;
474int lc = dobj->Comment().length();
475// itab - 0 : Version, 1 : NVar, 2 : Comment length, 3 reserved
476uint_4 itab[4];
477itab[0] = 2; // Version number = 2
478itab[1] = dobj->Size();
479itab[2] = lc;
480itab[3] = 0;
481s.Put(itab, 4);
482
483if (lc > 0) s.PutStr(dobj->Comment());
484sfw = "\n----Variable-List---------------\n";
485s.PutStr(sfw);
486
487DVList::ValList::const_iterator it;
488for(it = dobj->Begin(); it != dobj->End(); it++) {
489 switch ((*it).second.elval.Type()) {
490 case MuTyV::MTVInteger :
491 sprintf(buf,"I %s %ld\n", (*it).first.substr(0,64).c_str(), (long)((*it).second.elval.iv) );
492 sfw = buf; s.PutStr(sfw);
493 break;
494 case MuTyV::MTVFloat :
495 sprintf(buf,"F %s %.20g\n", (*it).first.substr(0,64).c_str(), (*it).second.elval.dv );
496 sfw = buf; s.PutStr(sfw);
497 break;
498 case MuTyV::MTVComplex :
499 sprintf(buf,"Z %s %.20g %.20g\n", (*it).first.substr(0,64).c_str(), (*it).second.elval.dv,
500 (*it).second.elval.dv_im);
501 sfw = buf; s.PutStr(sfw);
502 break;
503 case MuTyV::MTVString :
504 sprintf(buf,"S %s %s\n", (*it).first.substr(0,64).c_str(), (*it).second.elval.strv->substr(0,960).c_str() );
505 sfw = buf; s.PutStr(sfw);
506 break;
507 default :
508 break;
509 }
510// Ecriture eventuelle du commentaire associe
511 if ((*it).second.elcomm.length() > 0) {
512 sprintf(buf,"# %s", (*it).second.elcomm.substr(0,256).c_str());
513 sfw = buf; s.PutStr(sfw);
514 }
515}
516
517sfw = "ZZZZZ--End-of-Varible-List------"; s.PutStr(sfw);
518}
519
520/* --Methode-- */
521void ObjFileIO<DVList>::ReadSelf(PInPersist& s)
522{
523char buf[1024];
524string sfr;
525int_8 j,iv,k;
526r_8 dv, dvi;
527complex<r_8> z;
528bool ok=true;
529buf[0] = '\0';
530dobj->Clear();
531
532// itab - 0 : Version, 1 : NVar, 2 : Comment length, 3 reserved
533uint_4 itab[4];
534s.Get(itab, 4);
535if (itab[2] > 0) { // Il y a un champ commentaire a lire
536 s.GetStr(sfr);
537 dobj->Comment() = sfr;
538 }
539
540s.GetStr(sfr); // Pour lire les "------- "
541
542string key="";
543while(ok) {
544 s.GetStr(sfr);
545 strncpy(buf, sfr.c_str(), 1024);
546 buf[1023] = '\0';
547 j = strlen(buf)-1;
548 if ( (j >= 0) && (buf[j] == '\n') ) buf[j] = '\0';
549 if (strncmp(buf,"ZZZZZ",5) == 0) { ok=false; break; }
550 if (buf[0] == '#') {
551 dobj->SetComment(key, buf+2);
552 continue;
553 }
554 j = posc(buf+2, ' ')+2;
555 buf[j] = '\0';
556 switch (buf[0]) {
557 case 'I' :
558 iv = (int_8)atol(buf+j+1);
559 key = buf+2;
560 dobj->SetI(key, iv);
561 break;
562 case 'F' :
563 dv = atof(buf+j+1);
564 key = buf+2;
565 dobj->SetD(key, dv);
566 break;
567 case 'Z' :
568 k = posc(buf+j+1, ' ')+j+1;
569 buf[k] = '\0';
570 dv = atof(buf+j+1);
571 dvi = atof(buf+k+1);
572 key = buf+2;
573 z = complex<r_8>(dv, dvi);
574 dobj->SetZ(key, z);
575 break;
576 case 'S' :
577 key = buf+2;
578 dobj->SetS(key, buf+j+1);
579 break;
580 default :
581 break;
582 }
583 }
584if (dobj->Size() != itab[1]) // Probleme !!!
585 throw FileFormatExc("ObjFileIO<DVList>::ReadSelf() Error in Nb. Variables !");
586}
587
588#ifdef __CXX_PRAGMA_TEMPLATES__
589#pragma define_template ObjFileIO<DVList>
590#endif
591
592#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
593template class ObjFileIO<DVList>;
594#endif
Note: See TracBrowser for help on using the repository browser.