1 /*=========================================================================
2
3 Program: GDCM (Grassroots DICOM). A DICOM library
4
5 Copyright (c) 2006-2011 Mathieu Malaterre
6 All rights reserved.
7 See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
8
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the above copyright notice for more information.
12
13 =========================================================================*/
14 #include "gdcmXMLPrivateDictReader.h"
15 #include "gdcmDict.h"
16
17 #include <iostream>
18 #include <stdlib.h> // abort
19
20 namespace gdcm
21 {
22
XMLPrivateDictReader()23 XMLPrivateDictReader::XMLPrivateDictReader():ParsingDescription(false),Description()
24 {
25 }
26
HandleEntry(const char ** atts)27 void XMLPrivateDictReader::HandleEntry(const char **atts)
28 {
29 assert( !ParsingDescription );
30 std::string name;
31 std::string owner;
32 VR vr;
33 VM::VMType vm = VM::VM0;
34 bool ret = false;
35
36 PrivateTag &tag = CurrentTag;
37 DictEntry &de = CurrentDE;
38
39 int i = 0;
40 const char **current = atts;
41 // Supported attributes:
42 std::string group = "group";
43 std::string element = "element";
44 std::string strvr = "vr";
45 std::string strvm = "vm";
46 std::string retired = "retired";
47 std::string retiredtrue = "true";
48 std::string retiredfalse = "false";
49 std::string version = "version";
50 std::string strowner = "owner";
51 std::string strname = "name";
52
53 while(*current /*&& current+1*/)
54 {
55 assert( *(current + 1) );
56 if( group == *current )
57 {
58 unsigned int v;
59 const char *raw = *(current+1);
60 int r = sscanf(raw, "%04x", &v);
61 assert( r == 1 );
62 assert( v <= 0xFFFF );
63
64 char sv[4+1];
65 r = sprintf(sv, "%04x", v);
66 assert( r == 4 );
67 if( strncmp(raw, sv, 4) == 0 ) // GroupXX
68 {
69 tag.SetGroup( v );
70 }
71 else
72 {
73 assert( (raw[0] == '5' && raw[1] == '0') || (raw[0] == '6' && raw[1] == '0') ||
74 (raw[0] == '7' && raw[1] == '0') );
75 if( raw[0] == '5' ) tag.SetGroup( 0x5000 );
76 else if( raw[0] == '6' ) tag.SetGroup( 0x6000 );
77 else if( raw[0] == '7' ) tag.SetGroup( 0x7000 );
78 else assert(0);
79 CurrentDE.SetGroupXX( true );
80 }
81 }
82 else if( element == *current )
83 {
84 const char *raw = *(current+1);
85 assert( (raw[0] == 'x' && raw[1] == 'x' )
86 || (raw[2] == 'x' && raw[3] == 'x') );
87 if (raw[2] == 'x' && raw[3] == 'x')
88 {
89 if( raw[0] == '0' && raw[1] == '0' )
90 {
91 tag.SetElement( 0x0000 );
92 CurrentDE.SetElementXX( true );
93 }
94 else if( raw[0] == '1' && raw[1] == '0' )
95 {
96 tag.SetElement( 0x1000 );
97 CurrentDE.SetElementXX( true );
98 }
99 else
100 {
101 assert(0); // FIXME
102 }
103 }
104 else
105 {
106 unsigned int v;
107 int r = sscanf(raw+2, "%02x", &v);
108 assert( r == 1 );
109 assert( v <= 0xFF );
110
111 char sv[4+1];
112 r = sprintf(sv, "xx%02x", v);
113 assert( r == 4 );
114 if( strncmp(raw, sv, 4) == 0 )
115 {
116 tag.SetElement( v );
117 }
118 else
119 {
120 assert(0);
121 }
122 }
123 }
124 else if( strvr == *current )
125 {
126 vr = VR::GetVRTypeFromFile( *(current + 1) );
127 //assert( vr != VR::INVALID );
128 }
129 else if( strvm == *current )
130 {
131 vm = VM::GetVMType( *(current + 1) );
132 //assert( *(current+1) != '\0' );
133 //assert( vm != VM::VM0 );
134 //assert( vm != VM::VM_END );
135 }
136 else if( retired == *current )
137 {
138 if( retiredtrue == *(current+1) )
139 {
140 ret = true;
141 }
142 else if( retiredfalse == *(current+1) )
143 {
144 ret = false;
145 }
146 else
147 {
148 assert(0);
149 }
150 }
151 else if( version == *current )
152 {
153 // ??
154 }
155 else if( strowner == *current )
156 {
157 owner = *(current+1);
158 }
159 else if( strname == *current )
160 {
161 name = *(current+1);
162 }
163 else
164 {
165 assert(0);
166 }
167 // goes on to the next attribute (need to skip value)
168 ++current;
169 ++current;
170 }
171 // Done !
172 de = DictEntry(name.c_str(), vr, vm, ret );
173 tag.SetOwner( owner.c_str() );
174 }
175
HandleDescription(const char ** atts)176 void XMLPrivateDictReader::HandleDescription(const char **atts)
177 {
178 assert( ParsingDescription );
179 assert( *atts == NULL );
180 assert( Description == "" );
181 #if 0
182 DictEntry &de = CurrentDE;
183
184 const char **current = atts;
185 std::string description;
186 while(*current /*&& current+1*/)
187 {
188 assert( *(current + 1) );
189 ++current;
190 }
191 // Done !
192 //de.SetName( description.c_str() );
193 #endif
194 }
195
StartElement(const char * name,const char ** atts)196 void XMLPrivateDictReader::StartElement(const char *name, const char **atts)
197 {
198 std::string dict = "dict";
199 std::string entry = "entry";
200 std::string description = "description"; // aka name
201 Tag currenttag;
202 //DictEntry currentde("",VR::INVALID,VM::VM0,true);
203 if( dict == name )
204 {
205 // dict ??
206 }
207 else if( entry == name )
208 {
209 HandleEntry(atts);
210 }
211 else if( description == name )
212 {
213 ParsingDescription = true; // mark that we are processing description element
214 // We need a second pass to fill in the currentde struct:
215 HandleDescription(atts);
216 }
217 else
218 {
219 std::cerr << name << std::endl;
220 assert(0);
221 }
222 }
223
EndElement(const char * name)224 void XMLPrivateDictReader::EndElement(const char *name)
225 {
226 std::string entry = "entry";
227 std::string dict = "dict";
228 std::string description = "description"; // free form text usually the raw description of tag
229 if( entry == name )
230 {
231 // Ok currentde is now valid let's insert it into the Dict:
232 PDict.AddDictEntry( CurrentTag, CurrentDE);
233 }
234 else if( description == name )
235 {
236 assert( ParsingDescription );
237 ParsingDescription = false;
238
239 // TODO: do something with description ??
240 //
241 // Invalidate Description ?
242 Description = "";
243 }
244 else if ( dict == name )
245 {
246 }
247 else
248 {
249 assert(0);
250 }
251 }
252
CharacterDataHandler(const char * data,int length)253 void XMLPrivateDictReader::CharacterDataHandler(const char *data, int length)
254 {
255 if( ParsingDescription )
256 {
257 std::string name( data, length);
258 assert( length == strlen( name.c_str() ) );
259 Description.append( name );
260 }
261 }
262
263 }
264