]> Creatis software - gdcm.git/blob - src/gdcmElementSet.cxx
BUG: Apparently on Borland uses unsigned char to store boolean, all other plateformns...
[gdcm.git] / src / gdcmElementSet.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmElementSet.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/02/05 01:37:08 $
7   Version:   $Revision: 1.56 $
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 // Constructor / Destructor
29 /**
30  * \brief   Constructor for a given ElementSet
31  */
32 //BOZ depthLevel is not usefull anymore
33 ElementSet::ElementSet(int depthLevel) 
34               : DocEntrySet()
35 {
36   (void)depthLevel;
37 }
38
39 /**
40  * \brief   Canonical destructor.
41  */
42 ElementSet::~ElementSet() 
43 {
44    ClearEntry();
45 }
46
47 //-----------------------------------------------------------------------------
48 // Public
49 /**
50   * \brief   Writes the Header Entries (Dicom Elements)
51   *          from the H Table
52   * @param fp ofstream to write to  
53   * @param filetype filetype
54   */ 
55 void ElementSet::WriteContent(std::ofstream *fp, FileType filetype)
56 {
57    for (TagDocEntryHT::const_iterator i = TagHT.begin(); 
58                                      i != TagHT.end(); 
59                                     ++i)
60    {
61       i->second->WriteContent(fp, filetype);
62    } 
63 }
64
65 /**
66  * \brief   add a new Dicom Element pointer to the H Table
67  * @param   newEntry entry to add
68  */
69 bool ElementSet::AddEntry(DocEntry *newEntry)
70 {
71    const TagKey &key = newEntry->GetKey();
72
73    if( TagHT.count(key) == 1 )
74    {
75       gdcmWarningMacro( "Key already present: " << key.c_str());
76       return false;
77    }
78    else
79    {
80       TagHT.insert(TagDocEntryHT::value_type(newEntry->GetKey(), newEntry));
81       return true;
82    }
83 }
84
85 /**
86  * \brief   Clear the hash table from given entry AND delete the entry.
87  * @param   entryToRemove Entry to remove AND delete.
88  */
89 bool ElementSet::RemoveEntry( DocEntry *entryToRemove)
90 {
91    const TagKey &key = entryToRemove->GetKey();
92    if( TagHT.count(key) == 1 )
93    {
94       TagHT.erase(key);
95       //gdcmWarningMacro( "One element erased.");
96       delete entryToRemove;
97       return true;
98    }
99
100    gdcmWarningMacro( "Key not present");
101    return false ;
102 }
103
104 /**
105  * \brief   Clear the hash table from given entry BUT keep the entry.
106  * @param   entryToRemove Entry to remove.
107  */
108 bool ElementSet::RemoveEntryNoDestroy(DocEntry *entryToRemove)
109 {
110    const TagKey &key = entryToRemove->GetKey();
111    if( TagHT.count(key) == 1 )
112    {
113       TagHT.erase(key);
114       //gdcmWarningMacro( "One element erased.");
115       return true;
116    }
117
118    gdcmWarningMacro( "Key not present");
119    return false ;
120 }
121
122 /**
123  * \brief   delete all entries in the ElementSet
124  */
125 void ElementSet::ClearEntry()
126 {
127    for(TagDocEntryHT::iterator cc = TagHT.begin();cc != TagHT.end(); ++cc)
128    {
129       if ( cc->second )
130       {
131          delete cc->second;
132       }
133    }
134    TagHT.clear();
135 }
136
137 /**
138  * \brief   Get the first entry while visiting *the* 'zero level' DocEntrySet
139  *              (DocEntries out of any Sequence)
140  * \return  The first DocEntry if found, otherwhise NULL
141  */
142 DocEntry *ElementSet::GetFirstEntry()
143 {
144    ItTagHT = TagHT.begin();
145    if (ItTagHT != TagHT.end())
146       return  ItTagHT->second;
147    return NULL;
148 }
149
150 /**
151  * \brief   Get the next entry while visiting *the* 'zero level' DocEntrySet
152  *              (DocEntries out of any Sequence) 
153  * \note : meaningfull only if GetFirstEntry already called 
154  * \return  The next DocEntry if found, otherwhise NULL
155  */
156 DocEntry *ElementSet::GetNextEntry()
157 {
158    gdcmAssertMacro (ItTagHT != TagHT.end());
159
160    ++ItTagHT;
161    if (ItTagHT != TagHT.end())
162       return  ItTagHT->second;
163    return NULL;
164 }
165
166 /**
167  * \brief   Get the first ValEntry while visiting *the* 'zero level' DocEntrySet
168  *              (DocEntries out of any Sequence)
169  *              This method is designed for Python users
170  * \return  The first ValEntry if found, otherwhise NULL
171  */
172 ValEntry *ElementSet::GetFirstValEntry()
173 {
174    gdcm::ValEntry *valEntry;
175    gdcm::DocEntry *d = GetFirstEntry();
176    // an other iterator is needed to allow user iterate 
177    // at the same time both on DocEntries and ValEntries 
178    ItValEntryTagHT = ItTagHT;
179    if ( (valEntry = dynamic_cast<gdcm::ValEntry*>(d)))
180       return valEntry;
181    return  GetNextValEntry();  
182 }
183
184 /**
185  * \brief   Get the next ValEntry while visiting *the* 'zero level' DocEntrySet
186  *              (DocEntries out of any Sequence) 
187  * \note : meaningfull only if GetFirstValEntry already called 
188  * \return  The next ValEntry if found, otherwhise NULL
189  */
190 ValEntry *ElementSet::GetNextValEntry()
191 {
192    gdcm::ValEntry *valEntry;
193    gdcm::DocEntry *d = ItValEntryTagHT->second;
194    ++ItValEntryTagHT; 
195    while( d )
196    {
197       if ( (valEntry = dynamic_cast<gdcm::ValEntry*>(d)))
198          return valEntry;
199       else
200          return GetNextValEntry(); 
201    }
202    return 0;
203 }
204
205 /**
206  * \brief  retrieves a Dicom Element using (group, element)
207  * @param   group  Group number of the searched Dicom Element 
208  * @param   elem Element number of the searched Dicom Element 
209  * @return  
210  */
211 DocEntry *ElementSet::GetDocEntry(uint16_t group, uint16_t elem) 
212 {
213    TagKey key = DictEntry::TranslateToKey(group, elem);
214    TagDocEntryHT::iterator it = TagHT.find(key);
215
216    if ( it!=TagHT.end() )
217       return it->second;
218    return NULL;
219 }
220
221 //-----------------------------------------------------------------------------
222 // Protected
223
224 //-----------------------------------------------------------------------------
225 // Private
226
227 //-----------------------------------------------------------------------------
228 // Print
229 /**
230   * \brief   Prints the Header Entries (Dicom Elements) from the H Table
231   * @param os ostream to write to  
232   * @param indent Indentation string to be prepended during printing
233   */ 
234 void ElementSet::Print(std::ostream &os, std::string const & )
235 {
236    for( TagDocEntryHT::const_iterator i = TagHT.begin(); i != TagHT.end(); ++i)
237    {
238       DocEntry* entry = i->second;
239
240       entry->SetPrintLevel(PrintLevel);
241       entry->Print(os);   
242
243       if ( dynamic_cast<SeqEntry*>(entry) )
244       {
245          // Avoid the newline for a sequence:
246          continue;
247       }
248       os << std::endl;
249    }
250 }
251
252 //-----------------------------------------------------------------------------
253 } // end namespace gdcm