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

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

Declaration sa_size_t ds machdefs.h - Amelioration/correction DVList et MuTyV - Reza 29/8/2000

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