]> Creatis software - gdcm.git/blob - src/gdcmObject.cxx
Now the tree-like structure describing a DICOMDIR comming from an already
[gdcm.git] / src / gdcmObject.cxx
1 // gdcmObject.cxx
2 //-----------------------------------------------------------------------------
3 #include "gdcmObject.h"
4 #include "gdcmUtil.h"
5
6 //-----------------------------------------------------------------------------
7 // Constructor / Destructor
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(ListTag::iterator i=beginObj;i!=endObj;++i) // JPR
48       for(i=beginObj;;++i) {
49          (*i)->SetPrintLevel(printLevel);
50          (*i)->Print(os);
51          if (i == endObj) break;
52       }
53    }
54 }
55
56 //-----------------------------------------------------------------------------
57 // Public
58 /**
59  * \ingroup gdcmObject
60  * \brief   Get the value of an Header Entries (i.e Dicom Element) by number
61  * @return
62  */ 
63 std::string gdcmObject::GetEntryByNumber(guint16 group, guint16 element) {
64    //for(ListTag::iterator i=beginObj;i!=endObj;++i) // JPR
65    for(ListTag::iterator i=beginObj;;++i) {
66       if ( (*i)->GetGroup()==group && (*i)->GetElement()==element)
67          return (*i)->GetValue();
68       if (i == endObj) break;  
69    }   
70    return GDCM_UNFOUND;
71 }
72
73 /**
74  * \ingroup gdcmObject
75  * \brief   Get the value of an Header Entries (i.e Dicom Element) by name
76  * @param   name : name of the searched element.
77  * @return
78  */ 
79 std::string gdcmObject::GetEntryByName(TagName name)  {
80    gdcmDict *PubDict=gdcmGlobal::GetDicts()->GetDefaultPubDict();
81    gdcmDictEntry *dictEntry = (*PubDict).GetDictEntryByName(name); 
82
83    if( dictEntry == NULL)
84       return GDCM_UNFOUND;
85    return GetEntryByNumber(dictEntry->GetGroup(),dictEntry->GetElement()); 
86 }
87
88 /**
89  * \ingroup gdcmObject
90  * \brief   Set the 'boundaries' gdcmObject (gdcmDicomDirPatient,
91  *          gdcmDicomDirStudy, gdcmDicomDirSerie, gdcmDicomDirImage)
92  *          comming for the parsing of a DICOMDIR file
93  * \warning NOT en user intended function
94  * @param  flag = 0 when META to be dealt with
95  */ 
96 void gdcmObject::ResetBoundaries(int flag) {
97
98    if (flag) { // it's NOT a META
99      // upwards to fffe,e000   
100        for( i=j=debut();
101             ((*i)->GetGroup() != 0xfffe)  && ((*i)->GetElement() != 0x0000);
102             --i,j--) {      
103        }
104       beginObj=j;
105    }
106          
107   // downwards to fffe,e000       
108    for( i=j=fin();
109         ((*i)->GetGroup() != 0xfffe)  && ((*i)->GetElement() != 0x0000);
110         --i,j--) {          
111    }
112    j--;
113    endObj=j;    
114 }
115
116 /**
117  * \ingroup gdcmParser
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    gdcmHeaderEntry *a;
133    for(ListTag::iterator i=beginObj;;++i) { 
134       if ( (*i)->GetGroup() == 0xfffe && (*i)->GetElement() == 0xe000 ) 
135          continue;
136       if ( group   < (*i)->GetGroup() || 
137            (group == (*i)->GetGroup() && element < (*i)->GetElement()) ){
138          // instead of ReplaceOrCreateByNumber 
139          // that is a method of gdcmParser :-( 
140          gdcmHeaderEntry *Entry;
141          TagKey key = gdcmDictEntry::TranslateToKey(group, element);
142          if ( ! ptagHT->count(key)) {
143            // we assume a Public Dictionnary *is* loaded
144            gdcmDict *PubDict         = gdcmGlobal::GetDicts()->GetDefaultPubDict();
145            // if the invoked (group,elem) doesn't exist inside the Dictionary
146            // we create a VirtualDictEntry
147            gdcmDictEntry *DictEntry  = PubDict->GetDictEntryByNumber(group, element);
148            if (DictEntry == NULL) {
149               DictEntry=gdcmGlobal::GetDicts()->NewVirtualDictEntry(group,element,"UN","??","??");
150            } 
151            // we assume the constructor didn't fail
152            Entry = new gdcmHeaderEntry(DictEntry);
153            // ----
154            // TODO
155            // ----
156            // better we don't assume too much !
157            // in the next release, gdcmObject will be used 
158            // to describe any Header Entry ...
159          } else {
160             Entry = ptagHT->find(key)->second;
161          }
162          Entry->SetValue(val); 
163          Entry->SetLength(val.length());
164          plistEntries->insert(i,Entry); 
165          return true;
166       }    
167       if (group == (*i)->GetGroup() && element == (*i)->GetElement() ) {
168          (*i)->SetValue(val);
169          (*i)->SetLength(val.length()); 
170          return true;    
171       }   
172    }                                                
173 }
174 /**
175  * \ingroup gdcmObject
176  * \brief   Builds a hash table (multimap) containing 
177  *          pointers to all Header Entries (i.e Dicom Element)
178  *          related to this 'object'
179  * @return
180  */ 
181 TagHeaderEntryHT gdcmObject::GetEntry(void) {
182    TagHeaderEntryHT HT;
183    //for(ListTag::iterator i=beginObj;i!=endObj;++i) // JPR
184    for(ListTag::iterator i=beginObj;;++i) {
185       HT.insert( PairHT( (*i)->GetKey(),(*i)) );
186       if (i == endObj) break;      
187    }
188    return(HT);
189 }
190
191 /**
192  * \ingroup gdcmObject
193  * \brief   Builds a Chained List containing 
194  *          pointers to all Header Entries (i.e Dicom Element)
195  *          related to this 'object'
196  * @return
197  */ 
198 ListTag gdcmObject::GetListEntry(void) {
199    ListTag list;
200    //for(ListTag::iterator i=beginObj;i!=endObj;++i) // JPR
201    for(ListTag::iterator i=beginObj;;++i) {
202       list.push_back(*i);
203       if (i == endObj) break;      
204    }
205    return(list);
206 }
207
208
209 //-----------------------------------------------------------------------------
210 // Protected
211 /*
212  * \ingroup gdcmObject
213  * \brief   add the 'Object' related Dicom Elements to the listEntries
214  *          of a partially created DICOMDIR
215  */
216 void gdcmObject::FillObject(std::list<gdcmElement> elemList) {
217    std::list<gdcmElement>::iterator it;
218    guint16 tmpGr,tmpEl;
219    gdcmDictEntry *dictEntry;
220    gdcmHeaderEntry *entry;
221       
222    debInsertion = this->fin(); 
223    ++debInsertion;
224    finInsertion=debInsertion;
225    
226    for(it=elemList.begin();it!=elemList.end();++it)
227    {
228       tmpGr=it->group;
229       tmpEl=it->elem;
230       dictEntry=gdcmGlobal::GetDicts()->GetDefaultPubDict()->GetDictEntryByNumber(tmpGr,tmpEl);
231       entry=new gdcmHeaderEntry(dictEntry);
232       entry->SetOffset(0); // just to avoid missprinting //JPR
233       entry->SetValue(it->value);
234
235       if(dictEntry->GetGroup()==0xfffe) 
236          {
237             entry->SetLength(entry->GetValue().length());        
238          }
239       else if( (dictEntry->GetVR()=="UL") || (dictEntry->GetVR()=="SL") ) 
240          {
241             entry->SetLength(4);
242          } 
243       else if( (dictEntry->GetVR()=="US") || (dictEntry->GetVR()=="SS") ) 
244          {
245             entry->SetLength(2); 
246          } 
247       else if(dictEntry->GetVR()=="SQ") 
248          {
249             entry->SetLength(0xffffffff);
250          }
251       else
252          {
253             entry->SetLength(entry->GetValue().length());        
254          }                                
255       ptagHT->insert( PairHT(entry->GetKey(),entry) ); // add in the (multimap) H Table
256       plistEntries->insert(debInsertion ,entry);       // en tete de liste des Patients
257       ++finInsertion;                                      
258    }
259      
260    i=fin();
261    i++;
262    j=debInsertion;
263    j--;
264 }   
265 //-----------------------------------------------------------------------------
266 // Private
267
268 //-----------------------------------------------------------------------------