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

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

Documentation de fichiers - Reza 12/4/2000

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