1 /*
2  *
3  *  Copyright (C) 1998-2010, OFFIS e.V.
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation were developed by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *
14  *  Module: dcmpstat
15  *
16  *  Author: Marco Eichelberg
17  *
18  *  Purpose:
19  *    classes: DVPSReferencedSeries_PList
20  *
21  */
22 
23 #include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
24 #include "dcmtk/dcmdata/dcdeftag.h"
25 #include "dcmtk/dcmdata/dcsequen.h"
26 #include "dcmtk/dcmpstat/dvpsrsl.h"
27 #include "dcmtk/dcmpstat/dvpsrs.h"      /* for DVPSReferencedSeries */
28 #include "dcmtk/dcmpstat/dvpsri.h"      /* for DVPSReferencedImage, needed by MSVC5 with STL */
29 #include "dcmtk/dcmpstat/dvpsdef.h"
30 
DVPSReferencedSeries_PList()31 DVPSReferencedSeries_PList::DVPSReferencedSeries_PList()
32 : list_()
33 {
34 }
35 
DVPSReferencedSeries_PList(const DVPSReferencedSeries_PList & arg)36 DVPSReferencedSeries_PList::DVPSReferencedSeries_PList(const DVPSReferencedSeries_PList &arg)
37 : list_()
38 {
39   OFListConstIterator(DVPSReferencedSeries *) first = arg.list_.begin();
40   OFListConstIterator(DVPSReferencedSeries *) last = arg.list_.end();
41   while (first != last)
42   {
43     list_.push_back((*first)->clone());
44     ++first;
45   }
46 }
47 
~DVPSReferencedSeries_PList()48 DVPSReferencedSeries_PList::~DVPSReferencedSeries_PList()
49 {
50   clear();
51 }
52 
clear()53 void DVPSReferencedSeries_PList::clear()
54 {
55   OFListIterator(DVPSReferencedSeries *) first = list_.begin();
56   OFListIterator(DVPSReferencedSeries *) last = list_.end();
57   while (first != last)
58   {
59     delete (*first);
60     first = list_.erase(first);
61   }
62 }
63 
read(DcmItem & dset)64 OFCondition DVPSReferencedSeries_PList::read(DcmItem &dset)
65 {
66   OFCondition result = EC_Normal;
67   DcmStack stack;
68   DVPSReferencedSeries *newSeries = NULL;
69   DcmSequenceOfItems *dseq=NULL;
70   DcmItem *ditem=NULL;
71 
72   if (EC_Normal == dset.search(DCM_ReferencedSeriesSequence, stack, ESM_fromHere, OFFalse))
73   {
74     dseq=(DcmSequenceOfItems *)stack.top();
75     if (dseq)
76     {
77       unsigned long numItems = dseq->card();
78       for (unsigned int i=0; i<numItems; i++)
79       {
80         ditem = dseq->getItem(i);
81         newSeries = new DVPSReferencedSeries();
82         if (newSeries && ditem)
83         {
84           result = newSeries->read(*ditem);
85           list_.push_back(newSeries);
86         } else result = EC_MemoryExhausted;
87       }
88     }
89   }
90 
91   return result;
92 }
93 
write(DcmItem & dset)94 OFCondition DVPSReferencedSeries_PList::write(DcmItem &dset)
95 {
96   OFCondition result = EC_Normal;
97   DcmSequenceOfItems *dseq=NULL;
98   DcmItem *ditem=NULL;
99 
100   dseq = new DcmSequenceOfItems(DCM_ReferencedSeriesSequence);
101   if (dseq)
102   {
103     OFListIterator(DVPSReferencedSeries *) first = list_.begin();
104     OFListIterator(DVPSReferencedSeries *) last = list_.end();
105     while (first != last)
106     {
107       if (result==EC_Normal)
108       {
109         ditem = new DcmItem();
110         if (ditem)
111         {
112           result = (*first)->write(*ditem);
113           if (result==EC_Normal) dseq->insert(ditem); else delete ditem;
114         } else result = EC_MemoryExhausted;
115       }
116       ++first;
117     }
118     if (result==EC_Normal) dset.insert(dseq, OFTrue /*replaceOld*/); else delete dseq;
119   } else result = EC_MemoryExhausted;
120   return result;
121 }
122 
isValid()123 OFBool DVPSReferencedSeries_PList::isValid()
124 {
125   if (list_.size() == 0)
126   {
127     DCMPSTAT_WARN("referenced series SQ is empty in presentation state");
128     return OFFalse;
129   }
130 
131   OFBool result = OFTrue;
132   OFString sopclassuid;
133 
134   OFListIterator(DVPSReferencedSeries *) first = list_.begin();
135   OFListIterator(DVPSReferencedSeries *) last = list_.end();
136   while ((result == OFTrue) && (first != last))
137   {
138     result = (*first)->isValid(sopclassuid);
139     ++first;
140   }
141   return result;
142 }
143 
checkSOPClass(const char * uid)144 OFBool DVPSReferencedSeries_PList::checkSOPClass(const char *uid)
145 {
146 
147   OFBool result = OFTrue;
148   OFString sopclassuid(uid);
149   OFListIterator(DVPSReferencedSeries *) first = list_.begin();
150   OFListIterator(DVPSReferencedSeries *) last = list_.end();
151   while ((result == OFTrue) && (first != last))
152   {
153     result = (*first)->isValid(sopclassuid);
154     ++first;
155   }
156   return result;
157 }
158 
removeImageReference(const char * seriesUID,const char * instanceUID)159 void DVPSReferencedSeries_PList::removeImageReference(const char *seriesUID, const char *instanceUID)
160 {
161   DVPSReferencedSeries *series = findSeriesReference(seriesUID);
162   if (series) series->removeImageReference(instanceUID);
163   return;
164 }
165 
findSeriesReference(const char * seriesUID)166 DVPSReferencedSeries *DVPSReferencedSeries_PList::findSeriesReference(const char *seriesUID)
167 {
168   OFListIterator(DVPSReferencedSeries *) first = list_.begin();
169   OFListIterator(DVPSReferencedSeries *) last = list_.end();
170   while (first != last)
171   {
172     if ((*first)->isSeriesUID(seriesUID)) return *first;
173     ++first;
174   }
175   return NULL;
176 }
177 
findImageReference(const char * seriesUID,const char * instanceUID)178 DVPSReferencedImage *DVPSReferencedSeries_PList::findImageReference(const char *seriesUID, const char *instanceUID)
179 {
180   DVPSReferencedSeries *series = findSeriesReference(seriesUID);
181   if (series) return series->findImageReference(instanceUID); else return NULL;
182 }
183 
removeSeriesReference(const char * seriesUID)184 void DVPSReferencedSeries_PList::removeSeriesReference(const char *seriesUID)
185 {
186   OFListIterator(DVPSReferencedSeries *) first = list_.begin();
187   OFListIterator(DVPSReferencedSeries *) last = list_.end();
188   while (first != last)
189   {
190     if ((*first)->isSeriesUID(seriesUID))
191     {
192       delete (*first);
193       first = list_.erase(first);
194     } else ++first;
195   }
196   return;
197 }
198 
addImageReference(const char * seriesUID,const char * sopclassUID,const char * instanceUID,const char * frames,const char * aetitle,const char * filesetID,const char * filesetUID)199 OFCondition DVPSReferencedSeries_PList::addImageReference(
200     const char *seriesUID,
201     const char *sopclassUID,
202     const char *instanceUID,
203     const char *frames,
204     const char *aetitle,
205     const char *filesetID,
206     const char *filesetUID)
207 
208 {
209   if ((seriesUID==NULL) || (sopclassUID==NULL) || (instanceUID==NULL)) return EC_IllegalCall;
210 
211   OFCondition result = EC_Normal;
212   if (checkSOPClass(sopclassUID))
213   {
214     DVPSReferencedSeries *series = findSeriesReference(seriesUID);
215     if (series == NULL)
216     {
217       series = new DVPSReferencedSeries();
218       if (series)
219       {
220         series->setSeriesInstanceUID(seriesUID);
221         list_.push_back(series);
222       }
223     }
224     if (series)
225     {
226       result = series->addImageReference(sopclassUID, instanceUID, frames);
227       if (EC_Normal == result) series->setRetrieveLocation(aetitle, filesetID, filesetUID);
228     } else result = EC_MemoryExhausted;
229   } else result = EC_IllegalCall;
230   return result;
231 }
232 
233 
numberOfImageReferences()234 size_t DVPSReferencedSeries_PList::numberOfImageReferences()
235 {
236   size_t result=0;
237   OFListIterator(DVPSReferencedSeries *) first = list_.begin();
238   OFListIterator(DVPSReferencedSeries *) last = list_.end();
239   while (first != last)
240   {
241     result += (*first)->numberOfImageReferences();
242     ++first;
243   }
244   return result;
245 }
246 
getImageReference(size_t idx,OFString & seriesUID,OFString & sopclassUID,OFString & instanceUID,OFString & frames,OFString & aetitle,OFString & filesetID,OFString & filesetUID)247 OFCondition DVPSReferencedSeries_PList::getImageReference(
248     size_t idx,
249     OFString& seriesUID,
250     OFString& sopclassUID,
251     OFString& instanceUID,
252     OFString& frames,
253     OFString& aetitle,
254     OFString& filesetID,
255     OFString& filesetUID)
256 {
257   OFListIterator(DVPSReferencedSeries *) first = list_.begin();
258   OFListIterator(DVPSReferencedSeries *) last = list_.end();
259   OFBool found = OFFalse;
260   size_t i;
261   while ((!found)&&(first != last))
262   {
263     i=(*first)->numberOfImageReferences();
264     if (i > idx) found = OFTrue; else
265     {
266       idx -= i;
267       ++first;
268     }
269   }
270   if (found) return (*first)->getImageReference(idx, seriesUID, sopclassUID, instanceUID, frames, aetitle, filesetID, filesetUID);
271   return EC_IllegalCall;
272 }
273