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

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

traitement du commentaire par merge() -GLM

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