comparison Resources/Patches/dcmtk-dcdict_orthanc.cc @ 3593:0301f59450fe

improved the patch for loading DICOM dictionary from memory
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 06 Jan 2020 17:58:15 +0100
parents
children 0080c9b492e5
comparison
equal deleted inserted replaced
3592:de1665e7b341 3593:0301f59450fe
1 // Function by the Orthanc project to load a dictionary from a memory
2 // buffer, which is necessary in sandboxed environments. This is an
3 // adapted version of DcmDataDictionary::loadDictionary().
4
5
6 #include <boost/noncopyable.hpp>
7
8 struct OrthancLinesIterator;
9
10 // This plain old C class is implemented in "../../Core/Toolbox.h"
11 OrthancLinesIterator* OrthancLinesIterator_Create(const std::string& content);
12
13 bool OrthancLinesIterator_GetLine(std::string& target,
14 const OrthancLinesIterator* iterator);
15
16 void OrthancLinesIterator_Next(OrthancLinesIterator* iterator);
17
18 void OrthancLinesIterator_Free(OrthancLinesIterator* iterator);
19
20
21 class LinesIterator : public boost::noncopyable
22 {
23 private:
24 OrthancLinesIterator* iterator_;
25
26 public:
27 LinesIterator(const std::string& content) :
28 iterator_(NULL)
29 {
30 iterator_ = OrthancLinesIterator_Create(content);
31 }
32
33 ~LinesIterator()
34 {
35 if (iterator_ != NULL)
36 {
37 OrthancLinesIterator_Free(iterator_);
38 iterator_ = NULL;
39 }
40 }
41
42 bool GetLine(std::string& target) const
43 {
44 if (iterator_ != NULL)
45 {
46 return OrthancLinesIterator_GetLine(target, iterator_);
47 }
48 else
49 {
50 return false;
51 }
52 }
53
54 void Next()
55 {
56 if (iterator_ != NULL)
57 {
58 OrthancLinesIterator_Next(iterator_);
59 }
60 }
61 };
62
63
64
65 OFBool
66 DcmDataDictionary::loadFromMemory(const std::string& content, OFBool errorIfAbsent)
67 {
68 int lineNumber = 0;
69 char* lineFields[DCM_MAXDICTFIELDS + 1];
70 int fieldsPresent;
71 DcmDictEntry* e;
72 int errorsEncountered = 0;
73 OFBool errorOnThisLine = OFFalse;
74 int i;
75
76 DcmTagKey key, upperKey;
77 DcmDictRangeRestriction groupRestriction = DcmDictRange_Unspecified;
78 DcmDictRangeRestriction elementRestriction = DcmDictRange_Unspecified;
79 DcmVR vr;
80 char* vrName;
81 char* tagName;
82 char* privCreator;
83 int vmMin, vmMax = 1;
84 const char* standardVersion;
85
86 LinesIterator iterator(content);
87
88 std::string line;
89 while (iterator.GetLine(line)) {
90 iterator.Next();
91
92 if (line.size() >= DCM_MAXDICTLINESIZE) {
93 DCMDATA_ERROR("DcmDataDictionary: Too long line: " << line);
94 continue;
95 }
96
97 lineNumber++;
98
99 if (onlyWhitespace(line.c_str())) {
100 continue; /* ignore this line */
101 }
102 if (isaCommentLine(line.c_str())) {
103 continue; /* ignore this line */
104 }
105
106 errorOnThisLine = OFFalse;
107
108 /* fields are tab separated */
109 fieldsPresent = splitFields(line.c_str(), lineFields,
110 DCM_MAXDICTFIELDS,
111 DCM_DICT_FIELD_SEPARATOR_CHAR);
112
113 /* initialize dict entry fields */
114 vrName = NULL;
115 tagName = NULL;
116 privCreator = NULL;
117 vmMin = vmMax = 1;
118 standardVersion = "DICOM";
119
120 switch (fieldsPresent) {
121 case 0:
122 case 1:
123 case 2:
124 DCMDATA_ERROR("DcmDataDictionary: "
125 << "too few fields (line " << lineNumber << ")");
126 errorOnThisLine = OFTrue;
127 break;
128 default:
129 DCMDATA_ERROR("DcmDataDictionary: "
130 << "too many fields (line " << lineNumber << "): ");
131 errorOnThisLine = OFTrue;
132 break;
133 case 5:
134 stripWhitespace(lineFields[4]);
135 standardVersion = lineFields[4];
136 /* drop through to next case label */
137 case 4:
138 /* the VM field is present */
139 if (!parseVMField(lineFields[3], vmMin, vmMax)) {
140 DCMDATA_ERROR("DcmDataDictionary: "
141 << "bad VM field (line " << lineNumber << "): " << lineFields[3]);
142 errorOnThisLine = OFTrue;
143 }
144 /* drop through to next case label */
145 case 3:
146 if (!parseWholeTagField(lineFields[0], key, upperKey,
147 groupRestriction, elementRestriction, privCreator))
148 {
149 DCMDATA_ERROR("DcmDataDictionary: "
150 << "bad Tag field (line " << lineNumber << "): " << lineFields[0]);
151 errorOnThisLine = OFTrue;
152 } else {
153 /* all is OK */
154 vrName = lineFields[1];
155 stripWhitespace(vrName);
156
157 tagName = lineFields[2];
158 stripWhitespace(tagName);
159 }
160 }
161
162 if (!errorOnThisLine) {
163 /* check the VR Field */
164 vr.setVR(vrName);
165 if (vr.getEVR() == EVR_UNKNOWN) {
166 DCMDATA_ERROR("DcmDataDictionary: "
167 << "bad VR field (line " << lineNumber << "): " << vrName);
168 errorOnThisLine = OFTrue;
169 }
170 }
171
172 if (!errorOnThisLine) {
173 e = new DcmDictEntry(
174 key.getGroup(), key.getElement(),
175 upperKey.getGroup(), upperKey.getElement(),
176 vr, tagName, vmMin, vmMax, standardVersion, OFTrue,
177 privCreator);
178
179 e->setGroupRangeRestriction(groupRestriction);
180 e->setElementRangeRestriction(elementRestriction);
181 addEntry(e);
182 }
183
184 for (i = 0; i < fieldsPresent; i++) {
185 free(lineFields[i]);
186 lineFields[i] = NULL;
187 }
188
189 delete[] privCreator;
190
191 if (errorOnThisLine) {
192 errorsEncountered++;
193 }
194 }
195
196 /* return OFFalse in case of errors and set internal state accordingly */
197 if (errorsEncountered == 0) {
198 dictionaryLoaded = OFTrue;
199 return OFTrue;
200 }
201 else {
202 dictionaryLoaded = OFFalse;
203 return OFFalse;
204 }
205 }