]> Creatis software - gdcm.git/blob - src/gdcmDictSet.cxx
ENH: update gdcmDebug after Benoit comments
[gdcm.git] / src / gdcmDictSet.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmDictSet.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/01/07 19:20:38 $
7   Version:   $Revision: 1.48 $
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    VirtualEntry.clear();
62 }
63
64 //-----------------------------------------------------------------------------
65 // Print
66 /**
67  * \ingroup DictSet
68  * \brief   Print, in an informal fashion, the list of all the dictionaries
69  *          contained is this DictSet, along with their respective content.
70  * @param   os Output stream used for printing.
71  */
72 void DictSet::Print(std::ostream &os) 
73 {
74    for (DictSetHT::iterator dict = Dicts.begin(); dict != Dicts.end(); ++dict)
75    {
76       os << "Printing dictionary " << dict->first << std::endl;
77       dict->second->Print(os);
78    }
79 }
80
81 //-----------------------------------------------------------------------------
82 // Public
83 /** 
84  * \ingroup DictSet
85  * \brief   Consider all the entries of the public dicom dictionnary. 
86  *          Build all list of all the tag names of all those entries.
87  * \sa DictSet::GetPubDictTagNamesByCategory
88  * @return  A list of all entries of the public dicom dictionnary.
89  */
90
91 // Probabely useless!
92  
93 //EntryNamesList *DictSet::GetPubDictEntryNames() 
94 //{
95 //   return GetDefaultPubDict()->GetDictEntryNames();
96 //}
97
98 /** 
99  * \ingroup DictSet
100  * \brief   
101  *          - Consider all the entries of the public dicom dictionnary.
102  *          - Build an hashtable whose keys are the names of the groups
103  *           (fourth field in each line of dictionary) and whose corresponding
104  *           values are lists of all the dictionnary entries among that
105  *           group. Note that apparently the Dicom standard doesn't explicitely
106  *           define a name (as a string) for each group.
107  *           NO ! Dicom Standard explicitely doesn't define 
108  *                any name, for any group !
109  *          - A typical usage of this method would be to enable a dynamic
110  *           configuration of a Dicom file browser: the admin/user can
111  *           select in the interface which Dicom tags should be displayed.
112  * \warning 
113  *          - Dicom *doesn't* define any name for any 'categorie'
114  *          (the dictionnary fourth field was formerly NIH defined
115  *           -and no longer he is-
116  *           and will be removed when Dicom provides us a text file
117  *           with the 'official' Dictionnary, that would be more friendly
118  *           than asking us to perform a line by line check of the dictionnary
119  *           at the beginning of each year to -try to- guess the changes)
120  *          - Therefore : please NEVER use that fourth field :-(
121  * *
122  * @return  An hashtable: whose keys are the names of the groups and whose
123  *          corresponding values are lists of all the dictionnary entries
124  *          among that group.
125  */
126
127
128 // Probabely useless!
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 vm,
179                                          TagName name)
180 {
181    DictEntry *entry;
182    const std::string tag = DictEntry::TranslateToKey(group,element)
183                            + "#" + vr + "#" + vm + "#" + 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, vm, name);
194       VirtualEntry.insert(
195          std::map<TagKey, DictEntry>::value_type
196             (tag, ent));
197       entry = &(VirtualEntry.find(tag)->second);
198    }
199
200    return entry;
201 }
202
203 /**
204  * \brief   Obtain from the GDCM_DICT_PATH environnement variable the
205  *          path to directory containing the dictionnaries. When
206  *          the environnement variable is absent the path is defaulted
207  *          to "../Dicts/".
208  * @return  path to directory containing the dictionnaries
209  */
210 std::string DictSet::BuildDictPath() 
211 {
212    std::string resultPath;
213    const char *envPath = 0;
214    envPath = getenv("GDCM_DICT_PATH");
215
216    if (envPath && (strlen(envPath) != 0)) 
217    {
218       resultPath = envPath;
219       if ( resultPath[resultPath.length()-1] != '/' )
220       {
221          resultPath += '/';
222       }
223       gdcmVerboseMacro("DictSet::BuildDictPath:"
224                   "Dictionary path set from environnement");
225    } 
226    else
227    {
228       resultPath = PUB_DICT_PATH;
229    }
230
231    return resultPath;
232 }
233
234 //-----------------------------------------------------------------------------
235 // Protected
236 bool DictSet::AppendDict(Dict *newDict, DictKey const &name)
237 {
238    Dicts[name] = newDict;
239
240    return true;
241 }
242
243 //-----------------------------------------------------------------------------
244 // Private
245
246 //-----------------------------------------------------------------------------
247
248 } // end namespace gdcm