/src/dcmtk/dcmdata/libsrc/dcvris.cc
Line | Count | Source |
1 | | /* |
2 | | * |
3 | | * Copyright (C) 1994-2025, 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: dcmdata |
15 | | * |
16 | | * Author: Gerd Ehlers, Andreas Barth |
17 | | * |
18 | | * Purpose: Implementation of class DcmIntegerString |
19 | | * |
20 | | */ |
21 | | |
22 | | #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ |
23 | | |
24 | | #include "dcmtk/dcmdata/dcvris.h" |
25 | | #include "dcmtk/dcmdata/dcjson.h" |
26 | | #include "dcmtk/ofstd/ofstring.h" |
27 | | |
28 | 0 | #define MAX_IS_LENGTH 12 |
29 | | |
30 | | |
31 | | // ******************************** |
32 | | |
33 | | |
34 | | DcmIntegerString::DcmIntegerString(const DcmTag &tag, |
35 | | const Uint32 len) |
36 | 0 | : DcmByteString(tag, len) |
37 | 0 | { |
38 | 0 | setMaxLength(MAX_IS_LENGTH); |
39 | 0 | setNonSignificantChars(" \\"); |
40 | 0 | } |
41 | | |
42 | | |
43 | | DcmIntegerString::DcmIntegerString(const DcmIntegerString &old) |
44 | 0 | : DcmByteString(old) |
45 | 0 | { |
46 | 0 | } |
47 | | |
48 | | |
49 | | DcmIntegerString::~DcmIntegerString() |
50 | 0 | { |
51 | 0 | } |
52 | | |
53 | | |
54 | | DcmIntegerString &DcmIntegerString::operator=(const DcmIntegerString &obj) |
55 | 0 | { |
56 | 0 | DcmByteString::operator=(obj); |
57 | 0 | return *this; |
58 | 0 | } |
59 | | |
60 | | |
61 | | OFCondition DcmIntegerString::copyFrom(const DcmObject& rhs) |
62 | 0 | { |
63 | 0 | if (this != &rhs) |
64 | 0 | { |
65 | 0 | if (rhs.ident() != ident()) return EC_IllegalCall; |
66 | 0 | *this = OFstatic_cast(const DcmIntegerString &, rhs); |
67 | 0 | } |
68 | 0 | return EC_Normal; |
69 | 0 | } |
70 | | |
71 | | |
72 | | // ******************************** |
73 | | |
74 | | |
75 | | DcmEVR DcmIntegerString::ident() const |
76 | 0 | { |
77 | 0 | return EVR_IS; |
78 | 0 | } |
79 | | |
80 | | |
81 | | OFCondition DcmIntegerString::checkValue(const OFString &vm, |
82 | | const OFBool /*oldFormat*/) |
83 | 0 | { |
84 | 0 | OFString strVal; |
85 | | /* get "raw value" without any modifications (if possible) */ |
86 | 0 | OFCondition l_error = getStringValue(strVal); |
87 | 0 | if (l_error.good()) |
88 | 0 | l_error = DcmIntegerString::checkStringValue(strVal, vm); |
89 | 0 | return l_error; |
90 | 0 | } |
91 | | |
92 | | |
93 | | // ******************************** |
94 | | |
95 | | |
96 | | OFCondition DcmIntegerString::getSint32(Sint32 &sintVal, |
97 | | const unsigned long pos) |
98 | 0 | { |
99 | | /* get integer string value */ |
100 | 0 | OFString str; |
101 | 0 | OFCondition l_error = getOFString(str, pos, OFTrue); |
102 | 0 | if (l_error.good()) |
103 | 0 | { |
104 | | /* convert string to integer value */ |
105 | 0 | #ifdef SCNd32 |
106 | 0 | if (sscanf(str.c_str(), "%" SCNd32, &sintVal) != 1) |
107 | | #elif SIZEOF_LONG == 8 |
108 | | if (sscanf(str.c_str(), "%d", &sintVal) != 1) |
109 | | #else |
110 | | if (sscanf(str.c_str(), "%ld", &sintVal) != 1) |
111 | | #endif |
112 | 0 | l_error = EC_CorruptedData; |
113 | 0 | } |
114 | 0 | return l_error; |
115 | 0 | } |
116 | | |
117 | | |
118 | | // ******************************** |
119 | | |
120 | | |
121 | | OFCondition DcmIntegerString::getOFString(OFString &stringVal, |
122 | | const unsigned long pos, |
123 | | OFBool normalize) |
124 | 0 | { |
125 | | /* call inherited method */ |
126 | 0 | OFCondition l_error = DcmByteString::getOFString(stringVal, pos, normalize); |
127 | | /* normalize string if required */ |
128 | 0 | if (l_error.good() && normalize) |
129 | 0 | normalizeString(stringVal, !MULTIPART, DELETE_LEADING, DELETE_TRAILING); |
130 | 0 | return l_error; |
131 | 0 | } |
132 | | |
133 | | |
134 | | // ******************************** |
135 | | |
136 | | |
137 | | OFCondition DcmIntegerString::checkStringValue(const OFString &value, |
138 | | const OFString &vm) |
139 | 0 | { |
140 | 0 | return DcmByteString::checkStringValue(value, vm, "is", 8, MAX_IS_LENGTH); |
141 | 0 | } |
142 | | |
143 | | |
144 | | // ******************************** |
145 | | |
146 | | |
147 | | OFCondition DcmIntegerString::writeJson(STD_NAMESPACE ostream &out, |
148 | | DcmJsonFormat &format) |
149 | 0 | { |
150 | 0 | OFCondition status = EC_Normal; |
151 | | |
152 | | /* always write JSON Opener */ |
153 | 0 | writeJsonOpener(out, format); |
154 | 0 | OFBool isValid; |
155 | |
|
156 | 0 | if (!isEmpty()) |
157 | 0 | { |
158 | | /* write element value */ |
159 | 0 | if (format.asBulkDataURI(getTag(), getLength())) |
160 | 0 | { |
161 | | /* adjust byte order to little endian */ |
162 | 0 | Uint8 *byteValues = OFstatic_cast(Uint8 *, getValue(EBO_LittleEndian)); |
163 | 0 | status = format.writeBulkData(out, getTag(), getLengthField(), byteValues); |
164 | 0 | } |
165 | 0 | else |
166 | 0 | { |
167 | 0 | const unsigned long vm = getVM(); |
168 | 0 | if (vm > 0) |
169 | 0 | { |
170 | 0 | OFString value; |
171 | 0 | OFString vmstring = "1"; |
172 | 0 | status = getOFString(value, 0L); |
173 | 0 | if (status.bad()) |
174 | 0 | return status; |
175 | 0 | format.printValuePrefix(out); |
176 | |
|
177 | 0 | isValid = checkStringValue(value, vmstring).good(); |
178 | 0 | switch (format.getJsonNumStringPolicy()) |
179 | 0 | { |
180 | 0 | case DcmJsonFormat::NSP_auto: |
181 | 0 | if (isValid) |
182 | 0 | DcmJsonFormat::printNumberInteger(out, value); |
183 | 0 | else |
184 | 0 | { |
185 | 0 | DCMDATA_WARN("encountered illegal IS value '" << value << "', converting to JSON string"); |
186 | 0 | DcmJsonFormat::printValueString(out, value); |
187 | 0 | } |
188 | 0 | break; |
189 | 0 | case DcmJsonFormat::NSP_always_number: |
190 | 0 | if (isValid) DcmJsonFormat::printNumberInteger(out, value); |
191 | 0 | else |
192 | 0 | { |
193 | 0 | DCMDATA_WARN("encountered illegal IS value '" << value << "', aborting conversion to JSON"); |
194 | 0 | return EC_CannotWriteStringAsJSONNumber; |
195 | 0 | } |
196 | 0 | break; |
197 | 0 | case DcmJsonFormat::NSP_always_string: |
198 | 0 | if (!isValid) |
199 | 0 | { |
200 | 0 | DCMDATA_WARN("encountered illegal IS value '" << value << "', converting to JSON string"); |
201 | 0 | } |
202 | 0 | DcmJsonFormat::printValueString(out, value); |
203 | 0 | break; |
204 | 0 | } |
205 | | |
206 | 0 | for (unsigned long valNo = 1; valNo < vm; ++valNo) |
207 | 0 | { |
208 | 0 | status = getOFString(value, valNo); |
209 | 0 | if (status.bad()) |
210 | 0 | return status; |
211 | 0 | format.printNextArrayElementPrefix(out); |
212 | |
|
213 | 0 | isValid = checkStringValue(value, vmstring).good(); |
214 | 0 | switch (format.getJsonNumStringPolicy()) |
215 | 0 | { |
216 | 0 | case DcmJsonFormat::NSP_auto: |
217 | 0 | if (isValid) |
218 | 0 | DcmJsonFormat::printNumberInteger(out, value); |
219 | 0 | else |
220 | 0 | { |
221 | 0 | DCMDATA_WARN("encountered illegal IS value '" << value << "', converting to JSON string"); |
222 | 0 | DcmJsonFormat::printValueString(out, value); |
223 | 0 | } |
224 | 0 | break; |
225 | 0 | case DcmJsonFormat::NSP_always_number: |
226 | 0 | if (isValid) |
227 | 0 | DcmJsonFormat::printNumberInteger(out, value); |
228 | 0 | else |
229 | 0 | { |
230 | 0 | DCMDATA_WARN("encountered illegal IS value '" << value << "', aborting conversion to JSON"); |
231 | 0 | return EC_CannotWriteStringAsJSONNumber; |
232 | 0 | } |
233 | 0 | break; |
234 | 0 | case DcmJsonFormat::NSP_always_string: |
235 | 0 | if (!isValid) |
236 | 0 | { |
237 | 0 | DCMDATA_WARN("encountered illegal IS value '" << value << "', converting to JSON string"); |
238 | 0 | } |
239 | 0 | DcmJsonFormat::printValueString(out, value); |
240 | 0 | break; |
241 | 0 | } |
242 | 0 | } |
243 | 0 | format.printValueSuffix(out); |
244 | 0 | } |
245 | 0 | } |
246 | 0 | } |
247 | | |
248 | | /* write JSON Closer */ |
249 | 0 | writeJsonCloser(out, format); |
250 | | /* always report success */ |
251 | 0 | return status; |
252 | 0 | } |