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

Last change on this file since 2698 was 2698, checked in by ansari, 20 years ago

1/ Simplification de la classe gestionnairee PPersist ObjFile<T> (objfio.h)
2/ Ajout DECL_TEMP_SPEC ds ppftpointerio.h
3/ Nom specifique pour methode SegDBInterface::GetSegment() const devenu
SegDBInterface::GetCstSegment() const pour eviter l'appel a la methode non const
et adapatation classes derivees (segdatablock.h et swsegdb.h)
4/ Ajout SkipToNextObjet() ds PInPersist::ReadObject() (ppersist.cc) et protection contre pointeur NULL -> new DVList pour la lecture PPersist de DVList

Reza - 27 Avril 2005

File size: 18.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 "sopnamsp.h"
6#include "machdefs.h"
7#include <stdlib.h>
8#include <stdio.h>
9
10#include "dvlist.h"
11#include "strutil.h"
12
13//++
14// Class DVList
15// Lib BaseTools
16// include dvlist.h
17//
18// Cette classe permet de gérer une ensemble de variables (ou paramètres)
19// pouvant être définies dynamiquement à l'execution. Le nom des
20// variables ne doit pas contenir de blancs ("<espace>") et est
21// limité à 64 caractères maximum. Cette classe
22// offre la possibilité de sauvegarder l'ensemble
23// des variables (Nom, Type, Valeur) dans un fichier, ou de
24// recréer l'objet DVList et l'ensemble de ses variables à
25// partir d'un fichier (Objet PPersist). Une zone commentaire (max=320 c.)
26// est associée à chaque objet DVList, accessible à travers
27// la méthode "Comment()". Les objets de cette classe sont
28// en particulier destinés à être inclus dans d'autres objets
29// PPersist plus complexes. La classe DVList gère des
30// variables de type entier ("int_8"), réél double précision ("r_8")
31// et de type chaine de caracteres ("string, char*", maxi 30 caracteres ).
32// Une classe intermédiaire (*MuTyV*) est utilisée pour représenter une
33// variable et fournit les services de conversion entre les différents types.
34//--
35//--
36//++
37// Links Parents
38// PPersist
39//--
40
41
42static MuTyV ddvdum(-9.e19);
43
44
45/*!
46 \class SOPHYA::DVList
47 \ingroup BaseTools
48 This class can be used to construct list of values associated with names.
49 Variables names should not contain space characters and is limited to 64
50 characters. The DVList class uses \b SOPHYA::MuTyV objects to hold values
51 of type string, integer (\b int_8) or float (\b r_8). A comment string
52 can be associated with each variable name. A global comment string
53 can be attached to the DVList object. DVList objects can conveniently be
54 used to represent FITS headers. The class \b SOPHYA::ObjFileIO<DVList>
55 handles serialisation for DVList. (See SOPHYA::PPersist ).
56 \sa SOPHYA::ObjFileIO<DVList>
57
58 \code
59 // ------- Using DVList objects ------
60 DVList dvl;
61 dvl("toto") = 14; // Integer type value (=14) named toto
62 dvl("titi") = 25.5; // float type value (=25.5) named titi
63 dvl("tata") = "Bonjour !"; // string type value (="Bonjour !") named tata
64 // Upper and lower case letters are distinguished
65 dvl("hello") = 88;
66 dvl("Hello") = 77.77;
67 dvl.Comment() = "DVList test object, with values named hello, Hello ";
68 // Saving the dvl object into a PPF file
69 POutStream os("dvl.ppf");
70 os << dvl;
71 // later on ...
72 DVList dvlr;
73 PInStream is("dvl.ppf");
74 is << dvlr;
75 int k = dvlr["toto"] ; // k = 14
76 r_8 b = dvlr["titi"] ; // b = 25.5
77 string s = dvlr["tata"] ; // s = "Bonjour !"
78 int m = dvlr["hello"] ; // m = 88
79
80 \endcode
81*/
82
83//++
84// Titre Constructeurs
85//--
86
87//++
88// DVList()
89// Constructeur par défaut
90// DVList(DVList& cfd)
91// Constructeur par copie. Le nouvel objet est une copie complète de "cfd"
92// DVList(char* flnm)
93// Constructeur avec initialisation à partir du contenu du fichier (PPF)
94// "flnm". Le fichier doit avoir été créé par la méthode "Write()"
95//--
96
97/* --Methode-- */
98/*! Default constructor */
99DVList::DVList()
100{
101comment = "";
102}
103
104/* --Methode-- */
105/*! copy constructor */
106DVList::DVList(const DVList& dvl)
107{
108Merge(dvl);
109}
110
111/* --Methode-- */
112/*! Copy constructor - Object initialized using the PPF file \b flnm */
113DVList::DVList(char *flnm)
114{
115PInPersist s(flnm);
116ObjFileIO<DVList> fiodvl(this);
117fiodvl.Read(s);
118}
119
120
121/* --Methode-- */
122DVList::~DVList()
123{
124}
125
126//++
127// Titre Gestion des variables et opérateurs
128//--
129
130//++
131// void Clear()
132// Supprime la définition de toutes les variables de l'objet.
133// DVList& Merge(const DVList& lv)
134// Fusionne l'objet avec la liste des variables de l'objet "lv"
135// DVList& operator= (const DVList& cofr)
136// Remplace la liste des variables de l'objet par celle de l'objet "cofr".
137//--
138
139/* --Methode-- */
140/*! Copy operator - Replaces the variables list with the list from \b dvl */
141DVList& DVList::operator= (const DVList& dvl)
142{
143Clear();
144return(Merge(dvl));
145}
146
147
148/* --Methode-- */
149/*! Resets the object and clears the variable list and global comment */
150void DVList::Clear()
151{
152mvlist.erase(mvlist.begin(), mvlist.end());
153comment = "";
154}
155
156/* --Methode-- */
157/*! Appends the values from the object \b dvl to the objects list */
158DVList& DVList::Merge(const DVList& dvl)
159{
160ValList::const_iterator it;
161for(it = dvl.mvlist.begin(); it != dvl.mvlist.end(); it++)
162 {
163 switch ((*it).second.elval.Type())
164 {
165 case MuTyV::MTVInteger :
166 SetI((*it).first, (*it).second.elval.GetIntPart());
167 break;
168 case MuTyV::MTVFloat :
169 SetD((*it).first, (*it).second.elval.GetRealPart());
170 break;
171 case MuTyV::MTVComplex :
172 SetZ((*it).first, complex<r_8>((*it).second.elval.GetRealPart(), (*it).second.elval.GetImagPart()));
173 break;
174 case MuTyV::MTVString :
175 SetS((*it).first, *((*it).second.elval.GetStringPointer()));
176 break;
177 default :
178 break;
179 }
180 SetComment((*it).first, (*it).second.elcomm);
181 }
182comment = comment + "\n" + dvl.comment;
183return(*this);
184}
185
186
187//++
188// int_8 GetI(string const& key, int_8 def=-1)
189// r_8 GetD(string const& key, r_8 def=-9.e19)
190// string GetS(string const& key, char* def="")
191// Retourne la valeur de la variable de nom "key" et de type entier, réél,
192// chaine de caracteres.
193// Si la variable n'existe pas, la valeur par défaut "def" est renvoyée.
194// string GetComment(string const& key)
195// Retourne le commentaire associé à la variable de nom "key".
196//--
197
198/* --Methode-- */
199/*! Returns the value corresponding to name \b key, converted to integer
200 Default value \b def is returned if name \b key not found */
201int_8 DVList::GetI(string const& key, int_8 def) const
202{
203ValList::const_iterator it = mvlist.find(key);
204if (it == mvlist.end()) return(def);
205return( (int_8)((*it).second.elval) );
206}
207
208/* --Methode-- */
209/*! Returns the value corresponding to name \b key, converted to double
210 Default value \b def is returned if name \b key not found */
211r_8 DVList::GetD(string const& key, r_8 def) const
212{
213ValList::const_iterator it = mvlist.find(key);
214if (it == mvlist.end()) return(def);
215return( (r_8)((*it).second.elval) );
216}
217
218/* --Methode-- */
219/*! Returns the value corresponding to name \b key, converted to complex
220 Default value \b def is returned if name \b key not found */
221complex<r_8> DVList::GetZ(string const& key, complex<r_8> def) const
222{
223ValList::const_iterator it = mvlist.find(key);
224if (it == mvlist.end()) return(def);
225/*
226 Appel explicite de l'operateur de conversion
227 suite a la suggestion de M. Reinecke, Reza 31/7/2002
228#if defined(__GNUG__)
229complex<r_8> z;
230z = (*it).second.elval;
231return(z);
232#else
233return( (complex<r_8>)(*it).second.elval );
234#endif
235 --- Appel explicite de l'operateur de conversion sur l'objet MuTyV
236*/
237return( (*it).second.elval.operator complex<r_8>() );
238}
239
240/* --Methode-- */
241/*! Returns the value corresponding to name \b key, converted to string
242 Default value \b def is returned if name \b key not found */
243string DVList::GetS(string const& key, char* def) const
244{
245ValList::const_iterator it = mvlist.find(key);
246if (it == mvlist.end()) return(def);
247return( (string)((*it).second.elval) );
248}
249
250/* --Methode-- */
251/*! Returns the comment associated with name \b key */
252string DVList::GetComment(string const& key) const
253{
254ValList::const_iterator it = mvlist.find(key);
255if (it == mvlist.end()) return("");
256return((*it).second.elcomm);
257}
258
259//++
260// void SetI(string const& key, int_8 val)
261// void SetD(string const& key, r_8 val)
262// void SetZ(string const& key, complex<r_8> val)
263// void SetS(string const& key, char* val)
264// void SetS(string const& key, string val)
265// Crée la variable de nom "key", de type entier, double, complexe, string et
266// lui attribue la valeur "val". Si une variable du même nom existe,
267// sa valeur et eventuellement son type sont modifiés. Les noms de
268// variables ne doivent pas contenir de caractères spéciaux,
269// en particulier pas de CR/LF.
270// void SetComment(string const& key, string const& comm)
271// Modifie le commentaire associé à la variable de nom "key", si
272// celle-ci existe. Le texte du commentaire ne doit pas contenir
273// de caractères spéciaux, et en particulier pas de CR/LF.
274//--
275
276/* --Methode-- */
277/*! Removes the definition and value associated with the name \b key.
278 Return \c true if the \b key is found in the list, \c false otherwise. */
279bool DVList::DeleteKey(string const& key)
280{
281ValList::iterator it = mvlist.find(key);
282if (it == mvlist.end()) return(false);
283mvlist.erase(it);
284return(true);
285}
286
287/* --Methode-- */
288/*! Return \c true if the \b key is found in the list, \c false otherwise. */
289bool DVList::HasKey(string const& key) const
290{
291ValList::const_iterator it = mvlist.find(key);
292if (it == mvlist.end()) return(false);
293return(true);
294}
295
296
297/* --Methode-- */
298/*! Appends or sets the integer value \b val in the list with name \b key */
299void DVList::SetI(string const& key, int_8 val)
300{
301Get(key) = (int_8)val;
302}
303
304/* --Methode-- */
305void DVList::SetD(string const& key, r_8 val)
306/*! Appends or sets the double value \b val in the list with name \b key */
307{
308Get(key) = (r_8)val;
309}
310
311/* --Methode-- */
312void DVList::SetZ(string const& key, complex<r_8> val)
313/*! Appends or sets the complex value \b val in the list with name \b key */
314{
315Get(key) = val;
316}
317
318/* --Methode-- */
319/*! Appends or sets the string value \b val in the list with name \b key */
320void DVList::SetS(string const& key, char const* val)
321{
322MuTyV div(val);
323Get(key) = div;
324}
325
326/* --Methode-- */
327/*! Appends or sets the string value \b val in the list with name \b key */
328void DVList::SetS(string const& key, string const& val)
329{
330MuTyV div(val);
331Get(key) = div;
332}
333
334/* --Methode-- */
335/*! Assigns the comment \b comm with the name \b key .
336 Does nothing if the entry with name is not present in the list */
337void DVList::SetComment(string const& key, string const& comm)
338{
339ValList::iterator it = mvlist.find(key);
340if (it == mvlist.end()) return;
341(*it).second.elcomm = comm;
342}
343
344//++
345// MuTyV& Get(string const& key)
346// Renvoie une référence sur l'objet "MuTyV" de la liste avec le nom "key".
347// Si cet objet (variable) n'existe pas, il est créé.
348// MuTyV& operator() (string const& key)
349// MuTyV& operator[] (string const& key)
350//
351// Renvoie la variable de nom "key". Equivalent à "Get(key)".
352// string& Comment()
353// Renvoie une référence sur le champ commentaire de l'objet.
354//--
355
356/* --Methode-- */
357/*! Return the MuTyV value associated with name \b key .
358 Integer 0 is returned if \b key is not present in the list */
359MuTyV DVList::Get(string const& key) const
360{
361ValList::const_iterator it = mvlist.find(key);
362if (it == mvlist.end()) return(MuTyV( (int_8) 0));
363else return((*it).second.elval);
364}
365
366/* --Methode-- */
367/*! Return the MuTyV value associated with name \b key .
368 Adds an entry of type integer in the list if \b key is not present in the list */
369MuTyV& DVList::Get(string const& key)
370{
371size_t l = key.length();
372if ( (l < 1) || (key.find_first_of(" ") < l) ) return(ddvdum);
373// dvlElement xxx = {(int_8)0 , ""}; marche pas sur mac/CW (!) - cf DY
374dvlElement xxx; xxx.elval = (int_8)0; xxx.elcomm = "";
375ValList::iterator it = mvlist.find(key);
376if (it == mvlist.end()) mvlist[key] = xxx;
377it = mvlist.find(key);
378if (it == mvlist.end()) return(ddvdum);
379else return((*it).second.elval);
380}
381
382//++
383// Titre Entrée-Sortie
384//--
385
386//++
387// void Print()
388// Imprime (sur "cout") la liste des variables et leurs valeurs.
389// void Print(ostream& os)
390// Imprime sur le flot "os" la liste des variables et leurs valeurs.
391// ostream& operator << (ostream& s, DVList& dvl)
392// sortie sur flot "s" (Appel a "Print(s)").
393//--
394
395/* --Methode-- */
396/*! Prints a brief description of object on on the output stream \b os */
397void DVList::Show(ostream& os) const
398{
399os << "DVList::Show() - NVar= " << (int)mvlist.size() << "\n";
400os << comment << endl;
401}
402
403/* --Methode-- */
404/*! Prints the list of variables on the output stream \b os */
405void DVList::Print(ostream& os) const
406{
407os << "DVList::Print() - NVar= " << (int)mvlist.size() << "\n";
408if (comment.length() > 0) os << comment << endl;
409char buff[1024];
410ValList::const_iterator it;
411for(it = mvlist.begin(); it != mvlist.end(); it++) {
412 switch ((*it).second.elval.Type())
413 {
414 case MuTyV::MTVInteger :
415 sprintf(buff, "%s = %ld (int) %s\n", (*it).first.substr(0,64).c_str(),
416 (long)((*it).second.elval.GetIntPart()), (*it).second.elcomm.substr(0,128).c_str());
417 break;
418 case MuTyV::MTVFloat :
419 sprintf(buff, "%s = %.20g (double) %s\n", (*it).first.substr(0,64).c_str(),
420 (*it).second.elval.GetRealPart(), (*it).second.elcomm.substr(0,128).c_str());
421 break;
422 case MuTyV::MTVComplex :
423 sprintf(buff, "%s = %.20g %.20g i (complex) %s\n", (*it).first.substr(0,64).c_str(),
424 (*it).second.elval.GetRealPart(), (*it).second.elval.GetImagPart(), (*it).second.elcomm.substr(0,128).c_str());
425 break;
426 case MuTyV::MTVString :
427 sprintf(buff, "%s = %s (string) %s\n", (*it).first.substr(0,64).c_str(),
428 (*it).second.elval.GetStringPointer()->substr(0,800).c_str(), (*it).second.elcomm.substr(0,128).c_str());
429 break;
430 default :
431 break;
432 }
433 os << (string)buff;
434 }
435os << endl;
436}
437
438
439//++
440// Titre Exemples
441// Utilisation des objets *MuTyV* :
442//| MuTyV mvu; // Declaration d'une variable
443//| mvu = 60; // mvu est de type entier (= 60)
444//| mvu = 66.6; // et double (= 66.6) maintenant ...
445//| MuTyV mvi(14); // On construit une variable entiere = 14
446//| r_4 x = mvi; // x vaut 14.0
447//| MuTyV mvd(44.4); // Variable double = 44.4
448//| int k = mvd; // k vaut 44
449//| MuTyV mvs("Bonjour, Ca va ?"); // Variable chaine de caracteres
450//| string s = mvs; // s vaut "Bonjour, Ca va ?"
451// Utilisation des *DVList* :
452//| DVList dvl;
453//| dvl("toto") = 14;
454//| dvl("titi") = 25.5;
455//| dvl("tata") = "Bonjour, Ca va ?";
456// Majuscules et minuscules sont differenciees pour les noms, pas de blanc ...
457//| dvl("hello") = 88;
458//| dvl("Hello") = 77.77;
459//| dvl.Comment() = "Test d'objet DVList, avec variables hello, Hello ";
460//| dvl.Write("dvlist.ppf");
461// Plus loin, ou dans un autre programme, on relit le fichier fabrique plus haut
462//| DVList dvlr("dvlist.ppf");
463//| int k = dvlr["toto"] ; // k = 14
464//| r_8 b = dvlr["titi"] ; // b = 25.5
465//| string s = dvlr["tata"] ; // s = "Bonjour, Ca va ?"
466//| r_4 c = dvlr["Hello"] ; // c = 77.77
467//| int l = dvlr["Hello"] ; // l = 77
468//| int m = dvlr["hello"] ; // m = 88
469//--
470
471
472//----------------------------------------------------------
473// Classe pour la gestion de persistance
474// ObjFileIO<DVList>
475//----------------------------------------------------------
476
477/* --Methode-- */
478DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
479void ObjFileIO<DVList>::WriteSelf(POutPersist& s) const
480{
481char buf[1024];
482string sfw;
483int lc = dobj->Comment().length();
484// itab - 0 : Version, 1 : NVar, 2 : Comment length, 3 reserved
485uint_4 itab[4];
486itab[0] = 2; // Version number = 2
487itab[1] = dobj->Size();
488itab[2] = lc;
489itab[3] = 0;
490s.Put(itab, 4);
491
492if (lc > 0) s.PutStr(dobj->Comment());
493sfw = "\n----Variable-List---------------\n";
494s.PutStr(sfw);
495
496DVList::ValList::const_iterator it;
497for(it = dobj->Begin(); it != dobj->End(); it++) {
498 switch ((*it).second.elval.Type()) {
499 case MuTyV::MTVInteger :
500 sprintf(buf,"I %s %ld\n", (*it).first.substr(0,64).c_str(), (long)((*it).second.elval.GetIntPart()) );
501 sfw = buf; s.PutStr(sfw);
502 break;
503 case MuTyV::MTVFloat :
504 sprintf(buf,"F %s %.20g\n", (*it).first.substr(0,64).c_str(), (*it).second.elval.GetRealPart() );
505 sfw = buf; s.PutStr(sfw);
506 break;
507 case MuTyV::MTVComplex :
508 sprintf(buf,"Z %s %.20g %.20g\n", (*it).first.substr(0,64).c_str(), (*it).second.elval.GetRealPart(),
509 (*it).second.elval.GetImagPart());
510 sfw = buf; s.PutStr(sfw);
511 break;
512 case MuTyV::MTVString :
513 sprintf(buf,"S %s %s\n", (*it).first.substr(0,64).c_str(), (*it).second.elval.GetStringPointer()->substr(0,960).c_str() );
514 sfw = buf; s.PutStr(sfw);
515 break;
516 default :
517 break;
518 }
519// Ecriture eventuelle du commentaire associe
520 if ((*it).second.elcomm.length() > 0) {
521 sprintf(buf,"# %s", (*it).second.elcomm.substr(0,256).c_str());
522 sfw = buf; s.PutStr(sfw);
523 }
524}
525
526sfw = "ZZZZZ--End-of-Varible-List------"; s.PutStr(sfw);
527}
528
529/* --Methode-- */
530DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
531void ObjFileIO<DVList>::ReadSelf(PInPersist& s)
532{
533char buf[1024];
534string sfr;
535int_8 j,iv,k;
536r_8 dv, dvi;
537bool ok=true;
538buf[0] = '\0';
539if (dobj == NULL) dobj = new DVList;
540else dobj->Clear();
541
542// itab - 0 : Version, 1 : NVar, 2 : Comment length, 3 reserved
543uint_4 itab[4];
544s.Get(itab, 4);
545if (itab[2] > 0) { // Il y a un champ commentaire a lire
546 s.GetStr(sfr);
547 dobj->Comment() = sfr;
548 }
549
550s.GetStr(sfr); // Pour lire les "------- "
551
552string key="";
553while(ok) {
554 s.GetStr(sfr);
555 strncpy(buf, sfr.c_str(), 1024);
556 buf[1023] = '\0';
557 j = strlen(buf)-1;
558 if ( (j >= 0) && (buf[j] == '\n') ) buf[j] = '\0';
559 if (strncmp(buf,"ZZZZZ",5) == 0) { ok=false; break; }
560 if (buf[0] == '#') {
561 dobj->SetComment(key, buf+2);
562 continue;
563 }
564 j = posc(buf+2, ' ')+2;
565 buf[j] = '\0';
566 switch (buf[0]) {
567 case 'I' :
568 iv = (int_8)atol(buf+j+1);
569 key = buf+2;
570 dobj->SetI(key, iv);
571 break;
572 case 'F' :
573 dv = atof(buf+j+1);
574 key = buf+2;
575 dobj->SetD(key, dv);
576 break;
577 case 'Z' :
578 k = posc(buf+j+1, ' ')+j+1;
579 buf[k] = '\0';
580 dv = atof(buf+j+1);
581 dvi = atof(buf+k+1);
582 key = buf+2;
583 dobj->SetZ(key, complex<r_8>(dv, dvi));
584 break;
585 case 'S' :
586 key = buf+2;
587 dobj->SetS(key, buf+j+1);
588 break;
589 default :
590 break;
591 }
592 }
593if (dobj->Size() != itab[1]) // Probleme !!!
594 throw FileFormatExc("ObjFileIO<DVList>::ReadSelf() Error in Nb. Variables !");
595}
596
597#ifdef __CXX_PRAGMA_TEMPLATES__
598#pragma define_template ObjFileIO<DVList>
599#endif
600
601#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
602template class ObjFileIO<DVList>;
603#endif
Note: See TracBrowser for help on using the repository browser.