]> Creatis software - gdcm.git/blob - src/gdcmObject.cxx
BUG: JP suggest me to do this change
[gdcm.git] / src / gdcmObject.cxx
1 // gdcmObject.cxx
2 //-----------------------------------------------------------------------------
3 #include "gdcmObject.h"
4 #include "gdcmGlobal.h"
5 #include "gdcmDebug.h"
6
7 //-----------------------------------------------------------------------------
8 /**
9  * \ingroup gdcmObject
10  * \brief  Constructor 
11  * @param  begin  iterator on the first Header Entry (i.e Dicom Element)
12  *                related to this 'Object'
13  * @param  end  iterator on the last Header Entry 
14  *              (i.e Dicom Element) related to this 'Object'             
15  * @param ptagHT pointer to the HTable (gdcmObject needs it 
16  *               to build the gdcmHeaderEntries)
17  * @param plistEntries pointer to the chained List (gdcmObject needs it 
18  *               to build the gdcmHeaderEntries)
19  */
20 gdcmObject::gdcmObject(ListTag::iterator begin, ListTag::iterator end,
21               TagHeaderEntryHT *ptagHT, ListTag *plistEntries) {
22    beginObj = begin;
23    endObj   = end;
24    this->ptagHT = ptagHT;
25    this->plistEntries = plistEntries;
26    if(begin==end)
27       dbg.Verbose(0, "gdcmObject::gdcmObject empty list");
28 }
29
30 /**
31  * \ingroup gdcmObject
32  * \brief   Canonical destructor.
33  */
34 gdcmObject::~gdcmObject(void) {
35 }
36
37 //-----------------------------------------------------------------------------
38 // Print
39 /**
40  * \ingroup gdcmObject
41  * \brief   Prints the Object
42  * @return
43  */ 
44 void gdcmObject::Print(std::ostream &os) {
45    if(printLevel>=0) {
46       ListTag::iterator i;
47       for(i=beginObj;;++i) {
48          (*i)->SetPrintLevel(printLevel);
49          (*i)->Print(os);
50          if (i == endObj) break;
51       }
52    }
53 }
54
55 //-----------------------------------------------------------------------------
56 // Public
57 /**
58  * \ingroup gdcmObject
59  * \brief   Get the value of an Header Entries (i.e Dicom Element) by number
60  * @return
61  */ 
62 std::string gdcmObject::GetEntryByNumber(guint16 group, guint16 element) {
63    for(ListTag::iterator i=beginObj;;++i) {
64       if ( (*i)->GetGroup()==group && (*i)->GetElement()==element)
65          return (*i)->GetValue();
66       if (i == endObj) break;  
67    }   
68    return GDCM_UNFOUND;
69 }
70
71 /**
72  * \ingroup gdcmObject
73  * \brief   Get the value of an Header Entries (i.e Dicom Element) by name
74  * @param   name : name of the searched element.
75  * @return
76  */ 
77 std::string gdcmObject::GetEntryByName(TagName name)  {
78    gdcmDict *PubDict=gdcmGlobal::GetDicts()->GetDefaultPubDict();
79    gdcmDictEntry *dictEntry = (*PubDict).GetDictEntryByName(name); 
80
81    if( dictEntry == NULL)
82       return GDCM_UNFOUND;
83    return GetEntryByNumber(dictEntry->GetGroup(),dictEntry->GetElement()); 
84 }
85
86 /**
87  * \ingroup gdcmObject
88  * \brief   Set the 'boundaries' gdcmObject (gdcmDicomDirPatient,
89  *          gdcmDicomDirStudy, gdcmDicomDirSerie, gdcmDicomDirImage)
90  *          comming for the parsing of a DICOMDIR file
91  * \warning NOT en user intended function
92  * @param  flag = 0 when META to be dealt with
93  */ 
94 void gdcmObject::ResetBoundaries(int flag) {
95    
96    if (flag) { // it's NOT a META
97      // upwards to fffe,e000   
98       for( i=j=debut();
99           ((*i)->GetGroup() != 0xfffe)  && ((*i)->GetElement() != 0xe000);
100           --i,j--) {   
101       }
102       beginObj=j;
103    }
104          
105   // upwards again to fffe,e000   
106    if (fin()== (--(plistEntries->end())) )  // Don't try anything more when end 
107        return;                              // of Chained List is reached   
108                                            
109    for( i=j=fin();
110         ((*i)->GetGroup() != 0xfffe)  && ((*i)->GetElement() != 0xe000);
111         --i,j--) {          
112    }
113    j--;
114    endObj=j;    
115 }
116
117 /**
118  * \brief   Sets Entry (Dicom Element) value of an element,
119  *          specified by it's tag (Group, Number) 
120  *          and the length, too ...
121  *          If the Element is not found, it's just created !
122  * \warning we suppose, right now, the element belongs to a Public Group
123  *          (NOT a shadow one)       
124  * @param   val string value to set
125  * @param   group Group of the searched tag.
126  * @param   element Element of the searched tag.
127  * @return  true if element was found or created successfully
128  */
129  bool gdcmObject::SetEntryByNumber(std::string val,guint16 group, 
130                                                    guint16 element) {
131
132    for(ListTag::iterator i=beginObj;;++i) { 
133       if ( (*i)->GetGroup() == 0xfffe && (*i)->GetElement() == 0xe000 ) 
134          continue;
135       if ( group   < (*i)->GetGroup() || 
136            (group == (*i)->GetGroup() && element < (*i)->GetElement()) ){
137          // instead of ReplaceOrCreateByNumber 
138          // that is a method of gdcmParser :-( 
139          gdcmHeaderEntry *Entry;
140          TagKey key = gdcmDictEntry::TranslateToKey(group, element);
141          if ( ! ptagHT->count(key)) {
142            // we assume a Public Dictionnary *is* loaded
143            gdcmDict *PubDict         = gdcmGlobal::GetDicts()->GetDefaultPubDict();
144            // if the invoked (group,elem) doesn't exist inside the Dictionary
145            // we create a VirtualDictEntry
146            gdcmDictEntry *DictEntry  = PubDict->GetDictEntryByNumber(group, element);
147            if (DictEntry == NULL) {
148               DictEntry=gdcmGlobal::GetDicts()->NewVirtualDictEntry(group,element,"UN","??","??");
149            } 
150            // we assume the constructor didn't fail
151            Entry = new gdcmHeaderEntry(DictEntry);
152            /// \todo
153            /// ----
154            /// better we don't assume too much !
155            /// in the next release, gdcmObject will be used 
156            /// to describe any Header Entry ...
157          } else {
158             Entry = ptagHT->find(key)->second;
159          }
160          Entry->SetValue(val); 
161          Entry->SetLength(val.length());
162          plistEntries->insert(i,Entry); 
163          return true;
164       }    
165       if (group == (*i)->GetGroup() && element == (*i)->GetElement() ) {
166          (*i)->SetValue(val);
167          (*i)->SetLength(val.length()); 
168          return true;    
169       }   
170    }                                                
171 }
172 /**
173  * \ingroup gdcmObject
174  * \brief   Builds a hash table (multimap) containing 
175  *          pointers to all Header Entries (i.e Dicom Element)
176  *          related to this 'object'
177  * @return
178  */ 
179 TagHeaderEntryHT gdcmObject::GetEntry(void) {
180    TagHeaderEntryHT HT;
181    for(ListTag::iterator i=beginObj;;++i) {
182       HT.insert( PairHT( (*i)->GetKey(),(*i)) );
183       if (i == endObj) break;      
184    }
185    return(HT);
186 }
187
188 /**
189  * \ingroup gdcmObject
190  * \brief   Builds a Chained List containing 
191  *          pointers to all Header Entries (i.e Dicom Element)
192  *          related to this 'object'
193  * @return
194  */ 
195 ListTag gdcmObject::GetListEntry(void) {
196    ListTag list;
197    for(ListTag::iterator i=beginObj;;++i) {
198       list.push_back(*i);
199       if (i == endObj) break;      
200    }
201    return(list);
202 }
203
204
205 //-----------------------------------------------------------------------------
206 // Protected
207 /**
208  * \ingroup gdcmObject
209  * \brief   add the 'Object' related Dicom Elements to the listEntries
210  *          of a partially created DICOMDIR
211  */
212 void gdcmObject::FillObject(std::list<gdcmElement> elemList) {
213    std::list<gdcmElement>::iterator it;
214    guint16 tmpGr,tmpEl;
215    gdcmDictEntry *dictEntry;
216    gdcmHeaderEntry *entry;
217       
218    debInsertion = this->fin(); 
219    ++debInsertion;
220    finInsertion=debInsertion;
221    
222    for(it=elemList.begin();it!=elemList.end();++it)
223    {
224       tmpGr=it->group;
225       tmpEl=it->elem;
226       dictEntry=gdcmGlobal::GetDicts()->GetDefaultPubDict()->GetDictEntryByNumber(tmpGr,tmpEl);
227       entry=new gdcmHeaderEntry(dictEntry);
228       entry->SetOffset(0); // just to avoid further missprinting
229       entry->SetValue(it->value);
230
231       if(dictEntry->GetGroup()==0xfffe) 
232          {
233             entry->SetLength(entry->GetValue().length());        
234          }
235       else if( (dictEntry->GetVR()=="UL") || (dictEntry->GetVR()=="SL") ) 
236          {
237             entry->SetLength(4);
238          } 
239       else if( (dictEntry->GetVR()=="US") || (dictEntry->GetVR()=="SS") ) 
240          {
241             entry->SetLength(2); 
242          } 
243       else if(dictEntry->GetVR()=="SQ") 
244          {
245             entry->SetLength(0xffffffff);
246          }
247       else
248          {
249             entry->SetLength(entry->GetValue().length());        
250          }                                
251       ptagHT->insert( PairHT(entry->GetKey(),entry) ); // add in the (multimap) H Table
252       plistEntries->insert(debInsertion ,entry);       // add at the begining of the Patient list
253       ++finInsertion;                                      
254    }
255      
256    i=fin();
257    i++;
258    j=debInsertion;
259    j--;
260 }   
261 //-----------------------------------------------------------------------------
262 // Private
263
264 //-----------------------------------------------------------------------------