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

Last change on this file since 2826 was 2826, checked in by ansari, 20 years ago

1/ Correction bug TimeStamp::ToDays() + petites amelioration
2/ Prise en compte du type TimeStamp dans MuTyV (sous forme de r_8 en interne)
3/ Adaptation DVList a modifs MuTyV (typ TimeStamp) et R/W PPersist

+ Petites corrections et MAJ num.version , Reza 2 Nov 2005

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