]> Creatis software - gdcm.git/blob - src/gdcmSQItem.cxx
ENH: Minor patch, cosmetic -again-. Remove all this->. I might have discover the...
[gdcm.git] / src / gdcmSQItem.cxx
1 /*=========================================================================
2   
3   Program:   gdcm
4   Module:    $RCSfile: gdcmSQItem.cxx,v $
5   Language:  C++
6   Date:      $Date: 2004/08/01 00:59:21 $
7   Version:   $Revision: 1.22 $
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.htm 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 "gdcmSQItem.h"
20 #include "gdcmSeqEntry.h"
21 #include "gdcmValEntry.h"
22 #include "gdcmBinEntry.h"
23 #include "gdcmGlobal.h"
24 #include "gdcmUtil.h"
25
26 #include "gdcmDebug.h"
27
28
29 //-----------------------------------------------------------------------------
30 // Constructor / Destructor
31 /**
32  * \ingroup gdcmSQItem
33  * \brief   Constructor from a given gdcmSQItem
34  */
35 gdcmSQItem::gdcmSQItem(int depthLevel ) 
36           : gdcmDocEntrySet(depthLevel)
37 {
38    SQDepthLevel = depthLevel +1;
39 }
40
41 /**
42  * \brief   Canonical destructor.
43  */
44 gdcmSQItem::~gdcmSQItem() 
45 {
46    for(ListDocEntry::iterator cc = docEntries.begin();
47        cc != docEntries.end();
48        ++cc)
49    {
50       delete (*cc);
51    }
52    docEntries.clear();
53 }
54
55 //-----------------------------------------------------------------------------
56 // Print
57 /*
58  * \brief   canonical Printer
59  */
60  void gdcmSQItem::Print(std::ostream & os)
61  {
62    std::ostringstream s;
63
64    if (SQDepthLevel > 0)
65    {
66       for (int i = 0; i < SQDepthLevel; ++i)
67       {
68          s << "   | " ;
69       }
70    }
71    std::cout << s.str() << " --- SQItem number " << SQItemNumber  << std::endl;
72    for (ListDocEntry::iterator i  = docEntries.begin();
73                                i != docEntries.end();
74                              ++i)
75    {
76       gdcmDocEntry* Entry = *i;
77       bool PrintEndLine = true;
78
79       os << s.str();
80       Entry->SetPrintLevel(2);
81       Entry->Print(os);   
82       if ( gdcmSeqEntry* SeqEntry = dynamic_cast<gdcmSeqEntry*>(Entry) )
83       {
84          (void)SeqEntry;  //not used
85          PrintEndLine = false;
86       }
87       if (PrintEndLine)
88       {
89          os << std::endl;
90       }
91    } 
92 }
93
94 /*
95  * \ingroup gdcmSQItem
96  * \brief   canonical Writer
97  */
98 void gdcmSQItem::Write(FILE *fp,FileType filetype)
99 {
100    for (ListDocEntry::iterator i = docEntries.begin();  
101         i != docEntries.end();
102         ++i)
103    {
104       // Item Delimitor Item IS the last one of a 'no length' SQItem
105       // (when it exists) we don't write it right now
106       // It will be written outside, because ALL the SQItems are written
107       // as 'no length'
108       if ( (*i)->isItemDelimitor() )
109       {
110          break;
111       }
112
113       // Fix in order to make some MR PHILIPS images e-film readable
114       // see gdcmData/gdcm-MR-PHILIPS-16-Multi-Seq.dcm:
115       // we just *always* ignore spurious fffe|0000 tag ! 
116       if ( (*i)->GetGroup() == 0xfffe && (*i)->GetElement() == 0x0000 )
117       {
118          break;
119       }
120
121       // It's up to the gdcmDocEntry Writter to write the SQItem begin element
122       // (fffe|e000) as a 'no length' one
123       (*i)->Write(fp, filetype);
124    } 
125 }
126
127 //-----------------------------------------------------------------------------
128 // Public
129 /**
130  * \brief   adds any Entry (Dicom Element) to the Sequence Item
131  */
132 bool gdcmSQItem::AddEntry(gdcmDocEntry *entry)
133 {
134    docEntries.push_back(entry);
135    //TODO : check if it worked
136    return true;
137 }   
138
139 /**
140  * \brief   Sets Entry (Dicom Element) value of an element,
141  *          specified by it's tag (Group, Number) 
142  *          and the length, too ...  inside a SQ Item
143  *          If the Element is not found, it's just created !
144  * \warning we suppose, right now, the element belongs to a Public Group
145  *          (NOT a shadow one)       
146  * @param   val string value to set
147  * @param   group Group number of the searched tag.
148  * @param   element Element number of the searched tag.
149  * @return  true if element was found or created successfully
150  */
151
152 bool gdcmSQItem::SetEntryByNumber(std::string val,uint16_t group, 
153                                   uint16_t element)
154 {
155    for(ListDocEntry::iterator i = docEntries.begin(); i != docEntries.end(); ++i)
156    { 
157       if ( (*i)->GetGroup() == 0xfffe && (*i)->GetElement() == 0xe000 ) 
158       {
159          continue;
160       }
161
162       if (  ( group   < (*i)->GetGroup() )
163           ||( group == (*i)->GetGroup() && element < (*i)->GetElement()) )
164       {
165          // instead of ReplaceOrCreateByNumber 
166          // that is a method of gdcmDocument :-( 
167          gdcmValEntry* entry = 0;
168          gdcmTagKey key = gdcmDictEntry::TranslateToKey(group, element);
169
170          if ( ! PtagHT->count(key))
171          {
172             // we assume a Public Dictionnary *is* loaded
173             gdcmDict *pubDict = gdcmGlobal::GetDicts()->GetDefaultPubDict();
174             // if the invoked (group,elem) doesn't exist inside the Dictionary
175             // we create a VirtualDictEntry
176             gdcmDictEntry *dictEntry = pubDict->GetDictEntryByNumber(group,
177                                                                      element);
178             if (dictEntry == NULL)
179             {
180                dictEntry = 
181                   gdcmGlobal::GetDicts()->NewVirtualDictEntry(group, element,
182                                                               "UN", "??", "??");
183             } 
184             // we assume the constructor didn't fail
185             entry = new gdcmValEntry(dictEntry);
186             /// \todo
187             /// ----
188             /// better we don't assume too much !
189             /// gdcmSQItem is now used to describe any DICOMDIR related object
190          }
191          else
192          {
193             gdcmDocEntry* foundEntry = PtagHT->find(key)->second;
194             entry = dynamic_cast<gdcmValEntry*>(foundEntry);
195             if (!entry)
196             {
197                dbg.Verbose(0, "gdcmSQItem::SetEntryByNumber: docEntries"
198                               " contains non gdcmValEntry occurences");
199             }
200          }
201          if (entry)
202          {
203             entry->SetValue(val); 
204          }
205          entry->SetLength(val.length());
206          docEntries.insert(i,entry);
207
208          return true;
209       }   
210       if (group == (*i)->GetGroup() && element == (*i)->GetElement() )
211       {
212          if ( gdcmValEntry* entry = dynamic_cast<gdcmValEntry*>(*i) )
213          {
214             entry->SetValue(val);
215          }
216          (*i)->SetLength(val.length()); 
217          return true;    
218       }
219    }
220    return false;
221 }
222 //-----------------------------------------------------------------------------
223 // Protected
224
225
226 /**
227  * \brief   Gets a Dicom Element inside a SQ Item Entry, by number
228  * @return
229  */
230 gdcmDocEntry *gdcmSQItem::GetDocEntryByNumber(uint16_t group, uint16_t element)
231 {
232    for(ListDocEntry::iterator i = docEntries.begin();
233                               i != docEntries.end(); ++i)
234    {
235       if ( (*i)->GetGroup() == group && (*i)->GetElement() == element )
236       {
237          return *i;
238       }
239    }
240    return 0;
241 }
242
243 /**
244  * \brief   Get the value of a Dicom Element inside a SQ Item Entry, by number
245  * @return
246  */ 
247
248 std::string gdcmSQItem::GetEntryByNumber(uint16_t group, uint16_t element)
249 {
250    for(ListDocEntry::iterator i = docEntries.begin();
251                               i != docEntries.end(); ++i)
252    {
253       if ( (*i)->GetGroup() == group && (*i)->GetElement() == element)
254       {
255          return ((gdcmValEntry *)(*i))->GetValue();   //FIXME
256       }
257    }
258    return GDCM_UNFOUND;
259 }
260 //-----------------------------------------------------------------------------
261 // Private
262
263
264 //-----------------------------------------------------------------------------