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