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

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

Compil sous g++ , Reza 12/10/2000

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