GME
13
|
00001 00002 #include "stdafx.h" 00003 #include "GenParser.h" 00004 00005 #include <xercesc/util/PlatformUtils.hpp> 00006 #include <xercesc/parsers/SAXParser.hpp> 00007 #include <xercesc/sax/Locator.hpp> 00008 #include <xercesc/framework/LocalFileInputSource.hpp> 00009 #include <xercesc/framework\MemBufInputSource.hpp> 00010 #include <stdio.h> 00011 #include <string> 00012 #include "atlstr.h" 00013 #include <comutil.h> 00014 00015 // --------------------------- XmlStr 00016 00017 #ifdef UNICODE 00018 XmlStr::XmlStr(const XMLCh* const input) : std::tstring(input) 00019 { 00020 } 00021 00022 XmlStr::XmlStr(const XMLCh* const input, unsigned int len) : std::tstring(input) 00023 { 00024 resize(len); 00025 } 00026 #else 00027 XmlStr::XmlStr(const XMLCh* const input) 00028 { 00029 resize(GetCharLength(input, -1)); 00030 CopyTo(input, -1, &(operator[](0)), length()); 00031 ASSERT( operator[](length()-1) == 0 ); 00032 erase( length() - 1); // was: pop_back(); 00033 } 00034 00035 XmlStr::XmlStr(const XMLCh* const input, unsigned int len) 00036 { 00037 resize(GetCharLength(input, len)); 00038 CopyTo(input, len, &(operator[](0)), length()); 00039 } 00040 #endif 00041 00042 void CGenParser::SetErrorInfo2(HRESULT hr) 00043 { 00044 _bstr_t bstr; 00045 GetErrorInfo(hr, bstr.GetAddress()); 00046 std::tstring str; 00047 Format(str, _T("in file %s at line %ld, char %ld"), 00048 xmlfile.c_str(), err_line, err_column); 00049 00050 if (bstr.length()) 00051 { 00052 str = std::tstring(static_cast<const TCHAR*>(bstr)) + _T(": ") + str; 00053 } 00054 00055 SetErrorInfo(hr, _bstr_t(str.c_str())); 00056 } 00057 00058 void CGenParser::ThrowXmlError(const TCHAR *format, ...) 00059 { 00060 ASSERT( format != NULL ); 00061 00062 va_list args; 00063 va_start(args, format); 00064 00065 std::tstring desc; 00066 vFormat(desc, format, args); 00067 00068 std::tstring str; 00069 if( locator != NULL ) 00070 Format(str, 00071 _T("XML parser error in file %s at line %d, char %d : %s"), 00072 xmlfile.c_str(), (int)locator->getLineNumber(), 00073 (int)locator->getColumnNumber(), desc.c_str()); 00074 else 00075 Format(str, 00076 _T("XML parser error in file %s : %s"), xmlfile.c_str(), desc.c_str()); 00077 00078 errorinfo = str.c_str(); 00079 SetErrorInfo(const_cast<TCHAR*>(str.c_str())); 00080 HR_THROW(E_XMLPARSER); 00081 } 00082 00083 // ------- Handler Base 00084 00085 InputSource *CGenParser::resolveEntity(const XMLCh* const publicId, const XMLCh* const systemId) 00086 { 00087 do 00088 { 00089 XmlStr sysid = systemId; 00090 std::tstring syssid = sysid; 00091 00092 HMODULE hm = GetModuleHandle(_T("PARSER.DLL")); 00093 if( hm == NULL ) 00094 break; 00095 00096 HRSRC res = FindResource(hm, syssid.c_str(), _T("DTD")); 00097 if(res) { 00098 XMLByte *bytes = (XMLByte *)LockResource(LoadResource(hm, res)); 00099 if (!bytes) 00100 COMTHROW(E_INVALID_DTD); 00101 return new MemBufInputSource(bytes, SizeofResource(hm, res), syssid.c_str()); 00102 } 00103 00104 00105 TCHAR filename[MAX_PATH]; 00106 int a = GetModuleFileName(hm, filename, MAX_PATH); 00107 a -= 10; 00108 if( a <= 0 ) 00109 break; 00110 00111 if( _tcsicmp(filename + a, _T("PARSER.DLL")) != 0 ) 00112 break; 00113 00114 _tcscpy(filename + a, sysid.c_str()); 00115 00116 FILE *file = _tfopen(filename, _T("r")); 00117 if( file == NULL ) 00118 break; 00119 00120 fclose(file); 00121 00122 return new LocalFileInputSource(PutInBstr(filename)); 00123 00124 } while(false); 00125 00126 return HandlerBase::resolveEntity(publicId, systemId); 00127 } 00128 00129 void CGenParser::startDocument() 00130 { 00131 counter = 0; 00132 } 00133 00134 void CGenParser::endDocument() 00135 { 00136 locator = NULL; 00137 } 00138 00139 void CGenParser::startElement(const XMLCh* const name, AttributeList& attrlist) 00140 { 00141 #ifdef _DEBUG 00142 int cur_line, cur_column; 00143 if( locator != NULL ) 00144 { 00145 cur_line = (int)locator->getLineNumber(); 00146 cur_column = (int)locator->getColumnNumber(); 00147 // CString msg; 00148 // msg.Format(_T("Line %d, Col: %d\n"), cur_line, cur_column); 00149 // OutputDebugString(msg); 00150 } 00151 #endif 00152 00153 try 00154 { 00155 attributes_type attributes; 00156 00157 unsigned int len = attrlist.getLength(); 00158 for(unsigned int index = 0; index < len; index++) 00159 { 00160 attributes.push_back( std::pair<std::tstring,std::tstring>( 00161 XmlStr(attrlist.getName(index)), XmlStr(attrlist.getValue(index))) ); 00162 } 00163 00164 XmlStr namestr(name); 00165 00166 elements.push_back(element_type()); 00167 elements.back().name = namestr; 00168 elements.back().begin = counter; 00169 /* 00170 for(unsigned int index = 0; !elementfuncs[index].name.empty(); index++) 00171 { 00172 if( namestr == elementfuncs[index].name ) 00173 { 00174 elementfuncs[index].Start(this, attributes); 00175 break; 00176 } 00177 } 00178 */ 00179 00180 fireStartFunction(namestr, attributes); 00181 } 00182 catch (hresult_exception &) 00183 { 00184 if( locator != NULL ) 00185 { 00186 err_line = locator->getLineNumber(); 00187 err_column = locator->getColumnNumber(); 00188 00189 // we compose and set the error message for exceptions 00190 // [which come from the MGA layer because of meta incompatibility] 00191 std::tstring str; 00192 Format(str, _T("Improper use of object error in file %s at line %d, char %d."), xmlfile.c_str(), err_line, err_column); 00193 errorinfo = str.c_str(); 00194 } 00195 00196 throw; 00197 } 00198 catch (_com_error& e) 00199 { 00200 std::tstring str; 00201 if( locator != NULL ) 00202 { 00203 err_line = locator->getLineNumber(); 00204 err_column = locator->getColumnNumber(); 00205 00206 // we compose and set the error message for exceptions 00207 // [which come from the MGA layer because of meta incompatibility] 00208 Format(str, _T("In file %s at line %d, char %d: "), xmlfile.c_str(), err_line, err_column); 00209 errorinfo = str.c_str(); 00210 } 00211 if (e.Description() != _bstr_t()) 00212 { 00213 errorinfo = (str + static_cast<const TCHAR*>(e.Description())).c_str(); 00214 throw_com_error(e.Error(), errorinfo); 00215 } 00216 throw hresult_exception(e.Error()); 00217 } 00218 } 00219 00220 00221 void CGenParser::endElement(const XMLCh* const name) 00222 { 00223 try 00224 { 00225 XmlStr namestr(name); 00226 00227 ASSERT( !elements.empty() ); 00228 00229 // we modify the names, see clipboard 00230 // ASSERT( elements.back().name == namestr ); 00231 00232 elements.back().end = counter; 00233 /* 00234 for(int index = 0; !elementfuncs[index].name.empty(); index++) 00235 { 00236 if( namestr == elementfuncs[index].name ) 00237 { 00238 elementfuncs[index].End(this); 00239 break; 00240 } 00241 } 00242 */ 00243 00244 fireEndFunction(namestr); 00245 00246 elements.pop_back(); 00247 } 00248 catch(hresult_exception &) 00249 { 00250 if( locator != NULL ) 00251 { 00252 err_line = locator->getLineNumber(); 00253 err_column = locator->getColumnNumber(); 00254 00255 // we compose and set the error message for exceptions 00256 // [which come from the MGA layer because of meta incompatibility] 00257 std::tstring str; 00258 Format(str, _T("Improper use of object error in file %s at line %ld, char %ld."), xmlfile.c_str(), err_line, err_column); 00259 errorinfo = str.c_str(); 00260 } 00261 00262 throw; 00263 } 00264 catch (_com_error& e) 00265 { 00266 std::tstring str; 00267 if( locator != NULL ) 00268 { 00269 err_line = locator->getLineNumber(); 00270 err_column = locator->getColumnNumber(); 00271 00272 // we compose and set the error message for exceptions 00273 // [which come from the MGA layer because of meta incompatibility] 00274 Format(str, _T("In file %s at line %d, char %d: "), xmlfile.c_str(), err_line, err_column); 00275 errorinfo = str.c_str(); 00276 } 00277 if (e.Description() != _bstr_t()) 00278 { 00279 errorinfo = (str + static_cast<const TCHAR*>(e.Description())).c_str(); 00280 throw_com_error(e.Error(), errorinfo); 00281 } 00282 throw hresult_exception(e.Error()); 00283 } 00284 } 00285 00286 void CGenParser::characters(const XMLCh* const chars, const XMLSize_t length) 00287 { 00288 if( !elements.empty() ) 00289 elements.back().chardata += XmlStr(chars, length); 00290 } 00291 00292 void CGenParser::error(const SAXParseException &e) 00293 { 00294 ThrowXmlError( 00295 _T("(at line %d, char %d) %s"), 00296 (int)e.getLineNumber(),(int)e.getColumnNumber(), 00297 XmlStr(e.getMessage()).c_str()); 00298 } 00299 00300 void CGenParser::fatalError(const SAXParseException &e) 00301 { 00302 error(e); 00303 } 00304 00305 void CGenParser::setDocumentLocator(const Locator *const loc) 00306 { 00307 locator = loc; 00308 } 00309 00310 // ------- Attributes 00311 00312 const std::tstring *CGenParser::GetByNameX(const attributes_type &attributes, const TCHAR *name) 00313 { 00314 attributes_iterator i = attributes.begin(); 00315 attributes_iterator e = attributes.end(); 00316 while( i != e ) 00317 { 00318 if( (*i).first == name ) 00319 return &(*i).second; 00320 00321 ++i; 00322 } 00323 00324 return NULL; 00325 } 00326 00327 long CGenParser::toLong(std::tstring s) 00328 { 00329 const TCHAR *c = s.c_str(); 00330 TCHAR *e; 00331 00332 long a = _tcstol(c, &e, 0); 00333 00334 if( (e - c) != (int) s.length() ) 00335 HR_THROW(E_INVALID_XML_LONG); 00336 00337 return a; 00338 } 00339 00340 unsigned long CGenParser::toULong(std::tstring s) 00341 { 00342 const TCHAR *c = s.c_str(); 00343 TCHAR *e; 00344 00345 long a = _tcstoul(c, &e, 0); 00346 00347 if( (e - c) != (int) s.length() ) 00348 HR_THROW(E_INVALID_XML_LONG); 00349 00350 return a; 00351 }