1 /*
2  *
3  *  Copyright (C) 2000-2017, 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: dcmsr
15  *
16  *  Author: Joerg Riesmeier
17  *
18  *  Purpose:
19  *    classes: DSRWaveformChannelList
20  *
21  */
22 
23 
24 #include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
25 
26 #include "dcmtk/dcmsr/dsrwavch.h"
27 #include "dcmtk/dcmsr/dsrxmld.h"
28 
29 #include "dcmtk/dcmdata/dcdeftag.h"
30 #include "dcmtk/dcmdata/dcvrus.h"
31 
32 #define INCLUDE_CSTDIO
33 #include "dcmtk/ofstd/ofstdinc.h"
34 
35 
36 // global empty item object so it gets initialized and cleaned up by the linker
37 const DSRWaveformChannelItem DSRWaveformChannelEmptyItem(0, 0);
38 
39 template<>
DSRgetEmptyItem()40 const DSRWaveformChannelItem& DSRgetEmptyItem<DSRWaveformChannelItem>()
41 {
42     return DSRWaveformChannelEmptyItem;
43 }
44 
45 
DSRWaveformChannelList()46 DSRWaveformChannelList::DSRWaveformChannelList()
47   : DSRListOfItems<DSRWaveformChannelItem>()
48 {
49 }
50 
51 
DSRWaveformChannelList(const DSRWaveformChannelList & lst)52 DSRWaveformChannelList::DSRWaveformChannelList(const DSRWaveformChannelList &lst)
53   : DSRListOfItems<DSRWaveformChannelItem>(lst)
54 {
55 }
56 
57 
~DSRWaveformChannelList()58 DSRWaveformChannelList::~DSRWaveformChannelList()
59 {
60 }
61 
62 
operator =(const DSRWaveformChannelList & lst)63 DSRWaveformChannelList &DSRWaveformChannelList::operator=(const DSRWaveformChannelList &lst)
64 {
65     DSRListOfItems<DSRWaveformChannelItem>::operator=(lst);
66     return *this;
67 }
68 
69 
print(STD_NAMESPACE ostream & stream,const size_t flags,const char pairSeparator,const char itemSeparator) const70 OFCondition DSRWaveformChannelList::print(STD_NAMESPACE ostream &stream,
71                                           const size_t flags,
72                                           const char pairSeparator,
73                                           const char itemSeparator) const
74 {
75     const OFListConstIterator(DSRWaveformChannelItem) endPos = ItemList.end();
76     OFListConstIterator(DSRWaveformChannelItem) iterator = ItemList.begin();
77     while (iterator != endPos)
78     {
79         stream << (*iterator).MultiplexGroupNumber << pairSeparator << (*iterator).ChannelNumber;
80         iterator++;
81         if (iterator != endPos)
82         {
83             if (flags & DSRTypes::PF_shortenLongItemValues)
84             {
85                 stream << itemSeparator << "...";
86                 iterator = endPos;
87             } else
88                 stream << itemSeparator;
89         }
90     }
91     return EC_Normal;
92 }
93 
94 
read(DcmItem & dataset,const size_t)95 OFCondition DSRWaveformChannelList::read(DcmItem &dataset,
96                                          const size_t /*flags*/)
97 {
98     /* get integer array from dataset */
99     DcmUnsignedShort delem(DCM_ReferencedWaveformChannels);
100     OFCondition result = DSRTypes::getAndCheckElementFromDataset(dataset, delem, "2-2n", "1C", "WAVEFORM content item");
101     if (result.good())
102     {
103         /* clear internal list */
104         clear();
105         Uint16 group = 0;
106         Uint16 channel = 0;
107         const unsigned long count = delem.getVM();
108         /* fill list with values from integer array */
109         unsigned long i = 0;
110         while ((i < count) && result.good())
111         {
112             result = delem.getUint16(group, i++);
113             if (result.good())
114             {
115                 result = delem.getUint16(channel, i++);
116                 if (result.good())
117                     addItem(group, channel);
118             }
119         }
120     }
121     return result;
122 }
123 
124 
write(DcmItem & dataset) const125 OFCondition DSRWaveformChannelList::write(DcmItem &dataset) const
126 {
127     OFCondition result = EC_Normal;
128     /* fill integer array with values from list */
129     DcmUnsignedShort delem(DCM_ReferencedWaveformChannels);
130     const OFListConstIterator(DSRWaveformChannelItem) endPos = ItemList.end();
131     OFListConstIterator(DSRWaveformChannelItem) iterator = ItemList.begin();
132     unsigned long i = 0;
133     while ((iterator != endPos) && result.good())
134     {
135         result = delem.putUint16((*iterator).MultiplexGroupNumber, i++);
136         if (result.good())
137             result = delem.putUint16((*iterator).ChannelNumber, i++);
138         iterator++;
139     }
140     /* add to dataset */
141     if (result.good())
142         result = DSRTypes::addElementToDataset(result, dataset, new DcmUnsignedShort(delem), "2-2n", "1", "WAVEFORM content item");
143     return result;
144 }
145 
146 
isElement(const Uint16 multiplexGroupNumber,const Uint16 channelNumber) const147 OFBool DSRWaveformChannelList::isElement(const Uint16 multiplexGroupNumber,
148                                          const Uint16 channelNumber) const
149 {
150     return DSRListOfItems<DSRWaveformChannelItem>::isElement(DSRWaveformChannelItem(multiplexGroupNumber, channelNumber));
151 }
152 
153 
getItem(const size_t idx,Uint16 & multiplexGroupNumber,Uint16 & channelNumber) const154 OFCondition DSRWaveformChannelList::getItem(const size_t idx,
155                                             Uint16 &multiplexGroupNumber,
156                                             Uint16 &channelNumber) const
157 {
158     DSRWaveformChannelItem item;    /* default: 0,0 */
159     OFCondition result = DSRListOfItems<DSRWaveformChannelItem>::getItem(idx, item);
160     multiplexGroupNumber = item.MultiplexGroupNumber;
161     channelNumber = item.ChannelNumber;
162     return result;
163 }
164 
165 
addItem(const Uint16 multiplexGroupNumber,const Uint16 channelNumber)166 void DSRWaveformChannelList::addItem(const Uint16 multiplexGroupNumber,
167                                      const Uint16 channelNumber)
168 {
169     DSRListOfItems<DSRWaveformChannelItem>::addItem(DSRWaveformChannelItem(multiplexGroupNumber, channelNumber));
170 }
171 
172 
putString(const char * stringValue)173 OFCondition DSRWaveformChannelList::putString(const char *stringValue)
174 {
175     OFCondition result = EC_Normal;
176     /* clear internal list */
177     clear();
178     /* check input string */
179     if ((stringValue != NULL) && (strlen(stringValue) > 0))
180     {
181         Uint16 group = 0;
182         Uint16 channel = 0;
183         const char *ptr = stringValue;
184         /* retrieve channel pairs from string */
185         while (result.good() && (ptr != NULL))
186         {
187             if (sscanf(ptr, "%hu/%hu", &group, &channel) == 2)
188             {
189                 addItem(group, channel);
190                 /* jump to next channel pair */
191                 ptr = strchr(ptr, ',');
192                 if (ptr != NULL)
193                     ptr++;
194             } else
195                 result = EC_CorruptedData;
196         }
197     }
198     return result;
199 }
200