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