]> Creatis software - gdcm.git/blob - src/gdcmElementSet.cxx
* src/gdcmDocument.cxx : bug fix on potential memory leak
[gdcm.git] / src / gdcmElementSet.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmElementSet.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/01/25 11:11:59 $
7   Version:   $Revision: 1.50 $
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 "gdcmElementSet.h"
20 #include "gdcmDebug.h"
21 #include "gdcmValEntry.h"
22 #include "gdcmBinEntry.h"
23 #include "gdcmSeqEntry.h"
24
25 namespace gdcm 
26 {
27
28 //-----------------------------------------------------------------------------
29 // Constructor / Destructor
30 /**
31  * \brief   Constructor for a given ElementSet
32  */
33 //BOZ depthLevel is not usefull anymore
34 ElementSet::ElementSet(int depthLevel) 
35               : DocEntrySet()
36 {
37   (void)depthLevel;
38 }
39
40 /**
41  * \brief   Canonical destructor.
42  */
43 ElementSet::~ElementSet() 
44 {
45    ClearEntry();
46 }
47
48 //-----------------------------------------------------------------------------
49 // Print
50 /**
51   * \brief   Prints the Header Entries (Dicom Elements) from the H Table
52   * @param os ostream to write to  
53   * @param indent Indentation string to be prepended during printing
54   */ 
55 void ElementSet::Print(std::ostream &os, std::string const & )
56 {
57    for( TagDocEntryHT::const_iterator i = TagHT.begin(); i != TagHT.end(); ++i)
58    {
59       DocEntry* entry = i->second;
60
61       entry->SetPrintLevel(PrintLevel);
62       entry->Print(os);   
63
64       if ( dynamic_cast<SeqEntry*>(entry) )
65       {
66          // Avoid the newline for a sequence:
67          continue;
68       }
69       os << std::endl;
70    }
71 }
72
73 //-----------------------------------------------------------------------------
74 // Public
75 /**
76   * \brief   Writes the Header Entries (Dicom Elements)
77   *          from the H Table
78   * @param fp ofstream to write to  
79   * @param filetype filetype
80   */ 
81 void ElementSet::WriteContent(std::ofstream *fp, FileType filetype)
82 {
83    for (TagDocEntryHT::const_iterator i = TagHT.begin(); 
84                                      i != TagHT.end(); 
85                                     ++i)
86    {
87       i->second->WriteContent(fp, filetype);
88    } 
89 }
90
91 /**
92  * \brief  retrieves a Dicom Element using (group, element)
93  * @param   group  Group number of the searched Dicom Element 
94  * @param   elem Element number of the searched Dicom Element 
95  * @return  
96  */
97 DocEntry *ElementSet::GetDocEntry(uint16_t group, uint16_t elem) 
98 {
99    TagKey key = DictEntry::TranslateToKey(group, elem);
100    if ( !TagHT.count(key))
101    {
102       return NULL;
103    }
104    return TagHT.find(key)->second;
105 }
106
107 /**
108  * \brief  Same as \ref Document::GetDocEntry except it only
109  *         returns a result when the corresponding entry is of type
110  *         ValEntry.
111  * @param   group  Group number of the searched Dicom Element 
112  * @param   elem Element number of the searched Dicom Element  
113  * @return When present, the corresponding ValEntry. 
114  */
115 ValEntry *ElementSet::GetValEntry(uint16_t group, uint16_t elem)
116 {
117    DocEntry *currentEntry = GetDocEntry(group, elem);
118    if ( !currentEntry )
119    {
120       return 0;
121    }
122    if ( ValEntry *entry = dynamic_cast<ValEntry*>(currentEntry) )
123    {
124       return entry;
125    }
126    gdcmVerboseMacro( "Unfound ValEntry.");
127
128    return 0;
129 }
130
131 /**
132  * \brief  Same as \ref Document::GetDocEntry except it only
133  *         returns a result when the corresponding entry is of type
134  *         BinEntry.
135  * @param   group  Group number of the searched Dicom Element 
136  * @param   elem Element number of the searched Dicom Element  
137  * @return When present, the corresponding BinEntry. 
138  */
139 BinEntry *ElementSet::GetBinEntry(uint16_t group, uint16_t elem)
140 {
141    DocEntry *currentEntry = GetDocEntry(group, elem);
142    if ( !currentEntry )
143    {
144       return 0;
145    }
146    if ( BinEntry *entry = dynamic_cast<BinEntry*>(currentEntry) )
147    {
148       return entry;
149    }
150    gdcmVerboseMacro( "Unfound BinEntry.");
151
152    return 0;
153 }
154
155 /**
156  * \brief  Same as \ref Document::GetDocEntry except it only
157  *         returns a result when the corresponding entry is of type
158  *         SeqEntry.
159  * @param   group  Group number of the searched Dicom Element 
160  * @param   elem Element number of the searched Dicom Element  
161  * @return When present, the corresponding SeqEntry. 
162  */
163 SeqEntry *ElementSet::GetSeqEntry(uint16_t group, uint16_t elem)
164 {
165    DocEntry *currentEntry = GetDocEntry(group, elem);
166    if ( !currentEntry )
167    {
168       return 0;
169    }
170    if ( SeqEntry *entry = dynamic_cast<SeqEntry*>(currentEntry) )
171    {
172       return entry;
173    }
174    gdcmVerboseMacro( "Unfound SeqEntry.");
175
176    return 0;
177 }
178
179 /**
180  * \brief   Checks if a given Dicom Element exists within the H table
181  * @param   group   Group number of the searched Dicom Element 
182  * @param   elem  Element number of the searched Dicom Element 
183  * @return true is found
184  */
185 bool ElementSet::CheckIfEntryExist(uint16_t group, uint16_t elem )
186 {
187    const std::string &key = DictEntry::TranslateToKey(group, elem );
188    return TagHT.count(key) != 0;
189 }
190
191 /**
192  * \brief   Get the (std::string representable) value of the Dicom entry
193  * @param   group  Group number of the searched tag.
194  * @param   elem Element number of the searched tag.
195  * @return  Corresponding element value when it exists,
196  *          and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
197  */
198 std::string ElementSet::GetEntryValue(uint16_t group, uint16_t elem)
199 {
200    TagKey key = DictEntry::TranslateToKey(group, elem);
201    if ( !TagHT.count(key))
202    {
203       return GDCM_UNFOUND;
204    }
205
206    return ((ValEntry *)TagHT.find(key)->second)->GetValue();
207 }
208
209 /**
210  * \brief   delete all entries in the ElementSet
211  */
212 void ElementSet::ClearEntry()
213 {
214    for(TagDocEntryHT::iterator cc = TagHT.begin();cc != TagHT.end(); ++cc)
215    {
216       if ( cc->second )
217       {
218          delete cc->second;
219       }
220    }
221    TagHT.clear();
222 }
223
224 /**
225  * \brief   add a new Dicom Element pointer to the H Table
226  * @param   newEntry entry to add
227  */
228 bool ElementSet::AddEntry(DocEntry *newEntry)
229 {
230    const TagKey &key = newEntry->GetKey();
231
232    if( TagHT.count(key) == 1 )
233    {
234       gdcmVerboseMacro( "Key already present: " << key.c_str());
235       return false;
236    }
237    else
238    {
239       TagHT.insert(TagDocEntryHT::value_type(newEntry->GetKey(), newEntry));
240       return true;
241    }
242 }
243
244 /**
245  * \brief   Clear the hash table from given entry AND delete the entry.
246  * @param   entryToRemove Entry to remove AND delete.
247  */
248 bool ElementSet::RemoveEntry( DocEntry *entryToRemove)
249 {
250    const TagKey &key = entryToRemove->GetKey();
251    if( TagHT.count(key) == 1 )
252    {
253       TagHT.erase(key);
254       //gdcmVerboseMacro( "One element erased.");
255       delete entryToRemove;
256       return true;
257    }
258
259    gdcmVerboseMacro( "Key not present");
260    return false ;
261 }
262
263 /**
264  * \brief   Clear the hash table from given entry BUT keep the entry.
265  * @param   entryToRemove Entry to remove.
266  */
267 bool ElementSet::RemoveEntryNoDestroy(DocEntry *entryToRemove)
268 {
269    const TagKey &key = entryToRemove->GetKey();
270    if( TagHT.count(key) == 1 )
271    {
272       TagHT.erase(key);
273       //gdcmVerboseMacro( "One element erased.");
274       return true;
275    }
276
277    gdcmVerboseMacro( "Key not present");
278    return false ;
279 }
280
281 /**
282  * \brief   Get the first entry while visiting the DocEntrySet
283  * \return  The first DocEntry if found, otherwhise NULL
284  */
285 DocEntry *ElementSet::GetFirstEntry()
286 {
287    ItTagHT = TagHT.begin();
288    if (ItTagHT != TagHT.end())
289       return  ItTagHT->second;
290    return NULL;
291 }
292
293 /**
294  * \brief   Get the next entry while visiting the Hash table (TagHT)
295  * \note : meaningfull only if GetFirstEntry already called 
296  * \return  The next DocEntry if found, otherwhise NULL
297  */
298 DocEntry *ElementSet::GetNextEntry()
299 {
300    gdcmAssertMacro (ItTagHT != TagHT.end());
301
302    ++ItTagHT;
303    if (ItTagHT != TagHT.end())
304       return  ItTagHT->second;
305    return NULL;
306 }
307
308 /**
309  * \brief   Get the larst entry while visiting the DocEntrySet
310  * \return  The last DocEntry if found, otherwhise NULL
311  */
312 DocEntry *ElementSet::GetLastEntry()
313 {
314    ItTagHT = TagHT.end();
315    if ( ItTagHT != TagHT.begin() )
316       return  ItTagHT->second;
317    return NULL;
318 }
319
320 /**
321  * \brief   Get the previous entry while visiting the Hash table (TagHT)
322  * \note : meaningfull only if GetFirstEntry already called 
323  * \return  The previous DocEntry if found, otherwhise NULL
324  */
325 DocEntry *ElementSet::GetPreviousEntry()
326 {
327    gdcmAssertMacro (ItTagHT != TagHT.begin());
328
329    --ItTagHT;
330    if (ItTagHT != TagHT.begin())
331       return  ItTagHT->second;
332    return NULL;
333 }
334
335 //-----------------------------------------------------------------------------
336 // Protected
337
338 //-----------------------------------------------------------------------------
339 // Private
340
341 //-----------------------------------------------------------------------------
342 } // end namespace gdcm