]> Creatis software - gdcm.git/blob - src/gdcmDictSet.cxx
ENH: Remove any possible leaks with the dictionary. Now there is no /new/ anymore...
[gdcm.git] / src / gdcmDictSet.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmDictSet.cxx,v $
5   Language:  C++
6   Date:      $Date: 2004/10/27 22:31:12 $
7   Version:   $Revision: 1.42 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18
19 #include "gdcmDictSet.h"
20 #include "gdcmDebug.h"
21 #include <fstream>
22 #include <stdlib.h>  // For getenv
23
24 namespace gdcm 
25 {
26
27 //-----------------------------------------------------------------------------
28 // Constructor / Destructor
29 /** 
30  * \ingroup DictSet
31  * \brief   The Dictionnary Set obtained with this constructor simply
32  *          contains the Default Public dictionnary.
33  */
34 DictSet::DictSet() 
35 {
36    DictPath = BuildDictPath();
37    std::string pubDictFile(DictPath);
38    pubDictFile += PUB_DICT_FILENAME;
39    Dicts[PUB_DICT_NAME] = new Dict(pubDictFile);
40 }
41
42 /**
43  * \ingroup DictSet
44  * \brief  Destructor 
45  */
46 DictSet::~DictSet() 
47 {
48    // Remove dictionnaries
49    for (DictSetHT::iterator tag = Dicts.begin(); tag != Dicts.end(); ++tag) 
50    {
51       Dict *entryToDelete = tag->second;
52       if ( entryToDelete )
53       {
54          delete entryToDelete;
55       }
56       tag->second = NULL;
57    }
58    Dicts.clear();
59
60    // Remove virtual dictionnary entries
61 /*   TagKeyHT::iterator it;
62    for(it = VirtualEntry.begin(); it != VirtualEntry.end(); ++it)
63    {
64       DictEntry entry = it->second;
65       if ( entry )
66       {
67          delete entry;
68       }
69       it->second = NULL;
70    }*/
71 }
72
73 //-----------------------------------------------------------------------------
74 // Print
75 /**
76  * \ingroup DictSet
77  * \brief   Print, in an informal fashion, the list of all the dictionaries
78  *          contained is this DictSet, along with their respective content.
79  * @param   os Output stream used for printing.
80  */
81 void DictSet::Print(std::ostream& os) 
82 {
83    for (DictSetHT::iterator dict = Dicts.begin(); dict != Dicts.end(); ++dict)
84    {
85       os << "Printing dictionary " << dict->first << std::endl;
86       dict->second->Print(os);
87    }
88 }
89
90 //-----------------------------------------------------------------------------
91 // Public
92 /** 
93  * \ingroup DictSet
94  * \brief   Consider all the entries of the public dicom dictionnary. 
95  *          Build all list of all the tag names of all those entries.
96  * \sa DictSet::GetPubDictTagNamesByCategory
97  * @return  A list of all entries of the public dicom dictionnary.
98  */
99 EntryNamesList * DictSet::GetPubDictEntryNames() 
100 {
101    return GetDefaultPubDict()->GetDictEntryNames();
102 }
103
104 /** 
105  * \ingroup DictSet
106  * \brief   
107  *          - Consider all the entries of the public dicom dictionnary.
108  *          - Build an hashtable whose keys are the names of the groups
109  *           (fourth field in each line of dictionary) and whose corresponding
110  *           values are lists of all the dictionnary entries among that
111  *           group. Note that apparently the Dicom standard doesn't explicitely
112  *           define a name (as a string) for each group.
113  *          - A typical usage of this method would be to enable a dynamic
114  *           configuration of a Dicom file browser: the admin/user can
115  *           select in the interface which Dicom tags should be displayed.
116  * \warning 
117  *          - Dicom *doesn't* define any name for any 'categorie'
118  *          (the dictionnary fourth field was formerly NIH defined
119  *           -and no longer he is-
120  *           and will be removed when Dicom provides us a text file
121  *           with the 'official' Dictionnary, that would be more friendly
122  *           than asking us to perform a line by line check of the dictionnary
123  *           at the beginning of each year to -try to- guess the changes)
124  *          - Therefore : please NEVER use that fourth field :-(
125  * *
126  * @return  An hashtable: whose keys are the names of the groups and whose
127  *          corresponding values are lists of all the dictionnary entries
128  *          among that group.
129  */
130 EntryNamesByCatMap * DictSet::GetPubDictEntryNamesByCategory() 
131 {
132    return GetDefaultPubDict()->GetDictEntryNamesByCategory();
133 }
134
135 /**
136  * \ingroup DictSet
137  * \brief   Loads a dictionary from a specified file, and add it
138  *          to already the existing ones contained in this DictSet.
139  * @param   filename Absolute or relative filename containing the
140  *          dictionary to load.
141  * @param   name Symbolic name that be used as identifier of the newly 
142  *          created dictionary.
143  */
144 Dict *DictSet::LoadDictFromFile(std::string const & filename, 
145                                 DictKey const & name) 
146 {
147    Dict *newDict = new Dict(filename);
148    AppendDict(newDict, name);
149
150    return newDict;
151 }
152
153 /**
154  * \ingroup DictSet
155  * \brief   Retrieve the specified dictionary (when existing) from this
156  *          DictSet.
157  * @param   dictName The symbolic name of the searched dictionary.
158  * \result  The retrieved dictionary.
159  */
160 Dict *DictSet::GetDict(DictKey const & dictName) 
161 {
162    DictSetHT::iterator dict = Dicts.find(dictName);
163    if(dict != Dicts.end())
164    {
165       return dict->second;
166    }
167    return NULL;
168 }
169
170 /**
171  * \brief   Create a DictEntry which will be reference 
172  *          in no dictionnary
173  * @return  virtual entry
174  */
175 DictEntry *DictSet::NewVirtualDictEntry( uint16_t group,
176                                          uint16_t element,
177                                          TagName vr,
178                                          TagName fourth,
179                                          TagName name)
180 {
181    DictEntry *entry;
182    const std::string tag = DictEntry::TranslateToKey(group,element)
183                            + "#" + vr + "#" + fourth + "#" + name;
184    TagKeyHT::iterator it;
185    
186    it = VirtualEntry.find(tag);
187    if(it != VirtualEntry.end())
188    {
189       entry = &(it->second);
190    }
191    else
192    {
193       DictEntry ent(group, element, vr, fourth, name);
194       //VirtualEntry[tag] = entry;
195       VirtualEntry.insert(
196          TagKeyHT::value_type<TagKey, DictEntry>
197             (tag, ent));
198       entry = &(VirtualEntry.find(tag)->second);
199    }
200
201    return entry;
202 }
203
204 /**
205  * \brief   Obtain from the GDCM_DICT_PATH environnement variable the
206  *          path to directory containing the dictionnaries. When
207  *          the environnement variable is absent the path is defaulted
208  *          to "../Dicts/".
209  * @return  path to directory containing the dictionnaries
210  */
211 std::string DictSet::BuildDictPath() 
212 {
213    std::string resultPath;
214    const char *envPath = 0;
215    envPath = getenv("GDCM_DICT_PATH");
216
217    if (envPath && (strlen(envPath) != 0)) 
218    {
219       resultPath = envPath;
220       if ( resultPath[resultPath.length()-1] != '/' )
221       {
222          resultPath += '/';
223       }
224       dbg.Verbose(1, "DictSet::BuildDictPath:",
225                      "Dictionary path set from environnement");
226    } 
227    else
228    {
229       resultPath = PUB_DICT_PATH;
230    }
231
232    return resultPath;
233 }
234
235 //-----------------------------------------------------------------------------
236 // Protected
237 bool DictSet::AppendDict(Dict *newDict, DictKey const & name)
238 {
239    Dicts[name] = newDict;
240
241    return true;   //FIXME
242 }
243
244 //-----------------------------------------------------------------------------
245 // Private
246
247 //-----------------------------------------------------------------------------
248
249 } // end namespace gdcm