GME  13
GenParser.cpp
Go to the documentation of this file.
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 }