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