]> Creatis software - gdcm.git/blob - src/gdcmDict.cxx
Remove useless accesses to the Dicom Dictionnary std::map
[gdcm.git] / src / gdcmDict.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmDict.cxx,v $
5   Language:  C++
6   Date:      $Date: 2006/04/11 16:03:26 $
7   Version:   $Revision: 1.84 $
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 "gdcmDict.h"
20 #include "gdcmUtil.h"
21 #include "gdcmDebug.h"
22
23 #include <fstream>
24 #include <iostream>
25 #include <iomanip>
26
27 namespace gdcm 
28 {
29 //-----------------------------------------------------------------------------
30 /// \brief auto generated function, to fill up the Dicom Dictionnary,
31 ///       if relevant file is not found on user's disk
32 void FillDefaultDataDict(Dict *d);
33
34 //-----------------------------------------------------------------------------
35 // Constructor / Destructor
36 /**
37  * \brief   Constructor
38  */
39 Dict::Dict( )
40 {
41    Filename="";
42 }
43
44 /**
45  * \brief   Constructor
46  * @param   filename from which to build the dictionary.
47  */
48 Dict::Dict(std::string const &filename)
49 {
50    gdcmDebugMacro( "in Dict::Dict, filename =[" << filename << "]" );
51    std::ifstream from( filename.c_str() );
52    if ( !from )
53    {
54       gdcmWarningMacro( "Can't open dictionary" << filename.c_str());
55       // Using default embeded one:
56       FillDefaultDataDict( this );
57    }
58    else
59    {
60       gdcmDebugMacro( "in Dict::Dict, DoTheLoadingJob filename =[" 
61                     << filename << "]" );
62       DoTheLoadingJob(from);
63       Filename = filename;
64    }
65 }
66
67 /**
68  * \brief  Destructor 
69  */
70 Dict::~Dict()
71 {
72    ClearEntry();
73 }
74
75 //-----------------------------------------------------------------------------
76 // Public
77
78 /**
79  * \brief   Add all the entries held in a source dictionary
80  * \note it concerns only Private Dictionnary
81  * @param   filename from which to build the dictionary.
82  */
83 bool Dict::AddDict(std::string const &filename)
84 {
85
86    std::ifstream from( filename.c_str() );
87    if ( !from )
88    {
89       gdcmWarningMacro( "Can't open dictionary" << filename.c_str());
90       return false;
91    }
92    else
93    {
94       DoTheLoadingJob(from);
95       return true;
96    }
97 }
98
99
100 /**
101  * \brief   Removes from the current Dicom Dict all the entries held in a source dictionary
102  * \note it concerns only Private Dictionnary
103  * @param   filename from which we read the entries to remove.
104  */
105 bool Dict::RemoveDict(std::string const &filename)
106 {
107    std::ifstream from( filename.c_str() );
108    if ( !from )
109    {
110       gdcmWarningMacro( "Can't open dictionary" << filename.c_str());
111       return false;
112    }
113    else
114    {
115       uint16_t group;
116       uint16_t elem;
117       TagName vr;
118       TagName vm;
119       TagName name;
120
121       while (!from.eof() && from)
122       {
123          from >> std::hex;
124          from >> group;
125          from >> elem;
126          from >> vr;
127          from >> vm;
128         // from >> std::ws;  //remove white space
129          std::getline(from, name);
130  
131          RemoveEntry(group,elem);
132       }
133       from.close();
134       return true;
135    }
136 }
137
138 /**
139  * \brief  adds a new Dicom Dictionary Entry 
140  * @param   newEntry entry to add 
141  * @return  false if Dicom Element already exists
142  */
143 bool Dict::AddEntry(DictEntry *newEntry) 
144 {
145    const TagKey &key = newEntry->GetKey();
146
147    if ( KeyHt.count(key) == 1 )
148    {
149       gdcmErrorMacro( "Already present:" << key );
150       return false;
151    } 
152    else 
153    {
154       newEntry->Register();
155       KeyHt.insert( TagKeyHT::value_type(key, newEntry));
156       return true;
157    }
158 }
159
160 /**
161  * \brief  replaces an already existing Dicom Element by a new one
162  * @param   newEntry new entry (overwrites any previous one with same tag)
163  * @return  false if Dicom Element doesn't exist
164  */
165  
166  /* seems to be useless
167  
168 bool Dict::ReplaceEntry(DictEntry *newEntry) // seems to be useless
169 {
170    const TagKey &key = newEntry->GetKey();
171    if ( RemoveEntry(key) )
172    {
173       newEntry->Register();
174       KeyHt.insert( TagKeyHT::value_type(key, newEntry));
175       return true;
176    } 
177    return false;
178 }
179 */
180 /**
181  * \brief  removes an already existing Dicom Dictionary Entry,
182  *         identified by its Tag
183  * @param   key (group|element)
184  * @return  false if Dicom Dictionary Entry doesn't exist
185  */
186 bool Dict::RemoveEntry(TagKey const &key) 
187 {
188    TagKeyHT::const_iterator it = KeyHt.find(key);
189    if ( it != KeyHt.end() ) 
190    {
191       it->second->Unregister(); // delete the entry
192       KeyHt.erase(key);         // remove pointer from HTable
193
194       return true;
195    } 
196    else 
197    {
198       gdcmWarningMacro( "Unfound entry" << key );
199       return false;
200   }
201 }
202
203 /**
204  * \brief  removes an already existing Dicom Dictionary Entry, 
205  *          identified by its group,element number
206  * @param   group   Dicom group number of the Dicom Element
207  * @param   elem Dicom element number of the Dicom Element
208  * @return  false if Dicom Dictionary Entry doesn't exist
209  */
210 bool Dict::RemoveEntry(uint16_t group, uint16_t elem)
211 {
212    return RemoveEntry(DictEntry::TranslateToKey(group, elem));
213 }
214
215 /**
216  * \brief   Remove all Dicom Dictionary Entries
217  */
218 void Dict::ClearEntry()
219 {
220    // we assume all the pointed DictEntries are already cleaned-up
221    // when we clean KeyHt.
222    TagKeyHT::const_iterator it;
223
224    for(it = KeyHt.begin();it!=KeyHt.end();++it)
225       it->second->Unregister(); // delete the entry
226    KeyHt.clear();               // remove all the entries from HTable
227
228 }
229
230 /**
231  * \brief   Get the dictionary entry identified by a given tag ("group|element")
232  * @param   key   tag of the searched entry 
233  * @return  the corresponding dictionary entry when existing, NULL otherwise
234  */
235 DictEntry *Dict::GetEntry(TagKey const &key)
236 {
237    TagKeyHT::iterator it = KeyHt.find(key);
238    if ( it == KeyHt.end() )
239    {
240       return 0;
241    }
242    return it->second;
243 }
244 /**
245  * \brief   Get the dictionary entry identified by it's "group" and "element")
246  * @param   group  Group number of the searched entry.
247  * @param   elem Element number of the searched entry.
248  * @return  the corresponding dictionary entry when existing, NULL otherwise
249  */
250 DictEntry *Dict::GetEntry(uint16_t group, uint16_t elem)
251 {
252    TagKey key = DictEntry::TranslateToKey(group, elem);
253    TagKeyHT::iterator it = KeyHt.find(key);
254    if ( it == KeyHt.end() )
255    {
256       return 0;
257    }
258    return it->second;
259 }
260
261 /**
262  * \brief   Get the first entry while visiting the Dict entries
263  * \return  The first DicEntry if found, otherwhise NULL
264  */
265 DictEntry *Dict::GetFirstEntry()
266 {
267    ItKeyHt = KeyHt.begin();
268    if ( ItKeyHt != KeyHt.end() )
269       return ItKeyHt->second;
270    return NULL;
271 }
272
273 /**
274  * \brief   Get the next entry while visiting the Hash table (KeyHt)
275  * \note : meaningfull only if GetFirstEntry already called
276  * \return  The next DictEntry if found, otherwhise NULL
277  */
278 DictEntry *Dict::GetNextEntry()
279 {
280    gdcmAssertMacro (ItKeyHt != KeyHt.end());
281
282    ++ItKeyHt;
283    if (ItKeyHt != KeyHt.end())
284       return ItKeyHt->second;
285    return NULL;
286 }
287
288 //-----------------------------------------------------------------------------
289 // Protected
290
291 //-----------------------------------------------------------------------------
292 // Private
293 /**
294  * \brief Add all the dictionary entries from an already open source file 
295  * @param from input stream to read from.
296  */
297 void Dict::DoTheLoadingJob(std::ifstream &from)
298 {
299    uint16_t group;
300    uint16_t elem;
301    VRKey vr;
302    TagName vm;
303    TagName name;
304
305    DictEntry *newEntry;
306    while (!from.eof() && from)
307    {
308       from >> std::hex;
309       from >> group;
310       from >> elem;
311       from >> vr;
312       from >> vm;
313       from >> std::ws;  //remove white space
314       std::getline(from, name);
315
316       newEntry = DictEntry::New(group, elem, vr, vm, name);
317       AddEntry(newEntry);
318       newEntry->Delete();
319    }
320    from.close();
321 }
322 //-----------------------------------------------------------------------------
323 // Print
324 /**
325  * \brief   Print all the dictionary entries contained in this dictionary.
326  *          Entries will be sorted by tag i.e. the couple (group, element).
327  * @param   os The output stream to be written to.
328  * @param indent Indentation string to be prepended during printing
329  */
330 void Dict::Print(std::ostream &os, std::string const & )
331 {
332    os << "Dict file name : [" << Filename << "]" << std::endl;
333    std::ostringstream s;
334
335    for (TagKeyHT::iterator tag = KeyHt.begin(); tag != KeyHt.end(); ++tag)
336    {  
337 std::cout << tag->second->GetKey() << " " << tag->second->GetName() 
338           << std::endl;
339       s << "Entry : ";
340       s << "(" << tag->second->GetKey() << ") = "
341         << std::dec;
342       s << tag->second->GetVR() << ", ";
343       s << tag->second->GetVM() << ", ";
344       s << tag->second->GetName() << "."  << std::endl;
345      
346    }
347    os << s.str();
348
349 }
350
351 //-----------------------------------------------------------------------------
352 } // end namespace gdcm