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

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

Documentation + Modifs mineures (namespace, etc..) - Reza 13/4/2000

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