]> Creatis software - gdcm.git/blob - src/gdcmDict.cxx
ENH: First pass at removing name of function from hardcoded string from gdcmVerboseMa...
[gdcm.git] / src / gdcmDict.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmDict.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/01/07 22:03:30 $
7   Version:   $Revision: 1.60 $
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 void FillDefaultDataDict(Dict *d);
30 //-----------------------------------------------------------------------------
31 // Constructor / Destructor
32 /**
33  * \brief   Constructor
34  * @param   filename from which to build the dictionary.
35  */
36 Dict::Dict(std::string const &filename)
37 {
38    uint16_t group;
39    uint16_t element;
40    TagName vr;
41    TagName vm;
42    TagName name;
43
44    std::ifstream from( filename.c_str() );
45    if( !from )
46    {
47       gdcmVerboseMacro( "Can't open dictionary" << filename.c_str());
48       // Using default embeded one:
49       FillDefaultDataDict( this );
50    }
51    else
52    {
53       while (!from.eof())
54       {
55          from >> std::hex;
56          from >> group;
57          from >> element;
58          from >> vr;
59          from >> vm;
60          from >> std::ws;  //remove white space
61          std::getline(from, name);
62    
63          const DictEntry newEntry(group, element, vr, vm, name);
64          AddNewEntry(newEntry);
65       }
66
67       Filename = filename;
68    }
69    from.close();
70 }
71
72 /**
73  * \brief  Destructor 
74  */
75 Dict::~Dict()
76 {
77    // we assume all the pointed DictEntries are already cleaned-up
78    // when we clean KeyHt.
79    KeyHt.clear();
80 }
81
82 //-----------------------------------------------------------------------------
83 // Print
84 /**
85  * \brief   Print all the dictionary entries contained in this dictionary.
86  *          Entries will be sorted by tag i.e. the couple (group, element).
87  * @param   os The output stream to be written to.
88  */
89 void Dict::Print(std::ostream &os)
90 {
91    os << "Dict file name : " << Filename << std::endl;
92    PrintByKey(os);
93 }
94
95 /**
96  * \brief   Print all the dictionary entries contained in this dictionary.
97  *          Entries will be sorted by tag i.e. the couple (group, element).
98  * @param   os The output stream to be written to.
99  */
100 void Dict::PrintByKey(std::ostream &os)
101 {
102    std::ostringstream s;
103
104    for (TagKeyHT::iterator tag = KeyHt.begin(); tag != KeyHt.end(); ++tag)
105    {
106       s << "Entry : ";
107       s << "(" << std::hex << std::setw(4) << tag->second.GetGroup() << ',';
108       s << std::hex << std::setw(4) << tag->second.GetElement() << ") = "
109         << std::dec;
110       s << tag->second.GetVR() << ", ";
111       s << tag->second.GetVM() << ", ";
112       s << tag->second.GetName() << "."  << std::endl;
113    }
114    os << s.str();
115 }
116
117 //-----------------------------------------------------------------------------
118 // Public
119 /**
120  * \ingroup Dict
121  * \brief  adds a new Dicom Dictionary Entry 
122  * @param   newEntry entry to add 
123  * @return  false if Dicom Element already exists
124  */
125 bool Dict::AddNewEntry(DictEntry const &newEntry) 
126 {
127    const TagKey &key = newEntry.GetKey();
128
129    if(KeyHt.count(key) == 1)
130    {
131       gdcmVerboseMacro( "Already present" << key.c_str());
132       return false;
133    } 
134    else 
135    {
136       KeyHt.insert( TagKeyHT::value_type(newEntry.GetKey(), newEntry));
137       return true;
138    }
139 }
140
141 /**
142  * \ingroup Dict
143  * \brief  replaces an already existing Dicom Element by a new one
144  * @param   newEntry new entry (overwrites any previous one with same tag)
145  * @return  false if Dicom Element doesn't exist
146  */
147 bool Dict::ReplaceEntry(DictEntry const &newEntry)
148 {
149    if ( RemoveEntry(newEntry.GetKey()) )
150    {
151        KeyHt.insert( TagKeyHT::value_type(newEntry.GetKey(), newEntry));
152        return true;
153    } 
154    return false;
155 }
156
157 /**
158  * \ingroup Dict
159  * \brief  removes an already existing Dicom Dictionary Entry,
160  *         identified by its Tag
161  * @param   key (group|element)
162  * @return  false if Dicom Dictionary Entry doesn't exist
163  */
164 bool Dict::RemoveEntry (TagKey const &key) 
165 {
166    TagKeyHT::const_iterator it = KeyHt.find(key);
167    if(it != KeyHt.end()) 
168    {
169       KeyHt.erase(key);
170
171       return true;
172    } 
173    else 
174    {
175       gdcmVerboseMacro( "Unfound entry" << key.c_str());
176       return false;
177   }
178 }
179
180 /**
181  * \brief  removes an already existing Dicom Dictionary Entry, 
182  *          identified by its group,element number
183  * @param   group   Dicom group number of the Dicom Element
184  * @param   elem Dicom element number of the Dicom Element
185  * @return  false if Dicom Dictionary Entry doesn't exist
186  */
187 bool Dict::RemoveEntry (uint16_t group, uint16_t elem)
188 {
189    return RemoveEntry(DictEntry::TranslateToKey(group, elem));
190 }
191
192 /**
193  * \brief   Get the dictionnary entry identified by a given tag (group,element)
194  * @param   group   group of the entry to be found
195  * @param   elem element of the entry to be found
196  * @return  the corresponding dictionnary entry when existing, NULL otherwise
197  */
198 DictEntry *Dict::GetDictEntryByNumber(uint16_t group, uint16_t elem)
199 {
200    TagKey key = DictEntry::TranslateToKey(group, elem);
201    TagKeyHT::iterator it = KeyHt.find(key);
202    if ( it == KeyHt.end() )
203    {
204       return 0;
205    }
206    return &(it->second);
207 }
208
209 /** 
210  * \brief   Consider all the entries of the public dicom dictionnary. 
211  *          Build all list of all the tag names of all those entries.
212  * \sa      DictSet::GetPubDictTagNamesByCategory
213  * @return  A list of all entries of the public dicom dictionnary.
214  */
215
216  
217  // Probabely useless
218   
219  
220 //EntryNamesList *Dict::GetDictEntryNames() 
221 //{
222 //   EntryNamesList *result = new EntryNamesList;
223 //   for (TagKeyHT::iterator tag = KeyHt.begin(); tag != KeyHt.end(); ++tag)
224 //   {
225 //      result->push_back( tag->second.GetName() );
226 //   }
227 //   return result;
228 //}
229
230 /** 
231  * \ingroup Dict
232  * \brief   Consider all the entries of the public dicom dictionnary.
233  *          Build an hashtable whose keys are the names of the groups
234  *          (fourth field in each line of dictionary) and whose corresponding
235  *          values are lists of all the dictionnary entries among that
236  *          group. Note that apparently the Dicom standard doesn't explicitely
237  *          define a name (as a string) for each group.
238  *          A typical usage of this method would be to enable a dynamic
239  *          configuration of a Dicom file browser: the admin/user can
240  *          select in the interface which Dicom tags should be displayed.
241  * \warning Dicom *doesn't* define any name for any 'categorie'
242  *          (the dictionnary fourth field was formerly NIH defined
243  *           - and no longer he is-
244  *           and will be removed when Dicom provides us a text file
245  *           with the 'official' Dictionnary, that would be more friendly
246  *           than asking us to perform a line by line check of the dictionnary
247  *           at the beginning of each year to -try to- guess the changes)
248  *           Therefore : please NEVER use that fourth field :-(
249  *
250  * @return  An hashtable: whose keys are the names of the groups and whose
251  *          corresponding values are lists of all the dictionnary entries
252  *          among that group.
253  */
254  
255  // Probabely useless
256  
257 //EntryNamesByCatMap *Dict::GetDictEntryNamesByCategory() 
258 //{
259 //   EntryNamesByCatMap *result = new EntryNamesByCatMap;
260 //
261 //   for (TagKeyHT::iterator tag = KeyHt.begin(); tag != KeyHt.end(); ++tag)
262 //   {
263 //      (*result)[tag->second.GetFourth()].push_back(tag->second.GetName());
264 //   }
265 //
266 //   return result;
267 //}
268
269 //-----------------------------------------------------------------------------
270 // Protected
271
272 //-----------------------------------------------------------------------------
273 // Private
274
275 //-----------------------------------------------------------------------------
276
277 } // end namespace gdcm