Mercurial > hg > orthanc
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 } |