FEDM_XmlBase.cpp
Go to the documentation of this file.
00001 /*-------------------------------------------------------
00002 |                                                       |
00003 |                     FEDM_XMLBase.cpp                  |
00004 |                                                       |
00005 ---------------------------------------------------------
00006 
00007 Copyright � 2000-2011 FEIG ELECTRONIC GmbH, All Rights Reserved.
00008                                                 Lange Strasse 4
00009                                                 D-35781 Weilburg
00010                                                 Federal Republic of Germany
00011                                                 phone    : +49 6471 31090
00012                                                 fax      : +49 6471 310999
00013                                                 e-mail   : obid-support@feig.de
00014                                                 Internet : http://www.feig.de
00015                                         
00016 Author                  :       Markus Hultsch
00017 Begin                   :       01.04.2003
00018 Version                 :       04.00.02 / 22.08.2011 / M. Hultsch
00019 
00020 Operation Systems       :       independent
00021 
00022 Function                        :       base class for XML document handler
00023                                                 
00024 Note                            :       this XML document handler is designed only for use
00025                                                 inside the class library FEDM !!
00026 
00027 
00028 Trademarks:
00029 -----------
00030 OBID®, OBID i-scan® and OBID myAXXESS® are registered Trademarks of FEIG ELECTRONIC GmbH
00031 Other Trademarks: see FEDM.h
00032 */
00033 
00034 
00035 #ifdef _FEDM_XML_SUPPORT
00036 
00037 //      #define _FEDM_TRACE
00038 
00039 #include "FEDM_XmlBase.h"
00040 //#include <io.h>
00041 //#include <fcntl.h>
00042 #if !defined(_WIN32_WCE)
00043 #include <sys/stat.h>
00044 #endif
00045 
00046 #ifdef _FEDM_LINUX
00047         #include <string.h>
00048 #endif
00049 
00050 #if _MSC_VER >= 1400
00051         #pragma warning(disable : 4996)
00052 #endif
00053 
00054 
00055 //#####################################################################################
00056 // Construction/Destruction
00057 //#####################################################################################
00058 
00059 /***************************************************************************
00060   Begin         :       01.04.2003 / M. Hultsch
00061   Version       :       01.08.00 / 23.04.2003 / M. Hultsch
00062 
00063   Function              :       constructor
00064 
00065   Parameters    :       -
00066 
00067   Return value  :       -
00068 ***************************************************************************/
00069 FEDM_XMLBase::FEDM_XMLBase()
00070 {
00071         m_iLastError            = 0;    // last error code
00072         m_sXmlStream            = L"";  // xml text in UNICODE
00073         m_file                          = NULL; // file handle
00074 
00075         m_wsXmlVer                      = L"";
00076         m_wsEncoding            = L"";
00077         m_wsStandalone          = L"";
00078 }
00079 
00080 /***************************************************************************
00081   Begin         :       01.04.2003 / M. Hultsch
00082   Version       :       01.08.00 / 07.04.2003 / M. Hultsch
00083 
00084   Function              :       destructor
00085 
00086   Parameters    :       -
00087 
00088   Return value  :       -
00089 ***************************************************************************/
00090 FEDM_XMLBase::~FEDM_XMLBase()
00091 {
00092         DeleteXmlTree();
00093 
00094         if(m_file != NULL)
00095                 fclose(m_file);
00096 }
00097 
00098 /***************************************************************************
00099   Begin         :       07.04.2003 / M. Hultsch
00100   Version       :       01.08.00 / 07.04.2003 / M. Hultsch
00101 
00102   Function              :       main delete function for tree items
00103 
00104   Parameters    :       -
00105 
00106   Return value  :       -
00107 ***************************************************************************/
00108 void FEDM_XMLBase::DeleteXmlTree()
00109 {
00110         FEDM_XML_TREE_LIST_ITOR Itor;
00111 
00112         for(Itor = m_XmlTree.begin(); Itor != m_XmlTree.end(); Itor++)
00113         {
00114                 if((*Itor) != NULL)
00115                 {
00116                         DeleteTagItem(*(Itor));
00117                 }
00118         }
00119 
00120         m_XmlTree.clear();
00121 }
00122 
00123 /***************************************************************************
00124   Begin         :       07.04.2003 / M. Hultsch
00125   Version       :       01.08.00 / 24.04.2003 / M. Hultsch
00126 
00127   Function              :       delete of a child tree item
00128                                         - for recursive use -
00129 
00130   Parameters    :       FEDM_XML_TREEITEM* item - parent item
00131 
00132   Return value  :       FEDM_OK or error code (<0)
00133 ***************************************************************************/
00134 int FEDM_XMLBase::DeleteTagItem(FEDM_XML_TREEITEM* item)
00135 {
00136         FEDM_CHK5(item);
00137 
00138 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
00139         char buf[256];
00140 #endif
00141         FEDM_XML_TREE_LIST_ITOR TreeItor;
00142         FEDM_XML_ATTRIBUTE_LIST_ITOR AttrItor;
00143 
00144         for(TreeItor = item->aChildList.begin(); TreeItor != item->aChildList.end(); TreeItor++)
00145         {
00146                 if((*TreeItor) != NULL)
00147                 {
00148                         DeleteTagItem(*TreeItor);
00149                 }
00150         }
00151 
00152         item->aChildList.clear();
00153 
00154         for(AttrItor = item->aAttribList.begin(); AttrItor != item->aAttribList.end(); AttrItor++)
00155         {
00156 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
00157                 sprintf(buf, "%S=%S", (*AttrItor)->sAttribute.c_str(), (*AttrItor)->sValue.c_str());
00158                 TRACE("deleting attribute: %s\n", buf);
00159                 ::Sleep(0);
00160 #endif
00161                 (*AttrItor)->sAttribute.erase();
00162                 (*AttrItor)->sValue.erase();
00163 
00164                 delete *AttrItor;
00165         }
00166 
00167 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
00168         swscanf(item->sTag.c_str(), L"%S", buf);
00169         TRACE("deleting tag: %s\n", buf);
00170         ::Sleep(0);
00171 #endif
00172         delete item;
00173 
00174         return FEDM_OK;
00175 }
00176 
00177 
00178 //#####################################################################################
00179 // query functions
00180 //#####################################################################################
00181 
00182 /***************************************************************************
00183   Begin         :       28.03.2007 / M. Hultsch
00184   Version       :       02.05.08 / 28.03.2007 / M. Hultsch
00185 
00186   Function              :       open a xml document and get the document type
00187 
00188   Parameters    :       char* sFileName         - pointer to string with file name
00189                                         char* sDocType          - pointer to string for document type
00190                                         char* sDocVersion       - pointer to string for document version
00191 
00192   Return value  :       FEDM_OK or error code (<0)
00193 ***************************************************************************/
00194 int FEDM_XMLBase::QueryDocType(char* sFileName, char* sDocType, char* sDocVersion)
00195 {
00196         int iBack = 0;
00197         unsigned int i = 0;
00198         FEDM_XML_TREEITEM* root = NULL;
00199         FEDM_XML_TREEITEM* parent = NULL;
00200         FEDM_XML_TREEITEM* child = NULL;
00201 
00202         
00203         iBack = OpenDoc(sFileName, "r");
00204         if(iBack)
00205                 return iBack;
00206         
00207         // is it a xml document?
00208         if(IsXmlDoc())
00209         {
00210                 CloseDoc();
00211                 return m_iLastError;
00212         }
00213 
00214         // has the xml document an OBID tag?
00215         if(HasOBIDTag())
00216         {
00217                 CloseDoc();
00218                 return m_iLastError;
00219         }
00220         
00221         // read complete xml document into string
00222         if(ReadDoc())
00223         {
00224                 CloseDoc();
00225                 return m_iLastError;
00226         }
00227 
00228         CloseDoc();
00229 
00230         // root tag
00231         root = FindTag(FEDM_XML_TAG_OBID_UC);
00232         if(root == NULL)
00233                 return m_iLastError;
00234         AddTagItem(NULL, root);
00235 
00236         // header tag
00237         child = FindTag(FEDM_XML_TAG_FILE_HDR_UC);
00238         if(child == NULL)
00239         {
00240                 DeleteXmlTree(); // clean up
00241                 return m_iLastError;
00242         }
00243         AddTagItem(root, child);
00244         parent = child;
00245 
00246         // header tag document type
00247         child = FindTag(FEDM_XML_TAG_DOC_TYPE_UC);
00248         if(child == NULL)
00249         {
00250                 DeleteXmlTree(); // clean up
00251                 return m_iLastError;
00252         }
00253         AddTagItem(parent, child);
00254         m_wsDocType = child->sValue;
00255 
00256 #if defined(__BORLANDC__) || defined(_MSC_VER)
00257         for (i=0; i<child->sValue.length(); i++)
00258                 sDocType[i] = (char)(child->sValue.c_str())[i];
00259         sDocType[i] = '\0';
00260 #elif defined(_FEDM_SUPPORT_UCLINUX)
00261         FEDM_SWSCANF(child->sValue.c_str(), sDocType);
00262 #else
00263         swscanf(child->sValue.c_str(), L"%s", sDocType);
00264 #endif
00265 
00266         // header tag document version
00267         child = FindTag(FEDM_XML_TAG_DOC_VERSION_UC);
00268         if(child == NULL)
00269         {
00270                 DeleteXmlTree(); // clean up
00271                 return m_iLastError;
00272         }
00273         m_wsDocVer = child->sValue;
00274 
00275 #if defined(__BORLANDC__) || defined(_MSC_VER)
00276         swscanf(child->sValue.c_str(), L"%S", sDocVersion);
00277 #elif defined(_FEDM_SUPPORT_UCLINUX)
00278         FEDM_SWSCANF(child->sValue.c_str(), sDocVersion);
00279 #else
00280         swscanf(child->sValue.c_str(), L"%s", sDocVersion);
00281 #endif
00282         
00283         delete child;
00284         DeleteXmlTree(); // clean up
00285 
00286         FEDM_RETURN(FEDM_OK);
00287 }
00288 
00289 /***************************************************************************
00290   Begin         :       08.08.2011 / M. Hultsch
00291   Version       :       04.00.02 / 08.08.2011 / M. Hultsch
00292 
00293   Function              :       open a xml document and get the document type
00294 
00295   Parameters    :       char* sFileName         - pointer to string with file name
00296                                         char* sRootTag          - pointer to root tag name
00297                                         char* sDocType          - pointer to string for document type
00298                                         char* sDocVersion       - pointer to string for document version
00299 
00300   Return value  :       FEDM_OK or error code (<0)
00301 ***************************************************************************/
00302 int FEDM_XMLBase::QueryDocType(char* sFileName, const char* sRootTag, char* sDocType, char* sDocVersion)
00303 {
00304         int iBack = 0;
00305         unsigned int i = 0;
00306         wchar_t wcRootTag[64];
00307         FEDM_XML_TREEITEM* root = NULL;
00308         FEDM_XML_TREEITEM* parent = NULL;
00309         FEDM_XML_TREEITEM* child = NULL;
00310 
00311         
00312         iBack = OpenDoc(sFileName, "r");
00313         if(iBack)
00314                 return iBack;
00315         
00316         // is it a xml document?
00317         if(IsXmlDoc())
00318         {
00319                 CloseDoc();
00320                 return m_iLastError;
00321         }
00322 
00323         // read complete xml document into string
00324         if(ReadDoc())
00325         {
00326                 CloseDoc();
00327                 return m_iLastError;
00328         }
00329 
00330         CloseDoc();
00331 
00332         // root tag
00333         if(strlen(sRootTag) > 0)
00334         {
00335 #if defined(__BORLANDC__)
00336                 swprintf(wcRootTag, L"%S", sRootTag);
00337 #elif defined(_MSC_VER)
00338         #if defined(_WIN32_WCE)
00339                 swprintf(wcRootTag, L"%S", sRootTag);
00340         #else
00341         #if _MSC_VER <= 1200
00342                 swprintf(wcRootTag, L"%S", sRootTag);
00343         #else
00344                 swprintf(wcRootTag, 64, L"%S", sRootTag);
00345         #endif
00346         #endif
00347 #else
00348                 swprintf(wcRootTag, 64, L"%S", sRootTag);
00349 #endif
00350                 root = FindTag(wcRootTag);
00351                 if(root == NULL)
00352                         return m_iLastError;
00353                 AddTagItem(NULL, root);
00354         }
00355         else
00356         {
00357                 root = new FEDM_XML_TREEITEM;
00358                 AddTagItem(NULL, root);
00359         }
00360 
00361         // header tag
00362         child = FindTag(FEDM_XML_TAG_FILE_HDR_UC);
00363         if(child == NULL)
00364         {
00365                 DeleteXmlTree(); // clean up
00366                 return m_iLastError;
00367         }
00368         AddTagItem(root, child);
00369         parent = child;
00370 
00371         // header tag document type
00372         child = FindTag(FEDM_XML_TAG_DOC_TYPE_UC);
00373         if(child == NULL)
00374         {
00375                 DeleteXmlTree(); // clean up
00376                 return m_iLastError;
00377         }
00378         AddTagItem(parent, child);
00379         m_wsDocType = child->sValue;
00380 
00381 #if defined(__BORLANDC__) || defined(_MSC_VER)
00382         for (i=0; i<child->sValue.length(); i++)
00383                 sDocType[i] = (char)(child->sValue.c_str())[i];
00384         sDocType[i] = '\0';
00385 #elif defined(_FEDM_SUPPORT_UCLINUX)
00386         FEDM_SWSCANF(child->sValue.c_str(), sDocType);
00387 #else
00388         swscanf(child->sValue.c_str(), L"%s", sDocType);
00389 #endif
00390 
00391         // header tag document version
00392         child = FindTag(FEDM_XML_TAG_DOC_VERSION_UC);
00393         if(child == NULL)
00394         {
00395                 DeleteXmlTree(); // clean up
00396                 return m_iLastError;
00397         }
00398         m_wsDocVer = child->sValue;
00399 
00400 #if defined(__BORLANDC__) || defined(_MSC_VER)
00401         swscanf(child->sValue.c_str(), L"%S", sDocVersion);
00402 #elif defined(_FEDM_SUPPORT_UCLINUX)
00403         FEDM_SWSCANF(child->sValue.c_str(), sDocVersion);
00404 #else
00405         swscanf(child->sValue.c_str(), L"%s", sDocVersion);
00406 #endif
00407         
00408         delete child;
00409         DeleteXmlTree(); // clean up
00410 
00411         FEDM_RETURN(FEDM_OK);
00412 }
00413 
00414 
00415 
00416 
00417 //#####################################################################################
00418 // document management
00419 //#####################################################################################
00420 
00421 /***************************************************************************
00422   Begin         :       01.04.2003 / M. Hultsch
00423   Version       :       01.08.00 / 03.04.2003 / M. Hultsch
00424 
00425   Function              :       open a file
00426                                         append xml header, if write mode
00427 
00428   Parameters    :       char*   sFileName               - pointer to file name with path
00429                                         char*   sMode                   - file open options
00430                                                                                           "r" for read
00431                                                                                           "w" for write
00432                                         bool    bAddCopyright   - add copiright comment after head line
00433 
00434   Return value  :       FEDM_OK or error code
00435 ***************************************************************************/
00436 int FEDM_XMLBase::OpenDoc(char* sFileName, char* sMode, bool bAddCopyright)
00437 {
00438         FEDM_CHK5(sFileName);
00439         FEDM_CHK5(sMode);
00440 
00441         int iBack = 0;
00442 
00443         m_file = fopen(sFileName, sMode);
00444         if(m_file == NULL)
00445                 FEDM_RETURN(FEDM_ERROR_OPEN_FILE);
00446 
00447 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
00448         TRACE("open xml doc: %s\n", sFileName);
00449         ::Sleep(0);
00450 #endif
00451 
00452         // add header if write mode
00453         if(strcmp("w", sMode) == 0)
00454         {
00455                 m_sXmlStream  = L"<?xml version=";
00456                 m_sXmlStream += L"\"";
00457                 m_sXmlStream += FEDM_XML_STRING_XML_VERSION_UC;
00458                 m_sXmlStream += L"\"";
00459                 m_sXmlStream += L" encoding=";
00460                 m_sXmlStream += L"\"";
00461                 m_sXmlStream += FEDM_XML_STRING_XML_ENCODING_UC;
00462                 m_sXmlStream += L"\"";
00463                 m_sXmlStream += L" standalone=";
00464                 m_sXmlStream += L"\"";
00465                 m_sXmlStream += FEDM_XML_STRING_XML_STANDALONE_UC;
00466                 m_sXmlStream += L"\"";
00467                 m_sXmlStream += L"?>";
00468                 m_sXmlStream += L"\n";
00469 
00470                 if(bAddCopyright)
00471                 {
00472                         m_sXmlStream += m_sXmlComment;
00473                 }
00474         }
00475         else
00476         {
00477                 // query the file size to reserve memory for the wstring buffer
00478 #if defined(_FEDM_WINDOWS)
00479 #if defined(_WIN32_WCE)
00480                 CFileStatus status;
00481                 CString strFileName = sFileName;
00482                 if(CFile::GetStatus(strFileName, status))
00483                 {
00484                         m_sXmlStream.reserve((unsigned int)status.m_size + 1);
00485                 }
00486 #else
00487                 struct _stat buf;
00488                 iBack = _stat(sFileName, &buf);
00489                 
00490                 if(iBack == 0)
00491                 {
00492                         // resize buffer for m_sXmlStream
00493                         m_sXmlStream.reserve(buf.st_size + 1);
00494                 }
00495 #endif
00496 #endif
00497 #if defined(_FEDM_LINUX)
00498                 struct stat buf;
00499                 iBack = stat(sFileName, &buf);
00500                 
00501                 if(iBack == 0)
00502                 {
00503                         // resize buffer for m_sXmlStream
00504                         m_sXmlStream.reserve(buf.st_size + 1);
00505                 }
00506 #endif
00507         }
00508 
00509         FEDM_RETURN(FEDM_OK);
00510 }
00511 
00512 /***************************************************************************
00513   Begin         :       01.04.2003 / M. Hultsch
00514   Version       :       01.08.00 / 03.04.2003 / M. Hultsch
00515 
00516   Function              :       close the file
00517 
00518   Parameters    :       -
00519 
00520   Return value  :       FEDM_OK
00521 ***************************************************************************/
00522 int FEDM_XMLBase::CloseDoc()
00523 {
00524         if(m_file != NULL)
00525         {
00526 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
00527                 TRACE("close xml doc\n");
00528                 ::Sleep(0);
00529 #endif
00530                 fclose(m_file);
00531         }
00532 
00533         m_file = NULL;
00534 
00535         return FEDM_OK;
00536 }
00537 
00538 /***************************************************************************
00539   Begin         :       01.04.2003 / M. Hultsch
00540   Version       :       01.08.00 / 14.05.2003 / M. Hultsch
00541 
00542   Function              :       checks, if file is a xml document
00543 
00544   Parameters    :       -
00545 
00546   Return value  :       FEDM_OK or error code
00547 ***************************************************************************/
00548 int FEDM_XMLBase::IsXmlDoc()
00549 {
00550         if(m_file == NULL)
00551                 FEDM_RETURN(FEDM_ERROR_NULL_POINTER);
00552 
00553         char cBuffer[17];
00554         char* cSubStr;
00555         size_t iLen = 0;
00556 
00557         // set read position to begin of file
00558         if(fseek(m_file, 0, SEEK_SET))
00559                 FEDM_RETURN(FEDM_ERROR_READ_FILE);
00560 
00561 
00562         // read first 16 chars (string "<?xml" inside expected)
00563         iLen = fread(cBuffer, sizeof(char), 16, m_file);
00564         if(iLen < 16)
00565                 FEDM_RETURN(FEDM_XML_ERROR_NO_XML_FILE);
00566 
00567         cBuffer[16] = '\0';
00568 
00569         // is string "<?xml" inside?
00570         cSubStr = strstr(cBuffer, "<?xml");
00571         if(cSubStr == NULL)
00572                 FEDM_RETURN(FEDM_XML_ERROR_NO_XML_FILE);
00573 
00574         cSubStr[5] = '\0';
00575 
00576         if(strcmp("<?xml", cSubStr) == 0)
00577                 FEDM_RETURN(FEDM_OK);
00578 
00579         // no string match found
00580         FEDM_RETURN(FEDM_XML_ERROR_NO_XML_FILE);
00581 }
00582 
00583 /***************************************************************************
00584   Begin         :       01.04.2003 / M. Hultsch
00585   Version       :       02.05.08 / 20.03.2007 / M. Hultsch
00586 
00587   Function              :       checks, if xml document has an OBID tag
00588 
00589   Parameters    :       -
00590 
00591   Return value  :       FEDM_OK or error code
00592 ***************************************************************************/
00593 int FEDM_XMLBase::HasOBIDTag()
00594 {
00595         if(m_file == NULL)
00596                 FEDM_RETURN(FEDM_ERROR_NULL_POINTER);
00597 
00598         char cBuffer[128];
00599         char* cSubStr = NULL;
00600         size_t iLen = 0;
00601 
00602         // set read position to begin of file
00603         if(fseek(m_file, 0, SEEK_SET))
00604                 FEDM_RETURN(FEDM_ERROR_READ_FILE);
00605 
00606         // read first 128 wide chars (string "<OBID>" inside expected, or repeat)
00607         iLen = fread(cBuffer, sizeof(char), 128, m_file);
00608         while(iLen > 0)
00609         {
00610                 cSubStr = strstr(cBuffer, "<OBID>");
00611                 if(cSubStr != NULL)
00612                         break;
00613 
00614                 iLen = fread(cBuffer, sizeof(char), 128, m_file);
00615         }
00616 
00617         if(cSubStr == NULL)
00618                 FEDM_RETURN(FEDM_XML_ERROR_NO_OBID_TAG);
00619 
00620         cSubStr[6] = '\0';
00621 
00622         if(strcmp("<OBID>", cSubStr) == 0)
00623                 FEDM_RETURN(FEDM_OK);
00624 
00625         // no string match found
00626         FEDM_RETURN(FEDM_XML_ERROR_NO_OBID_TAG);
00627 }
00628 
00629 /***************************************************************************
00630   Begin         :       22.08.2011 / M. Hultsch
00631   Version       :       04.00.02 / 22.08.2011 / M. Hultsch
00632 
00633   Function              :       checks, if xml document has a root tag <szOemRootTag>
00634 
00635   Parameters    :       -
00636 
00637   Return value  :       FEDM_OK or error code
00638 ***************************************************************************/
00639 int FEDM_XMLBase::HasRootTag(const char* szOemRootTag)
00640 {
00641         if(m_file == NULL)
00642                 FEDM_RETURN(FEDM_ERROR_NULL_POINTER);
00643 
00644         char cBuffer[128];
00645         char* cSubStr = NULL;
00646         size_t iLen = 0;
00647         string sRootTag = "<";
00648         sRootTag += szOemRootTag;
00649         sRootTag += ">";
00650 
00651         // set read position to begin of file
00652         if(fseek(m_file, 0, SEEK_SET))
00653                 FEDM_RETURN(FEDM_ERROR_READ_FILE);
00654 
00655         // read first 128 wide chars (string "<OBID>" inside expected, or repeat)
00656         iLen = fread(cBuffer, sizeof(char), 128, m_file);
00657         while(iLen > 0)
00658         {
00659                 cSubStr = strstr(cBuffer, sRootTag.c_str());
00660                 if(cSubStr != NULL)
00661                         break;
00662 
00663                 iLen = fread(cBuffer, sizeof(char), 128, m_file);
00664         }
00665 
00666         if(cSubStr == NULL)
00667                 FEDM_RETURN(FEDM_XML_ERROR_TAG_NOT_FOUND);
00668 
00669         cSubStr[sRootTag.size()] = '\0';
00670 
00671         if(strcmp(sRootTag.c_str(), cSubStr) == 0)
00672                 FEDM_RETURN(FEDM_OK);
00673 
00674         // no string match found
00675         FEDM_RETURN(FEDM_XML_ERROR_TAG_NOT_FOUND);
00676 }
00677 
00678 /***************************************************************************
00679   Begin         :       01.04.2003 / M. Hultsch
00680   Version       :       01.08.00 / 04.09.2003 / M. Hultsch
00681 
00682   Function              :       read the complete xml document
00683 
00684   Parameters    :       -
00685 
00686   Return value  :       FEDM_OK or error code
00687 ***************************************************************************/
00688 int FEDM_XMLBase::ReadDoc()
00689 {
00690         bool bFirstRead = true;
00691         char cBuffer[101];
00692         wchar_t wcBuffer[101];
00693         size_t iRead = 0;
00694 
00695         if(m_file == NULL)
00696                 FEDM_RETURN(FEDM_ERROR_NULL_POINTER);
00697 
00698         // set read position to begin of file
00699         if(fseek(m_file, 0, SEEK_SET))
00700                 FEDM_RETURN(FEDM_ERROR_READ_FILE);
00701 
00702         // delete content of xml string
00703         m_sXmlStream.erase();
00704 
00705         // read loop
00706         while(! feof(m_file))
00707         {
00708                 iRead = fread(cBuffer, sizeof(char), 100, m_file);
00709                 if(iRead <= 0)
00710                 {
00711                         int err = ferror(m_file);
00712                         if(err)
00713                         {
00714                                 FEDM_RETURN(FEDM_ERROR_READ_FILE);
00715                         }
00716                         else
00717                         {
00718                         }
00719                 }
00720 
00721                 cBuffer[iRead] = '\0';
00722 #if defined(__BORLANDC__) || defined(_MSC_VER)
00723                 swprintf(wcBuffer, L"%S", cBuffer);
00724 #else
00725                 swprintf(wcBuffer, 101, L"%s", cBuffer);
00726 #endif
00727                 m_sXmlStream += wcBuffer;
00728 
00729                 if(bFirstRead)
00730                 {
00731                         bFirstRead = false;
00732                         ReadXmlHeader(cBuffer);
00733                 }
00734         }
00735 
00736         // delete old xml tree
00737         DeleteXmlTree();
00738 
00739         FEDM_RETURN(FEDM_OK);
00740 }
00741 
00742 /***************************************************************************
00743   Begin         :       14.09.2007 / M. Hultsch
00744   Version       :       03.00.08 / 30.06.2009 / M. Hultsch
00745 
00746   Function              :       ste xml stream to parse for
00747 
00748   Parameters    :       wstring sXmlStream
00749 
00750   Return value  :       FEDM_OK or error code
00751 ***************************************************************************/
00752 int FEDM_XMLBase::LoadStream(wstring sXmlStream)
00753 {
00754         // delete content of xml string
00755         m_sXmlStream.erase();
00756 
00757         m_sXmlStream = sXmlStream;
00758 
00759         FEDM_RETURN(FEDM_OK);
00760 }
00761 
00762 /***************************************************************************
00763   Begin         :       01.04.2003 / M. Hultsch
00764   Version       :       01.08.00 / 03.09.2003 / M. Hultsch
00765 
00766   Function              :       write the complete xml document into the file
00767 
00768   Parameters    :       -
00769 
00770   Return value  :       FEDM_OK or error code
00771 ***************************************************************************/
00772 int FEDM_XMLBase::WriteDoc()
00773 {
00774         if(m_file == NULL)
00775                 FEDM_RETURN(FEDM_ERROR_NULL_POINTER);
00776 
00777         FEDM_XML_TREE_LIST_ITOR Itor;
00778 
00779         // build xml string
00780         for(Itor = m_XmlTree.begin(); Itor != m_XmlTree.end(); Itor++)
00781         {
00782                 if((*Itor) != NULL)
00783                         WriteTagStream(*Itor);
00784         }
00785 
00786         // write xml string into document
00787         int iBack = fwprintf(m_file, m_sXmlStream.c_str());
00788 
00789         // delete content of xml string
00790         m_sXmlStream.erase();
00791         
00792         // delete xml tree
00793         DeleteXmlTree();
00794 
00795         if(iBack <= 0)
00796                 FEDM_RETURN(FEDM_ERROR_WRITE_FILE);
00797 
00798         FEDM_RETURN(FEDM_OK);
00799 }
00800 
00801 /***************************************************************************
00802   Begin         :       13.09.2007 / M. Hultsch
00803   Version       :       03.00.00 / 13.09.2007 / M. Hultsch
00804 
00805   Function              :       write the complete xml document into a stream
00806 
00807   Parameters    :       -
00808 
00809   Return value  :       FEDM_OK or error code
00810 ***************************************************************************/
00811 wstring FEDM_XMLBase::WriteStream()
00812 {
00813         FEDM_XML_TREE_LIST_ITOR Itor;
00814 
00815         // delete content of xml string
00816         m_sXmlStream.erase();
00817         
00818         // build xml string
00819         for(Itor = m_XmlTree.begin(); Itor != m_XmlTree.end(); Itor++)
00820         {
00821                 if((*Itor) != NULL)
00822                         WriteTagStream(*Itor);
00823         }
00824 
00825 
00826         // delete xml tree
00827         DeleteXmlTree();
00828 
00829         return m_sXmlStream;
00830 }
00831 
00832 /***************************************************************************
00833   Begin         :       01.04.2003 / M. Hultsch
00834   Version       :       04.00.02 / 22.08.2011 / M. Hultsch
00835 
00836   Function              :       write one tag into the xml string
00837                                         - for recursive use -
00838 
00839   Parameters    :       FEDM_XML_TREEITEM* item
00840 
00841   Return value  :       FEDM_OK or error code (<0)
00842 ***************************************************************************/
00843 int FEDM_XMLBase::WriteTagStream(FEDM_XML_TREEITEM* item)
00844 {
00845         FEDM_CHK5(item);
00846 
00847         int iPos = 0;
00848         wstring wStr;
00849         FEDM_XML_TREE_LIST_ITOR TreeItor;
00850         FEDM_XML_ATTRIBUTE_LIST_ITOR AttrItor;
00851 
00852         // building string part 1a: start tag
00853         m_sXmlStream += L"<";
00854         m_sXmlStream += item->sTag;
00855 
00856 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
00857         char buf[256];
00858         swscanf(item->sTag.c_str(), L"%S", buf);
00859         TRACE("writing tag: %s\n", buf);
00860         ::Sleep(0);
00861 #endif
00862 
00863         // building string part 2: insert tag attributes
00864         for(AttrItor = item->aAttribList.begin(); AttrItor != item->aAttribList.end(); AttrItor++)
00865         {
00866                 m_sXmlStream += L" ";
00867                 m_sXmlStream += (*AttrItor)->sAttribute;
00868                 m_sXmlStream += L"=";
00869                 m_sXmlStream += L"\"";
00870                 m_sXmlStream += (*AttrItor)->sValue;
00871                 m_sXmlStream += L"\"";
00872 
00873 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
00874                 char buf[256];
00875                 sprintf(buf, "%S=%S", (*AttrItor)->sAttribute.c_str(), (*AttrItor)->sValue.c_str());
00876                 TRACE("writing attribute: %s\n", buf);
00877                 ::Sleep(0);
00878 #endif
00879         }
00880 
00881         // building string part 1b: start tag
00882         if(item->bEmpty)
00883                 m_sXmlStream += L"/";
00884         m_sXmlStream += L">";
00885         if(item->bNewLine)              // add new line char
00886                 m_sXmlStream += L"\n";
00887 
00888         // building string part 3: insert child tags
00889         for(TreeItor = item->aChildList.begin(); TreeItor != item->aChildList.end(); TreeItor++)
00890         {
00891                 if((*TreeItor) != NULL)
00892                         WriteTagStream(*TreeItor);
00893         }
00894 
00895         // building string part 4: tag value
00896         if(! item->bEmpty)
00897         {
00898                 // search for: < > & " ' 
00899                 iPos = (int)item->sValue.find(L"&");
00900                 while(iPos >= 0)
00901                 {
00902                         item->sValue.replace(iPos, 1, L"&amp;");
00903                         iPos = (int)item->sValue.find(L"&", iPos+1);
00904                 }
00905 
00906                 iPos = (int)item->sValue.find(L"<");
00907                 while(iPos >= 0)
00908                 {
00909                         item->sValue.replace(iPos, 1, L"&lt;");
00910                         iPos = (int)item->sValue.find(L"<", iPos+1);
00911                 }
00912 
00913                 iPos = (int)item->sValue.find(L">");
00914                 while(iPos >= 0)
00915                 {
00916                         item->sValue.replace(iPos, 1, L"&gt;");
00917                         iPos = (int)item->sValue.find(L">", iPos+1);
00918                 }
00919 
00920                 iPos = (int)item->sValue.find(L"\"");
00921                 while(iPos >= 0)
00922                 {
00923                         item->sValue.replace(iPos, 1, L"&quot;");
00924                         iPos = (int)item->sValue.find(L"\"", iPos+1);
00925                 }
00926 
00927                 iPos = (int)item->sValue.find(L"'");
00928                 while(iPos >= 0)
00929                 {
00930                         item->sValue.replace(iPos, 1, L"&apos;");
00931                         iPos = (int)item->sValue.find(L"'", iPos+1);
00932                 }
00933 
00934                 m_sXmlStream += item->sValue;
00935         }
00936 
00937         // building string part 5: end tag
00938         if(! item->bEmpty)      // tag name in end tag
00939         {
00940                 m_sXmlStream += L"</";
00941                 m_sXmlStream += item->sTag;
00942                 m_sXmlStream += L">";
00943         }
00944 
00945         m_sXmlStream += L"\n";
00946 
00947         FEDM_RETURN(FEDM_OK);
00948 }
00949 
00950 
00951 
00952 //#####################################################################################
00953 // tag functions
00954 //#####################################################################################
00955 
00956 /***************************************************************************
00957   Begin         :       08.04.2003 / M. Hultsch
00958   Version       :       01.08.00 / 08.04.2003 / M. Hultsch
00959 
00960   Function              :       build a tree item
00961 
00962   Parameters    :       wstring sTag    - tags name (in UNICODE)
00963                                         bool bNewLine   - new line after end tag
00964                                         bool bEmpty             - empty tag
00965 
00966   Return value  :       FEDM_XML_TREEITEM*      - pointer to new tree item
00967 ***************************************************************************/
00968 FEDM_XML_TREEITEM* FEDM_XMLBase::BuildTag(wstring sTag, bool bNewLine, bool bEmpty)
00969 {
00970         if(sTag.empty())
00971         {
00972                 SetLastError(FEDM_ERROR_PARAMETER);
00973                 return NULL;
00974         }
00975 
00976         FEDM_XML_TREEITEM* item = new FEDM_XML_TREEITEM;
00977 
00978         if(item == NULL)
00979         {
00980                 SetLastError(FEDM_ERROR_NO_MORE_MEM);
00981                 return NULL;
00982         }
00983 
00984         item->sTag = sTag;
00985         item->bNewLine = bNewLine;
00986         item->bEmpty = bEmpty;
00987 
00988 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
00989         char buf[256];
00990         swscanf(sTag.c_str(), L"%S", buf);
00991         TRACE("build tag: %s\n", buf);
00992         ::Sleep(0);
00993 #endif
00994 
00995         SetLastError(FEDM_OK);
00996         return item;
00997 }
00998 
00999 /***************************************************************************
01000   Begin         :       07.04.2003 / M. Hultsch
01001   Version       :       01.08.00 / 08.04.2003 / M. Hultsch
01002 
01003   Function              :       add a value to a tree item
01004 
01005   Parameters    :       FEDM_XML_TREEITEM* item - pointer to tree item
01006                                         wstring sValue                  - tags value (in UNICODE)
01007 
01008   Return value  :       FEDM_OK or error code
01009 ***************************************************************************/
01010 int FEDM_XMLBase::AddTagValue(FEDM_XML_TREEITEM* item, wstring sValue)
01011 {
01012         FEDM_CHK5(item);
01013 
01014         if(sValue.empty())
01015         {
01016                 item->bEmpty = true;
01017                 FEDM_RETURN(FEDM_OK);
01018         }
01019 
01020         item->sValue = sValue;
01021         item->bEmpty = false;
01022 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
01023         char buf[256];
01024         sprintf(buf, "%S", item->sValue.c_str());
01025         TRACE("add tag value: %s\n", buf);
01026         ::Sleep(0);
01027 #endif
01028 
01029         FEDM_RETURN(FEDM_OK);
01030 }
01031 
01032 /***************************************************************************
01033   Begin         :       07.04.2003 / M. Hultsch
01034   Version       :       03.00.00 / 05.05.2007 / M. Hultsch
01035 
01036   Function              :       add an attribute to a tree item
01037 
01038   Parameters    :       FEDM_XML_TREEITEM* item - pointer to tree item
01039                                         wstring sAttrib                 - tags attribute (in UNICODE)
01040                                         wstring sValue                  - tags attribute value (in UNICODE)
01041 
01042   Return value  :       FEDM_OK or error code
01043 ***************************************************************************/
01044 int FEDM_XMLBase::AddTagAttrib(FEDM_XML_TREEITEM* item, wstring sAttrib, wstring sValue)
01045 {
01046         FEDM_CHK5(item);
01047 
01048         if(sAttrib.empty())
01049                 FEDM_RETURN(FEDM_ERROR_PARAMETER);
01050         
01051         FEDM_XML_ATTRIBUTE* pAttribute = new FEDM_XML_ATTRIBUTE;
01052 
01053         if(pAttribute == NULL)
01054                 FEDM_RETURN(FEDM_ERROR_NO_MORE_MEM);
01055 
01056         pAttribute->sAttribute = sAttrib;
01057         pAttribute->sValue = sValue;
01058 
01059         item->aAttribList.push_back(pAttribute);
01060 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
01061         char buf[256];
01062         sprintf(buf, "%S=%S", pAttribute->sAttribute.c_str(), pAttribute->sValue.c_str());
01063         TRACE("add tag attribute: %s\n", buf);
01064         ::Sleep(0);
01065 #endif
01066 
01067         FEDM_RETURN(FEDM_OK);
01068 }
01069 
01070 /***************************************************************************
01071   Begin         :       01.04.2003 / M. Hultsch
01072   Version       :       01.08.00 / 08.04.2003 / M. Hultsch
01073 
01074   Function              :       adds a tag to the xml tree
01075 
01076   Parameters    :       FEDM_XML_TREEITEM* pParent      - pointer to tree item of parent
01077                                         FEDM_XML_TREEITEM* pChild       - pointer to tree item of child
01078 
01079   Return value  :       FEDM_OK or error code
01080 ***************************************************************************/
01081 int FEDM_XMLBase::AddTagItem(FEDM_XML_TREEITEM* pParent, FEDM_XML_TREEITEM* pChild)
01082 {
01083         FEDM_CHK5(pChild);
01084 
01085 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
01086         char buf[256];
01087 #endif
01088 
01089         if(pParent == NULL)
01090         {
01091                 // root item
01092 
01093                 if(m_XmlTree.empty())
01094                 {
01095                         m_XmlTree.push_back(pChild);
01096 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
01097                         sprintf(buf, "%S", pChild->sTag.c_str());
01098                         TRACE("add root tag: %s\n", buf);
01099                         ::Sleep(0);
01100 #endif
01101                 }
01102                 else
01103                         FEDM_RETURN(FEDM_ERROR_PARAMETER);
01104         }
01105         else
01106         {
01107                 // child item
01108                 pParent->aChildList.push_back(pChild);
01109 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
01110                 sprintf(buf, "%S", pChild->sTag.c_str());
01111                 TRACE("add child tag: %s\n", buf);
01112                 ::Sleep(0);
01113 #endif
01114         }
01115 
01116         FEDM_RETURN(FEDM_OK);
01117 }
01118 
01119 /***************************************************************************
01120   Begin         :       01.04.2003 / M. Hultsch
01121   Version       :       03.00.00 / 05.07.2007 / M. Hultsch
01122 
01123   Function              :       itentify a tag inside the xml string
01124                                         pick out all attributes and values and create a tree item
01125 
01126   Parameters    :       wstring sTag            - tag string to be identify (in UNICODE)
01127                                         bool bInside=false      - find the tag inside the positions iPos1 
01128                                                                                   and iPos2 of last function call.
01129                                                                                   This allows the search of child tags 
01130                                                                                   inside a previously found parent tag
01131                                         bool bSavePos           - save the tag positions iPos1 and iPos2
01132                                         bool bNext                      - continue with search behind iPosEnd 
01133 
01134   Return value  :       FEDM_XML_TREEITEM*      - pointer to tree item
01135                                         NULL                            - in error case
01136 ***************************************************************************/
01137 FEDM_XML_TREEITEM* FEDM_XMLBase::FindTag(wstring sTag, 
01138                                                                                  bool bInside, 
01139                                                                                  bool bSavePos,
01140                                                                                  bool bNext)
01141 {
01142         if(m_sXmlStream.empty())
01143         {
01144                 SetLastError(FEDM_ERROR_NO_DATA);
01145                 return NULL;
01146         }
01147 
01148         // static int because of its reuse in the following function call
01149         static int iPosStart = 0;       // position start of tag
01150         static int iPosEnd   = 0;       // position end of tag
01151         static int iTagLen       = 0;   // length of start tag
01152 
01153         bool bAttrib = true;
01154         int iPos0 = 0;  // position start of empty tag
01155         int iPos1 = 0;  // position start of tag
01156         int iPos2 = 0;  // position end of tag
01157         int iPos3 = 0;  // position inside tag
01158         int iPos4 = 0;  // position inside tag
01159         int iPos5 = 0;  // position inside tag
01160         wstring s0, s1, s2, s3, s4;
01161         FEDM_XML_TREEITEM* item = NULL;
01162         FEDM_XML_ATTRIBUTE* attrib = NULL;
01163 
01164 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
01165         char buf[256];
01166 #endif
01167 
01168         // build search string for empty tag
01169         s0 = L"<";
01170         s0 += sTag;
01171         s0 += L"/>";
01172 
01173         // build search string for beginning tag
01174         s1 = L"<";
01175         s1 += sTag;
01176 
01177         // build search string for end tag
01178         s2 = L"</";
01179         s2 += sTag;
01180         s2 += L">";
01181 
01182         // create item structure
01183         item = new FEDM_XML_TREEITEM;
01184         if(item == NULL)
01185         {
01186                 SetLastError(FEDM_ERROR_NO_MORE_MEM);
01187                 return NULL;
01188         }
01189         item->sTag = sTag;
01190 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
01191         sprintf(buf, "%S", sTag.c_str());
01192         TRACE("new tag: %s\n", buf);
01193         ::Sleep(0);
01194 #endif
01195 
01196         // set search position behind iPosEnd
01197         if(bNext)
01198         {
01199                 iPosStart += iTagLen;
01200         }
01201 
01202         // search begin of tag
01203         if(bInside)
01204         {
01205                 // search begin of empty tag inside the previously found tag
01206                 iPos0 = (int)m_sXmlStream.find(s0.c_str(), iPosStart);
01207                 if(iPos0 > 0 && iPos0 > iPosStart && iPos0 < iPosEnd)
01208                 {
01209                         item->bEmpty = true;
01210                         SetLastError(FEDM_OK);
01211                         return item;
01212                 }
01213 
01214                 // search begin of tag inside the previously found tag
01215                 iPos1 = (int)m_sXmlStream.find(s1.c_str(), iPosStart);
01216 
01217                 if(iPos1 < 0 || iPos1 < iPosStart || iPos1 > iPosEnd)
01218                 {
01219                         SetLastError(FEDM_XML_ERROR_TAG_NOT_FOUND);
01220                         DeleteTagItem(item);
01221                         return NULL;
01222                 }
01223 
01224                 // search end of tag
01225                 iPos2 = (int)m_sXmlStream.find(s2.c_str(), iPos1);
01226                 if(iPos2 < 0 || iPos2 < iPosStart || iPos2 > iPosEnd)
01227                 {       // empty tag?
01228                 
01229                         // build search string for empty end tag..
01230                         s2 = L"/>";
01231                         // ..and try again
01232                         iPos2 = (int)m_sXmlStream.find(s2.c_str(), iPos1);
01233                         
01234                         if(iPos2 < 0 || iPos2 < iPosStart || iPos2 > iPosEnd)
01235                         {
01236                                 SetLastError(FEDM_XML_ERROR_TAG_NOT_FOUND);
01237                                 DeleteTagItem(item);
01238                                 return NULL;
01239                         }
01240 
01241                         // is there any '<' char inside?
01242                         iPos3 = (int)m_sXmlStream.find(L"<", iPos1, iPos2-iPos1);
01243                         if(iPos3 > 0 && (iPos3 < iPos1 || iPos3 > iPos2))
01244                         {
01245                                 SetLastError(FEDM_XML_ERROR_DOC_NOT_WELL_FORMED);
01246                                 DeleteTagItem(item);
01247                                 return NULL;
01248                         }
01249 
01250                         item->bEmpty = true;
01251 
01252                         // if no attributes, we can return
01253                         if(iPos2 - iPos1 - s1.size() == 0)
01254                         {
01255                                 SetLastError(FEDM_OK);
01256                                 return item;
01257                         }
01258                 }
01259                 else
01260                 {
01261                         item->bEmpty = false;
01262                 }
01263         }
01264         else
01265         {
01266                 // search begin of tag inside the complete xml string
01267                 if(bNext)
01268                 {
01269                         // search begin of empty tag
01270                         iPos0 = (int)m_sXmlStream.find(s0.c_str(), iPosStart);
01271                         if(iPos0 > 0 && iPos0 > iPosStart && iPos0 < iPosEnd)
01272                         {
01273                                 item->bEmpty = true;
01274                                 SetLastError(FEDM_OK);
01275                                 return item;
01276                         }
01277 
01278                         // start position �s behind last start position
01279                         iPos1 = (int)m_sXmlStream.find(s1.c_str(), iPosStart);
01280                 }
01281                 else
01282                 {
01283                         // search begin of empty tag inside the complete xml string
01284                         iPos0 = (int)m_sXmlStream.find(s0.c_str());
01285                         if(iPos0 > 0)
01286                         {
01287                                 item->bEmpty = true;
01288                                 SetLastError(FEDM_OK);
01289                                 return item;
01290                         }
01291 
01292                         // start position is at begin of xml string
01293                         iPos1 = (int)m_sXmlStream.find(s1.c_str());
01294                 }
01295 
01296                 if(iPos1 < 0 || iPos1 == (int)m_sXmlStream.size())
01297                 {
01298                         SetLastError(FEDM_XML_ERROR_TAG_NOT_FOUND);
01299                         DeleteTagItem(item);
01300                         return NULL;
01301                 }
01302 
01303                 // search end of tag
01304                 iPos2 = (int)m_sXmlStream.find(s2, iPos1);
01305                 if(iPos2 < 0 || iPos2 == (int)m_sXmlStream.size())
01306                 {       // empty tag?
01307                 
01308                         // build search string for empty end tag..
01309                         s2 = L"/>";
01310                         // ..and try again
01311                         iPos2 = (int)m_sXmlStream.find(s2, iPos1);
01312                         
01313                         if(iPos2 < 0 || iPos2 == (int)m_sXmlStream.size())
01314                         {
01315                                 SetLastError(FEDM_XML_ERROR_TAG_NOT_FOUND);
01316                                 DeleteTagItem(item);
01317                                 return NULL;
01318                         }
01319 
01320                         // is there any '<' char inside?
01321                         iPos3 = (int)m_sXmlStream.find(L"<", iPos1, iPos2-iPos1);
01322                         if(iPos3 > 0 && (iPos3 < iPos1 || iPos3 > iPos2))
01323                         {
01324                                 SetLastError(FEDM_XML_ERROR_DOC_NOT_WELL_FORMED);
01325                                 DeleteTagItem(item);
01326                                 return NULL;
01327                         }
01328 
01329                         item->bEmpty = true;
01330 
01331                         // if no attributes, we can return
01332                         if(iPos2 - iPos1 - s1.size() == 0)
01333                         {
01334                                 SetLastError(FEDM_OK);
01335                                 return item;
01336                         }
01337                 }
01338                 else
01339                 {       
01340                         item->bEmpty = false;
01341                 }
01342         }
01343 
01344         // get next char and check, if it is a space char or '>' char
01345         s3 = m_sXmlStream.at(iPos1 + s1.size());
01346         if(s3 == L" ")
01347         {       
01348                 // get end position of start tag
01349                 iPos3 = (int)m_sXmlStream.find_first_of(L">", iPos1);
01350 
01351                 // extract substring with all attrubutes
01352                 s3 = m_sXmlStream.substr(iPos1 + s1.size() + 1, iPos3 - iPos1 - s1.size() - 1);
01353 
01354                 // tokenize
01355                 bAttrib = true; // toggles between attributes name and attributes value
01356                 iPos4 = 0; // set start position
01357                 while(iPos4 < (int)s3.size())
01358                 {
01359                         if(bAttrib)
01360                         {
01361                                 iPos5 = (int)s3.find_first_of(L"=", iPos4);
01362                                 if(iPos5 < 0 || iPos5 >= (int)s3.size())
01363                                 {
01364                                         SetLastError(FEDM_XML_ERROR_DOC_NOT_WELL_FORMED);
01365                                         break;
01366                                 }
01367 
01368                                 // create attribute pair
01369                                 attrib = new FEDM_XML_ATTRIBUTE;
01370                                 if(attrib == NULL)
01371                                 {
01372                                         SetLastError(FEDM_ERROR_NO_MORE_MEM);
01373                                         break;
01374                                 }
01375 
01376                                 // add attribute name
01377                                 if(s3[iPos4] == L' ')
01378                                         attrib->sAttribute = s3.substr(iPos4+1, iPos5-iPos4-1);
01379                                 else
01380                                         attrib->sAttribute = s3.substr(iPos4, iPos5-iPos4);
01381 
01382                                 bAttrib = false;        // continue with attribute value
01383                                 iPos4 = iPos5 + 1;      // positioning after '='
01384                         }
01385                         else
01386                         {
01387                                 if(s3[iPos4] == L'\"')
01388                                 {
01389                                         iPos4++; // positioning after first '"'
01390                                         iPos5 = (int)s3.find_first_of(L"\"", iPos4);
01391                                         if(iPos5 <= 0 || iPos5 >= (int)s3.size())
01392                                         {
01393                                                 SetLastError(FEDM_XML_ERROR_DOC_NOT_WELL_FORMED);
01394                                                 break;
01395                                         }
01396 
01397                                         // add attribute value
01398                                         attrib->sValue = s3.substr(iPos4, iPos5-iPos4);;
01399 
01400                                         // add attribute pair to attribute list
01401                                         item->aAttribList.push_back(attrib);
01402                                         bAttrib = true; // continue with attribute name
01403                                         iPos4 = iPos5 + 1;      // positioning after '"'
01404 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
01405                                         sprintf(buf, "%S=%S", attrib->sAttribute.c_str(), attrib->sValue.c_str());
01406                                         TRACE("new tag attribute: %s\n", buf);
01407                                         ::Sleep(0);
01408 #endif
01409                                 }
01410                                 else
01411                                 {
01412                                         delete attrib;
01413                                         SetLastError(FEDM_XML_ERROR_DOC_NOT_WELL_FORMED);
01414                                         break;
01415                                 }
01416                         }
01417                 } // while(iPos4 < (int)s3.size())
01418 
01419                 if(!item->bEmpty)
01420                 {
01421                         // get next char and check, if it is a LF char
01422                         s3 = m_sXmlStream.at(iPos3 + 1);
01423                         if(s3 == L"\n")
01424                         {
01425                                 item->bNewLine = true;
01426                         }
01427                         else if(s3 != L"<")
01428                         {
01429                                 item->bNewLine = false;
01430                                 if(iPos2 - iPos3 - 1 > 0)
01431                                 {
01432                                         // get tag value
01433                                         item->sValue = m_sXmlStream.substr(iPos3 + 1, iPos2 - iPos3 - 1);
01434 
01435                                         // search for: < > & " ' 
01436                                         int iPos = (int)item->sValue.find(L"&amp;");
01437                                         while(iPos >= 0)
01438                                         {
01439                                                 item->sValue.erase(iPos+1, 4);
01440                                                 iPos = (int)item->sValue.find(L"&amp;", iPos+1);
01441                                         }
01442 
01443                                         iPos = (int)item->sValue.find(L"&lt;");
01444                                         while(iPos >= 0)
01445                                         {
01446                                                 item->sValue.replace(iPos, 1, L"<");
01447                                                 iPos = (int)item->sValue.find(L"&lt;", iPos+1);
01448                                         }
01449 
01450                                         iPos = (int)item->sValue.find(L"&gt;");
01451                                         while(iPos >= 0)
01452                                         {
01453                                                 item->sValue.replace(iPos, 1, L">");
01454                                                 iPos = (int)item->sValue.find(L"&gt;", iPos+1);
01455                                         }
01456 
01457                                         iPos = (int)item->sValue.find(L"&quot;");
01458                                         while(iPos >= 0)
01459                                         {
01460                                                 item->sValue.replace(iPos, 1, L"\"");
01461                                                 iPos = (int)item->sValue.find(L"&quot;", iPos+1);
01462                                         }
01463 
01464                                         iPos = (int)item->sValue.find(L"&apos;");
01465                                         while(iPos >= 0)
01466                                         {
01467                                                 item->sValue.replace(iPos, 1, L"'");
01468                                                 iPos = (int)item->sValue.find(L"&apos;", iPos+1);
01469                                         }
01470                                 }
01471                         }
01472                 }
01473         }
01474         else if(s3 == L">")
01475         {
01476                 // get next char and check, if it is a LF char
01477                 s3 = m_sXmlStream.at(iPos1 + s1.size() + 1);
01478                 if(s3 == L"\n")
01479                 {
01480                         item->bNewLine = true;
01481                 }
01482                 else if(s3 != L"<")
01483                 {
01484                         item->bNewLine = false;
01485                         if(iPos2 - iPos1 - s1.size() - 1 > 0)
01486                         {
01487                                 // get tag value
01488                                 item->sValue = m_sXmlStream.substr(iPos1 + s1.size() + 1, iPos2 - iPos1 - s1.size() - 1);
01489 
01490                                 // search for: < > & " ' 
01491                                 int iPos = (int)item->sValue.find(L"&amp;");
01492                                 while(iPos >= 0)
01493                                 {
01494                                         item->sValue.erase(iPos+1, 4);
01495                                         iPos = (int)item->sValue.find(L"&amp;", iPos+1);
01496                                 }
01497 
01498                                 iPos = (int)item->sValue.find(L"&lt;");
01499                                 while(iPos >= 0)
01500                                 {
01501                                         item->sValue.replace(iPos, 1, L"<");
01502                                         iPos = (int)item->sValue.find(L"&lt;", iPos+1);
01503                                 }
01504 
01505                                 iPos = (int)item->sValue.find(L"&gt;");
01506                                 while(iPos >= 0)
01507                                 {
01508                                         item->sValue.replace(iPos, 1, L">");
01509                                         iPos = (int)item->sValue.find(L"&gt;", iPos+1);
01510                                 }
01511 
01512                                 iPos = (int)item->sValue.find(L"&quot;");
01513                                 while(iPos >= 0)
01514                                 {
01515                                         item->sValue.replace(iPos, 1, L"\"");
01516                                         iPos = (int)item->sValue.find(L"&quot;", iPos+1);
01517                                 }
01518 
01519                                 iPos = (int)item->sValue.find(L"&apos;");
01520                                 while(iPos >= 0)
01521                                 {
01522                                         item->sValue.replace(iPos, 1, L"'");
01523                                         iPos = (int)item->sValue.find(L"&apos;", iPos+1);
01524                                 }
01525                         }
01526                 }
01527         }
01528         else if(s3 == L"/")
01529         {
01530                 // empty tag
01531                 item->bEmpty = true;
01532         }
01533         else
01534         {
01535                 SetLastError(FEDM_XML_ERROR_DOC_NOT_WELL_FORMED);
01536                 DeleteTagItem(item);
01537                 return NULL;
01538         }
01539 
01540         if(bSavePos)
01541         {
01542                 if(iPos1 > 0 && iPos2-iPos1 > 0)
01543                 {
01544                         iPosStart = iPos1;
01545                         iPosEnd   = iPos2;
01546                         iTagLen   = (int)s1.size();
01547                 }
01548         }
01549 
01550         SetLastError(FEDM_OK);
01551         return item;
01552 }
01553 
01554 /***************************************************************************
01555   Begin         :       27.03.2007 / M. Hultsch
01556   Version       :       03.00.00 / 05.07.2007 / M. Hultsch
01557 
01558   Function              :       itentify a tag inside the xml string
01559                                         pick out all attributes and values and create a tree item
01560                                         all position are saved in an array
01561 
01562   Parameters    :       wstring sTag                    - tag string to be identify (in UNICODE)
01563                                         unsigned int uiTagLevel - level of this tag = index in save position
01564                                         bool bNext                              - continue with search behind iPosEnd 
01565 
01566   Return value  :       FEDM_XML_TREEITEM*      - pointer to tree item
01567                                         NULL                            - in error case
01568 ***************************************************************************/
01569 FEDM_XML_TREEITEM* FEDM_XMLBase::FindTag(       wstring sTag,
01570                                                                                         unsigned int uiTagLevel,
01571                                                                                         bool bNext)
01572 {
01573         if(m_sXmlStream.empty())
01574         {
01575                 SetLastError(FEDM_ERROR_NO_DATA);
01576                 return NULL;
01577         }
01578 
01579         if(uiTagLevel >= 15)
01580         {
01581                 SetLastError(FEDM_ERROR_ARRAY_BOUNDARY);
01582                 return NULL;
01583         }
01584 
01585         // static int because of its reuse in the following function call
01586         static int iPosStart[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // position start of tag
01587         static int iPosEnd[]   = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // position end of tag
01588 
01589         bool bRoot = false;
01590         bool bAttrib = true;
01591         int iPos0 = 0;  // position start of empty tag
01592         int iPos1 = 0;  // position start of tag
01593         int iPos2 = 0;  // position end of tag
01594         int iPos3 = 0;  // position inside tag
01595         int iPos4 = 0;  // position inside tag
01596         int iPos5 = 0;  // position inside tag
01597         
01598         unsigned int uiLevel = 0;
01599         unsigned int i = 0;
01600 
01601         int iNextPosStart = 0;
01602         int iNextPos = 0;
01603 
01604         wstring s0, s1, s2, s3, s4;
01605         FEDM_XML_TREEITEM* item = NULL;
01606         FEDM_XML_ATTRIBUTE* attrib = NULL;
01607 
01608         // build search string for empty tag
01609         s0 = L"<";
01610         s0 += sTag;
01611         s0 += L"/>";
01612 
01613         // build search string for beginning tag
01614         s1 = L"<";
01615         s1 += sTag;
01616 
01617         // build search string for end tag
01618         s2 = L"</";
01619         s2 += sTag;
01620         s2 += L">";
01621 
01622         // create item structure
01623         item = new FEDM_XML_TREEITEM;
01624         if(item == NULL)
01625         {
01626                 SetLastError(FEDM_ERROR_NO_MORE_MEM);
01627                 return NULL;
01628         }
01629         item->sTag = sTag;
01630 
01631         if(uiTagLevel == 0)     // root tag
01632         {
01633                 // initializing position marker for new parsing process
01634                 bRoot = true;
01635                 for(i=0; i<15; i++)
01636                 {
01637                         iPosStart[i] = 0;
01638                         iPosEnd[i] = 0;
01639                 }
01640         }
01641 
01642         // set search position behind iPosEnd
01643         if(bNext && !bRoot)
01644         {
01645                 for(i=uiTagLevel; i<15; i++)
01646                 {
01647                         if(iPosStart[i] > 0)
01648                         {
01649                                 iPosStart[i] = iPosEnd[uiTagLevel] + 1;
01650                         }
01651                 }
01652 
01653                 if(iPosStart[uiTagLevel] > iPosEnd[uiTagLevel])
01654                         iPosEnd[uiTagLevel] = iPosEnd[uiTagLevel-1];
01655 
01656                 // for multiple tags with same tagname in same level
01657                 iNextPosStart = iPosStart[uiTagLevel-1] + 1;
01658                 if(iPosStart[uiTagLevel] > iPosStart[uiTagLevel-1])
01659                         iNextPosStart = iPosStart[uiTagLevel];
01660 
01661         }
01662         else
01663         {
01664                 if(uiTagLevel == 0)     // root tag
01665                         iNextPosStart = iPosStart[0];
01666                 else
01667                         iNextPosStart = iPosStart[uiTagLevel-1];
01668         }
01669 
01670         if(uiTagLevel == 0)     // root tag
01671         {
01672                 uiTagLevel++;
01673                 iPosEnd[0] = (int)m_sXmlStream.size();
01674         }
01675 
01676 
01677         // search begin of empty tag inside the previously found tag
01678         iPos0 = (int)m_sXmlStream.find(s0.c_str(), iNextPosStart);
01679         if(iPos0 > 0 && iPos0 > iNextPosStart && iPos0 < iPosEnd[uiTagLevel-1])
01680         {
01681                 item->bEmpty = true;
01682                 iPosEnd[uiTagLevel]       = iPos0;
01683                 SetLastError(FEDM_OK);
01684                 return item;
01685         }
01686 
01687         // search begin of tag inside the previously found tag
01688         iPos1 = (int)m_sXmlStream.find(s1.c_str(), iNextPosStart);
01689 
01690         if(iPos1 < 0 || iPos1 < iNextPosStart || iPos1 > iPosEnd[uiTagLevel-1])
01691         {
01692                 iPosEnd[uiTagLevel] = iPosStart[uiTagLevel]++;
01693                 SetLastError(FEDM_XML_ERROR_TAG_NOT_FOUND);
01694                 DeleteTagItem(item);
01695                 return NULL;
01696         }
01697 
01698         // empty tag with attribute?
01699         iPos2 = (int)m_sXmlStream.find(L"/>", iPos1+1);
01700         if(iPos2 > iPos1)
01701         {
01702                 iPos3 = (int)m_sXmlStream.find(L"<", iPos1+1);
01703                 if(iPos3 > iPos2)
01704                 {
01705                         item->bEmpty = true;
01706                         iPosEnd[uiTagLevel]       = iPos2;
01707 
01708                         // get next char and check, if it is a space char or '>' or '/' char
01709                         s3 = m_sXmlStream.at(iPos1 + s1.size());
01710                         if(s3 == L" ")
01711                         {       
01712                                 // get end position of start tag
01713                                 iPos3 = (int)m_sXmlStream.find_first_of(L">", iPos1);
01714 
01715                                 // extract substring with all attributes
01716                                 s3 = m_sXmlStream.substr(iPos1 + s1.size() + 1, iPos3 - iPos1 - s1.size() - 1);
01717 
01718                                 // tokenize
01719                                 bAttrib = true; // toggles between attributes name and attributes value
01720                                 iPos4 = 0; // set start position
01721                                 while(iPos4 < (int)s3.size())
01722                                 {
01723                                         if(bAttrib)
01724                                         {
01725                                                 iPos5 = (int)s3.find_first_of(L"=", iPos4);
01726                                                 if(iPos5 < 0 || iPos5 >= (int)s3.size())
01727                                                 {
01728                                                         SetLastError(FEDM_XML_ERROR_DOC_NOT_WELL_FORMED);
01729                                                         break;
01730                                                 }
01731 
01732                                                 // create attribute pair
01733                                                 attrib = new FEDM_XML_ATTRIBUTE;
01734                                                 if(attrib == NULL)
01735                                                 {
01736                                                         SetLastError(FEDM_XML_ERROR_DOC_NOT_WELL_FORMED);
01737                                                         break;
01738                                                 }
01739 
01740                                                 // add attribute name
01741                                                 if(s3[iPos4] == L' ')
01742                                                         attrib->sAttribute = s3.substr(iPos4+1, iPos5-iPos4-1);
01743                                                 else
01744                                                         attrib->sAttribute = s3.substr(iPos4, iPos5-iPos4);
01745 
01746                                                 bAttrib = false;        // continue with attribute value
01747                                                 iPos4 = iPos5 + 1;      // positioning after '='
01748                                         }
01749                                         else
01750                                         {
01751                                                 if(s3[iPos4] == L'\"')
01752                                                 {
01753                                                         iPos4++; // positioning after first '"'
01754                                                         iPos5 = (int)s3.find_first_of(L"\"", iPos4);
01755                                                         if(iPos5 <= 0 || iPos5 >= (int)s3.size())
01756                                                         {
01757                                                                 SetLastError(FEDM_XML_ERROR_DOC_NOT_WELL_FORMED);
01758                                                                 break;
01759                                                         }
01760 
01761                                                         // add attribute value
01762                                                         attrib->sValue = s3.substr(iPos4, iPos5-iPos4);;
01763 
01764                                                         // add attribute pair to attribute list
01765                                                         item->aAttribList.push_back(attrib);
01766                                                         bAttrib = true; // continue with attribute name
01767                                                         iPos4 = iPos5 + 1;      // positioning after '"'
01768                                                 }
01769                                                 else
01770                                                 {
01771                                                         delete attrib;
01772                                                         SetLastError(FEDM_XML_ERROR_DOC_NOT_WELL_FORMED);
01773                                                         break;
01774                                                 }
01775                                         }
01776                                 } // while(iPos4 < (int)s3.size())
01777                         }
01778 
01779                         SetLastError(FEDM_OK);
01780                         return item;
01781                 }
01782         }
01783 
01784         // search first occurrence of end of tag
01785         iPos2 = (int)m_sXmlStream.find(s2.c_str(), iPos1);
01786 
01787         if(iPos2 > 0)
01788         {
01789                 // if tag has inner tags
01790                 s3 = L"<";
01791                 iPos3 = (int)m_sXmlStream.find(s3.c_str(), iPos1 + 1);
01792                 if(iPos3 > 0 && iPos3 < iPos2)
01793                 {
01794                         // verify, if this end tag is in the same tag level as the start tag
01795                         // if inner tags with same tag name found, recalc iPos2
01796                         iNextPos = iPos1 + (int)s1.size() + 1; // behind start of tag
01797                         uiLevel = uiTagLevel;
01798                         while(iPos2 > 0 && iPos2 < iPosEnd[0])
01799                         {
01800                                 // empty tag inside ?
01801                                 iPos3 = (int)m_sXmlStream.find(s0.c_str(), iNextPos);
01802                                 if(iPos3 > 0 && iPos3 < iPos2)//iPosEnd[uiTagLevel-1])
01803                                         iNextPos = iPos3 + (int)s0.size();
01804 
01805                                 // begin of tag inside ?
01806                                 iPos3 = (int)m_sXmlStream.find(s1.c_str(), iNextPos);
01807                                 if(iPos3 > 0 && iPos3 < iPos2)
01808                                 {
01809                                         // check, if next char is a " " or "/" or ">"
01810                                         s3 = m_sXmlStream.at(iPos3 + s1.size());
01811                                         if(s3 != L" " && s3 != L"/" && s3 != L">")
01812                                         {
01813                                                 if(uiLevel == uiTagLevel)
01814                                                         break;
01815                                         }
01816 
01817                                         // inner start tag with same tag name found
01818                                         uiLevel++; // increment tag level
01819                                         iNextPos = iPos3 + (int)s1.size();
01820                                 }
01821                                 else
01822                                 {
01823                                         if(uiLevel == uiTagLevel)
01824                                                 break;
01825                                 }
01826 
01827                                 // skip to next end of tag
01828                                 iPos2 = (int)m_sXmlStream.find(s2.c_str(), iPos2 + s2.size());
01829                                 if(iPos2 > 0 && iPos2 < iPosEnd[uiTagLevel-1])
01830                                 {
01831                                         // inner end tag with same tag name found
01832                                         uiLevel--;
01833                                 }
01834                                 else
01835                                 {
01836                                         if(uiLevel == uiTagLevel)
01837                                                 break;
01838                                 }
01839                         
01840                         } // while(iPos2 > 0 && iPos2 < iPosEnd[0])
01841 
01842                 } // if(iPos3 > 0)
01843 
01844         } // if(iPos2 > 0)
01845 
01846         if(iPos2 < 0 || iPos2 < iNextPosStart || iPos2 > iPosEnd[uiTagLevel-1])
01847         {       // empty tag?
01848         
01849                 // build search string for empty end tag..
01850                 s2 = L"/>";
01851                 // ..and try again
01852                 iPos2 = (int)m_sXmlStream.find(s2.c_str(), iPos1);
01853                 
01854                 if(iPos2 < 0 || iPos2 < iNextPosStart || iPos2 > iPosEnd[uiTagLevel-1])
01855                 {
01856                         iPosEnd[uiTagLevel] = iPosStart[uiTagLevel] + 1;
01857                         SetLastError(FEDM_XML_ERROR_TAG_NOT_FOUND);
01858                         DeleteTagItem(item);
01859                         return NULL;
01860                 }
01861 
01862                 // is there any '<' char inside?
01863                 iPos3 = (int)m_sXmlStream.find(L"<", iPos1, iPos2-iPos1);
01864                 if(iPos3 > 0 && (iPos3 < iPos1 || iPos3 > iPos2))
01865                 {
01866                         SetLastError(FEDM_XML_ERROR_DOC_NOT_WELL_FORMED);
01867                         DeleteTagItem(item);
01868                         return NULL;
01869                 }
01870 
01871                 item->bEmpty = true;
01872 
01873                 // if no attributes, we can return
01874                 if(iPos2 - iPos1 - s1.size() == 0)
01875                 {
01876                         iPosEnd[uiTagLevel]       = iPos2;
01877                         SetLastError(FEDM_OK);
01878                         return item;
01879                 }
01880         }
01881         else
01882         {
01883                 item->bEmpty = false;
01884         }
01885 
01886         // get next char and check, if it is a space char or '>' or '/' char
01887         s3 = m_sXmlStream.at(iPos1 + s1.size());
01888         if(s3 == L" ")
01889         {       
01890                 // get end position of start tag
01891                 iPos3 = (int)m_sXmlStream.find_first_of(L">", iPos1);
01892 
01893                 // extract substring with all attributes
01894                 s3 = m_sXmlStream.substr(iPos1 + s1.size() + 1, iPos3 - iPos1 - s1.size() - 1);
01895 
01896                 // tokenize
01897                 bAttrib = true; // toggles between attributes name and attributes value
01898                 iPos4 = 0; // set start position
01899                 while(iPos4 < (int)s3.size())
01900                 {
01901                         if(bAttrib)
01902                         {
01903                                 iPos5 = (int)s3.find_first_of(L"=", iPos4);
01904                                 if(iPos5 < 0 || iPos5 >= (int)s3.size())
01905                                 {
01906                                         SetLastError(FEDM_XML_ERROR_DOC_NOT_WELL_FORMED);
01907                                         break;
01908                                 }
01909 
01910                                 // create attribute pair
01911                                 attrib = new FEDM_XML_ATTRIBUTE;
01912                                 if(attrib == NULL)
01913                                 {
01914                                         SetLastError(FEDM_ERROR_NO_MORE_MEM);
01915                                         break;
01916                                 }
01917 
01918                                 // add attribute name
01919                                 if(s3[iPos4] == L' ')
01920                                         attrib->sAttribute = s3.substr(iPos4+1, iPos5-iPos4-1);
01921                                 else
01922                                         attrib->sAttribute = s3.substr(iPos4, iPos5-iPos4);
01923 
01924                                 bAttrib = false;        // continue with attribute value
01925                                 iPos4 = iPos5 + 1;      // positioning after '='
01926                         }
01927                         else
01928                         {
01929                                 if(s3[iPos4] == L'\"')
01930                                 {
01931                                         iPos4++; // positioning after first '"'
01932                                         iPos5 = (int)s3.find_first_of(L"\"", iPos4);
01933                                         if(iPos5 <= 0 || iPos5 >= (int)s3.size())
01934                                         {
01935                                                 SetLastError(FEDM_XML_ERROR_DOC_NOT_WELL_FORMED);
01936                                                 break;
01937                                         }
01938 
01939                                         // add attribute value
01940                                         attrib->sValue = s3.substr(iPos4, iPos5-iPos4);;
01941 
01942                                         // add attribute pair to attribute list
01943                                         item->aAttribList.push_back(attrib);
01944                                         bAttrib = true; // continue with attribute name
01945                                         iPos4 = iPos5 + 1;      // positioning after '"'
01946                                 }
01947                                 else
01948                                 {
01949                                         delete attrib;
01950                                         SetLastError(FEDM_XML_ERROR_DOC_NOT_WELL_FORMED);
01951                                         break;
01952                                 }
01953                         }
01954                 } // while(iPos4 < (int)s3.size())
01955 
01956                 if(!item->bEmpty)
01957                 {
01958                         // get next char and check, if it is a LF char
01959                         s3 = m_sXmlStream.at(iPos3 + 1);
01960                         if(s3 == L"\n")
01961                         {
01962                                 item->bNewLine = true;
01963                         }
01964                         else if(s3 != L"<")
01965                         {
01966                                 item->bNewLine = false;
01967                                 if(iPos2 - iPos3 - 1 > 0)
01968                                 {
01969                                         // get tag value
01970                                         item->sValue = m_sXmlStream.substr(iPos3 + 1, iPos2 - iPos3 - 1);
01971 
01972                                         // search for: < > & " ' 
01973                                         int iPos = (int)item->sValue.find(L"&amp;");
01974                                         while(iPos >= 0)
01975                                         {
01976                                                 item->sValue.erase(iPos+1, 4);
01977                                                 iPos = (int)item->sValue.find(L"&amp;", iPos+1);
01978                                         }
01979 
01980                                         iPos = (int)item->sValue.find(L"&lt;");
01981                                         while(iPos >= 0)
01982                                         {
01983                                                 item->sValue.replace(iPos, 1, L"<");
01984                                                 iPos = (int)item->sValue.find(L"&lt;", iPos+1);
01985                                         }
01986 
01987                                         iPos = (int)item->sValue.find(L"&gt;");
01988                                         while(iPos >= 0)
01989                                         {
01990                                                 item->sValue.replace(iPos, 1, L">");
01991                                                 iPos = (int)item->sValue.find(L"&gt;", iPos+1);
01992                                         }
01993 
01994                                         iPos = (int)item->sValue.find(L"&quot;");
01995                                         while(iPos >= 0)
01996                                         {
01997                                                 item->sValue.replace(iPos, 1, L"\"");
01998                                                 iPos = (int)item->sValue.find(L"&quot;", iPos+1);
01999                                         }
02000 
02001                                         iPos = (int)item->sValue.find(L"&apos;");
02002                                         while(iPos >= 0)
02003                                         {
02004                                                 item->sValue.replace(iPos, 1, L"'");
02005                                                 iPos = (int)item->sValue.find(L"&apos;", iPos+1);
02006                                         }
02007                                 }
02008                         }
02009                 }
02010         }
02011         else if(s3 == L">")
02012         {
02013                 // get next char and check, if it is a LF char
02014                 s3 = m_sXmlStream.at(iPos1 + s1.size() + 1);
02015                 if(s3 == L"\n")
02016                 {
02017                         item->bNewLine = true;
02018                 }
02019                 else if(s3 != L"<")
02020                 {
02021                         item->bNewLine = false;
02022                         if(iPos2 - iPos1 - s1.size() - 1 > 0)
02023                         {
02024                                 // get tag value
02025                                 item->sValue = m_sXmlStream.substr(iPos1 + s1.size() + 1, iPos2 - iPos1 - s1.size() - 1);
02026 
02027                                 // search for: < > & " ' 
02028                                 int iPos = (int)item->sValue.find(L"&amp;");
02029                                 while(iPos >= 0)
02030                                 {
02031                                         item->sValue.erase(iPos+1, 4);
02032                                         iPos = (int)item->sValue.find(L"&amp;", iPos+1);
02033                                 }
02034 
02035                                 iPos = (int)item->sValue.find(L"&lt;");
02036                                 while(iPos >= 0)
02037                                 {
02038                                         item->sValue.replace(iPos, 1, L"<");
02039                                         iPos = (int)item->sValue.find(L"&lt;", iPos+1);
02040                                 }
02041 
02042                                 iPos = (int)item->sValue.find(L"&gt;");
02043                                 while(iPos >= 0)
02044                                 {
02045                                         item->sValue.replace(iPos, 1, L">");
02046                                         iPos = (int)item->sValue.find(L"&gt;", iPos+1);
02047                                 }
02048 
02049                                 iPos = (int)item->sValue.find(L"&quot;");
02050                                 while(iPos >= 0)
02051                                 {
02052                                         item->sValue.replace(iPos, 1, L"\"");
02053                                         iPos = (int)item->sValue.find(L"&quot;", iPos+1);
02054                                 }
02055 
02056                                 iPos = (int)item->sValue.find(L"&apos;");
02057                                 while(iPos >= 0)
02058                                 {
02059                                         item->sValue.replace(iPos, 1, L"'");
02060                                         iPos = (int)item->sValue.find(L"&apos;", iPos+1);
02061                                 }
02062                         }
02063                 }
02064         }
02065         else if(s3 == L"/")
02066         {
02067                 // empty tag
02068                 item->bEmpty = true;
02069         }
02070         else
02071         {
02072                 SetLastError(FEDM_XML_ERROR_DOC_NOT_WELL_FORMED);
02073                 DeleteTagItem(item);
02074                 return NULL;
02075         }
02076 
02077         if(iPos1 > 0 && iPos2-iPos1 > 0)
02078         {
02079                 if(bRoot)
02080                 {
02081                         iPosStart[0]= iPos1;
02082                         iPosEnd[0]      = iPos2;
02083                 }
02084                 else
02085                 {
02086                         iPosStart[uiTagLevel] = iPos1;
02087                         iPosEnd[uiTagLevel]       = iPos2;
02088                 }
02089         }
02090 
02091         SetLastError(FEDM_OK);
02092         return item;
02093 }
02094 
02095 
02096 /***************************************************************************
02097   Begin         :       17.04.2003 / M. Hultsch
02098   Version       :       01.08.00 / 24.04.2003 / M. Hultsch
02099 
02100   Function              :       itentify a tag inside the xml string
02101                                         pick out all attributes and values and create a tree item
02102                                         return item only if additional attribute specs are valid
02103 
02104   Parameters    :       wstring sTag                    - tag string to be identify (in UNICODE)
02105                                         wstring sAttribName             - tag attribute name
02106                                         bool bInside                    - find the tag inside the positions iPos1 
02107                                                                                           and iPos2 of last function call.
02108                                                                                           This allows the search of child tags 
02109                                                                                           inside a previously found parent tag
02110                                         bool bSavePos                   - save the tag positions iPos1 and iPos2
02111                                                                                         
02112   Return value  :       FEDM_XML_TREEITEM*              - pointer to tree item
02113                                         NULL                                    - in error case
02114 ***************************************************************************/
02115 FEDM_XML_TREEITEM* FEDM_XMLBase::FindTag(wstring sTag, 
02116                                                                                  wstring sAttribName, 
02117                                                                                  bool bInside, 
02118                                                                                  bool bSavePos)
02119 {
02120         bool bNext = false;
02121 
02122         while(true)
02123         {
02124                 FEDM_XML_TREEITEM* item = FindTag(sTag, bInside, bSavePos, bNext);
02125 
02126                 if(item == NULL)
02127                 {
02128                         SetLastError(FEDM_XML_ERROR_NO_TAG_ATTRIBUTE);
02129                         return NULL;
02130                 }
02131 
02132                 for(int i=0; i<(int)item->aAttribList.size(); ++i)
02133                 {
02134                         if(item->aAttribList[i]->sAttribute == sAttribName)
02135                         {
02136                                 SetLastError(FEDM_OK);
02137                                 return item;
02138                         }
02139                 }
02140 
02141                 DeleteTagItem(item);
02142 
02143                 bNext = true;
02144         }
02145 
02146         SetLastError(FEDM_XML_ERROR_NO_TAG_ATTRIBUTE);
02147         return NULL;
02148 }
02149 
02150 
02151 /***************************************************************************
02152   Begin         :       28.03.2007 / M. Hultsch
02153   Version       :       02.05.08 / 28.03.2007 / M. Hultsch
02154 
02155   Function              :       itentify a tag inside the xml string
02156                                         pick out all attributes and values and create a tree item
02157                                         return item only if additional attribute specs are valid
02158 
02159   Parameters    :       wstring sTag                    - tag string to be identify (in UNICODE)
02160                                         wstring sAttribName             - tag attribute name
02161                                         unsigned int uiTagLevel - level of this tag = index in save position
02162                                         bool bNext                              - continue with search behind iPosEnd 
02163                                                                                         
02164   Return value  :       FEDM_XML_TREEITEM*              - pointer to tree item
02165                                         NULL                                    - in error case
02166 ***************************************************************************/
02167 FEDM_XML_TREEITEM* FEDM_XMLBase::FindTag(       wstring sTag, 
02168                                                                                         wstring sAttribName, 
02169                                                                                         unsigned int uiTagLevel,
02170                                                                                         bool bNext)
02171 {
02172         while(true)
02173         {
02174                 FEDM_XML_TREEITEM* item = FindTag(sTag, uiTagLevel, bNext);
02175 
02176                 if(item == NULL)
02177                 {
02178                         SetLastError(FEDM_XML_ERROR_NO_TAG_ATTRIBUTE);
02179                         return NULL;
02180                 }
02181 
02182                 for(int i=0; i<(int)item->aAttribList.size(); ++i)
02183                 {
02184                         if(item->aAttribList[i]->sAttribute == sAttribName)
02185                         {
02186                                 SetLastError(FEDM_OK);
02187                                 return item;
02188                         }
02189                 }
02190 
02191                 DeleteTagItem(item);
02192 
02193                 bNext = true;
02194         }
02195 
02196         SetLastError(FEDM_XML_ERROR_NO_TAG_ATTRIBUTE);
02197         return NULL;
02198 }
02199 
02200 
02201 /***************************************************************************
02202   Begin         :       17.04.2003 / M. Hultsch
02203   Version       :       01.08.00 / 24.04.2003 / M. Hultsch
02204 
02205   Function              :       itentify a tag inside the xml string
02206                                         pick out all attributes and values and create a tree item
02207                                         return item only if additional attribute specs are valid
02208 
02209   Parameters    :       wstring sTag                    - tag string to be identify (in UNICODE)
02210                                         wstring sAttribName             - tag attribute name
02211                                         wstring sAttribValue    - tag attribute value
02212                                         bool bInside=false              - find the tag inside the positions iPos1 
02213                                                                                           and iPos2 of last function call.
02214                                                                                           This allows the search of child tags 
02215                                                                                           inside a previously found parent tag
02216                                         bool bSavePos                   - save the tag positions iPos1 and iPos2
02217 
02218   Return value  :       FEDM_XML_TREEITEM*              - pointer to tree item
02219                                         NULL                                    - in error case
02220 ***************************************************************************/
02221 FEDM_XML_TREEITEM* FEDM_XMLBase::FindTag(wstring sTag, 
02222                                                                                  wstring sAttribName, 
02223                                                                                  wstring sAttribValue, 
02224                                                                                  bool bInside, 
02225                                                                                  bool bSavePos)
02226 {
02227         bool bNext = false;
02228 
02229         while(true)
02230         {
02231                 FEDM_XML_TREEITEM* item = FindTag(sTag, bInside, bSavePos, bNext);
02232 
02233                 if(item == NULL)
02234                 {
02235                         SetLastError(FEDM_XML_ERROR_NO_TAG_ATTRIBUTE);
02236                         return NULL;
02237                 }
02238 
02239                 for(int i=0; i<(int)item->aAttribList.size(); ++i)
02240                 {
02241                         if( item->aAttribList[i]->sAttribute == sAttribName &&
02242                                 item->aAttribList[i]->sValue == sAttribValue)
02243                         {
02244                                 SetLastError(FEDM_OK);
02245                                 return item;
02246                         }
02247                 }
02248 
02249                 DeleteTagItem(item);
02250 
02251                 bNext = true;
02252         }
02253         
02254         SetLastError(FEDM_XML_ERROR_NO_TAG_ATTRIBUTE);
02255         return NULL;
02256 }
02257 
02258 
02259 
02260 //#####################################################################################
02261 // functions for query content from xml tree
02262 //#####################################################################################
02263 
02264 /***************************************************************************
02265   Begin         :       11.04.2003 / M. Hultsch
02266   Version       :       01.08.00 / 11.04.2003 / M. Hultsch
02267 
02268   Function              :       query the root tag
02269 
02270   Parameters    :       -
02271 
02272   Return value  :       FEDM_XML_TREEITEM*      - pointer to tree item
02273                                         NULL                            - in error case
02274 ***************************************************************************/
02275 /*FEDM_XML_TREEITEM* FEDM_XMLBase::GetRootTag()
02276 {
02277         if(m_XmlTree.size() == 0)
02278         {
02279                 SetLastError(FEDM_XML_ERROR_NO_OBID_TAG);
02280                 return NULL;
02281         }
02282 
02283         return m_XmlTree[0];
02284 }*/
02285 
02286 /***************************************************************************
02287   Begin         :       11.04.2003 / M. Hultsch
02288   Version       :       01.08.00 / 11.04.2003 / M. Hultsch
02289 
02290   Function              :       query a child tag
02291 
02292   Parameters    :       int iIndex      - item index in tag child list
02293 
02294   Return value  :       FEDM_XML_TREEITEM*      - pointer to tree item
02295                                         NULL                            - in error case
02296 ***************************************************************************/
02297 /*FEDM_XML_TREEITEM* FEDM_XMLBase::GetChildTag(int iIndex)
02298 {
02299         if(m_XmlTree.size() == 0)
02300         {
02301                 SetLastError(FEDM_XML_ERROR_NO_OBID_TAG);
02302                 return NULL;
02303         }
02304 
02305         if(m_XmlTree[0]->aChildList.size() <= iIndex)
02306         {
02307                 SetLastError(FEDM_XML_ERROR_NO_CHILD_TAG);
02308                 return NULL;
02309         }
02310 
02311         return m_XmlTree[0]->aChildList[iIndex];
02312 }*/
02313 
02314 /***************************************************************************
02315   Begin         :       11.04.2003 / M. Hultsch
02316   Version       :       01.08.00 / 11.04.2003 / M. Hultsch
02317 
02318   Function              :       query of the number of childs
02319 
02320   Parameters    :       FEDM_XML_TREEITEM*      - pointer to tree item
02321 
02322   Return value  :       int     -       number of childs (>=0) or error code (<0)
02323 ***************************************************************************/
02324 /*int FEDM_XMLBase::GetTagChildCount(FEDM_XML_TREEITEM* item)
02325 {
02326         FEDM_CHK5(item);
02327         
02328         return item->aChildList.size();
02329 }*/
02330 
02331 /***************************************************************************
02332   Begin         :       11.04.2003 / M. Hultsch
02333   Version       :       01.08.00 / 04.09.2003 / M. Hultsch
02334 
02335   Function              :       query of tag value
02336 
02337   Parameters    :       FEDM_XML_TREEITEM*      - pointer to tree item
02338                                         string& sValue          - reference to string
02339 
02340   Return value  :       FEDM_OK or error code (<0)
02341 ***************************************************************************/
02342 int FEDM_XMLBase::GetTagValue(FEDM_XML_TREEITEM* item, string& sValue)
02343 {
02344         FEDM_CHK5(item);
02345 
02346         if(item->sValue.empty())
02347                 FEDM_RETURN(FEDM_XML_ERROR_NO_TAG_VALUE);
02348 
02349         char cBuffer[256];
02350 
02351         // convert UNICODE to char
02352         if(item->sValue.size() > 256)
02353                 FEDM_RETURN(FEDM_ERROR_STRING_LENGTH);
02354 
02355 #if defined(__BORLANDC__) || defined(_MSC_VER)
02356         sprintf(cBuffer, "%S", item->sValue.c_str());
02357 #else
02358         sprintf(cBuffer, "%S", /*(const char*)*/item->sValue.c_str());
02359 #endif
02360         sValue = cBuffer;
02361 
02362         FEDM_RETURN(FEDM_OK);
02363 }
02364 
02365 /***************************************************************************
02366   Begin         :       11.04.2003 / M. Hultsch
02367   Version       :       01.08.00 / 11.04.2003 / M. Hultsch
02368 
02369   Function              :       query of the number of attributes
02370 
02371   Parameters    :       FEDM_XML_TREEITEM*      - pointer to tree item
02372 
02373   Return value  :       int     -       number of attributes (>=0) or error code (<0)
02374 ***************************************************************************/
02375 int FEDM_XMLBase::GetTagAttribCount(FEDM_XML_TREEITEM* item)
02376 {
02377         FEDM_CHK5(item);
02378         
02379         return (int)item->aAttribList.size();
02380 }
02381 
02382 /***************************************************************************
02383   Begin         :       22.04.2003 / M. Hultsch
02384   Version       :       01.08.00 / 22.04.2003 / M. Hultsch
02385 
02386   Function              :       query at index one attribute (name and value) from tags attribute list
02387 
02388   Parameters    :       FEDM_XML_TREEITEM* item - pointer to tree item
02389                                         int iIndex                              - index in attribute list
02390                                         wstring& sAttrib                - attribute name
02391                                         wstring& sValue                 - attribute value
02392 
02393   Return value  :       
02394 ***************************************************************************/
02395 int FEDM_XMLBase::GetTagAttrib(FEDM_XML_TREEITEM* item, int iIndex, wstring& wsAttrib, wstring& wsValue)
02396 {
02397         FEDM_CHK5(item);
02398         
02399         if((int)item->aAttribList.size() <= iIndex)
02400                 FEDM_RETURN(FEDM_XML_ERROR_NO_TAG_ATTRIBUTE);
02401 
02402         wsAttrib = item->aAttribList[iIndex]->sAttribute;
02403         wsValue = item->aAttribList[iIndex]->sValue;
02404 
02405         FEDM_RETURN(FEDM_OK);
02406 }
02407 
02408 /***************************************************************************
02409   Begin         :       11.04.2003 / M. Hultsch
02410   Version       :       01.08.00 / 04.09.2003 / M. Hultsch
02411 
02412   Function              :       query at index one attribute (name and value) from tags attribute list
02413 
02414   Parameters    :       FEDM_XML_TREEITEM* item - pointer to tree item
02415                                         int iIndex                              - index in attribute list
02416                                         string sAttrib                  - attribute name
02417                                         string& sValue                  - attribute value
02418 
02419   Return value  :       
02420 ***************************************************************************/
02421 int FEDM_XMLBase::GetTagAttrib(FEDM_XML_TREEITEM* item, int iIndex, string& sAttrib, string& sValue)
02422 {
02423         FEDM_CHK5(item);
02424         
02425         if((int)item->aAttribList.size() <= iIndex)
02426                 FEDM_RETURN(FEDM_XML_ERROR_NO_TAG_ATTRIBUTE);
02427 
02428         char cBuffer[256];
02429 
02430         // attribute name: convert UNICODE to char
02431         if(item->aAttribList[iIndex]->sAttribute.size() > 256)
02432                 FEDM_RETURN(FEDM_ERROR_STRING_LENGTH);
02433 
02434         // attribute value: convert UNICODE to char
02435         if(item->aAttribList[iIndex]->sValue.size() > 256)
02436                 FEDM_RETURN(FEDM_ERROR_STRING_LENGTH);
02437 
02438 #if defined(__BORLANDC__) || defined(_MSC_VER)
02439         sprintf(cBuffer, "%S", item->aAttribList[iIndex]->sAttribute.c_str());
02440 #else
02441         sprintf(cBuffer, "%S", /*(const char*)*/item->aAttribList[iIndex]->sAttribute.c_str());
02442 #endif
02443         sAttrib = cBuffer;
02444 
02445 #if defined(__BORLANDC__) || defined(_MSC_VER)
02446         sprintf(cBuffer, "%S", item->aAttribList[iIndex]->sValue.c_str());
02447 #else
02448         sprintf(cBuffer, "%S", /*(const char*)*/item->aAttribList[iIndex]->sValue.c_str());
02449 #endif
02450         sValue = cBuffer;
02451 
02452         FEDM_RETURN(FEDM_OK);
02453 }
02454 
02455 
02456 /***************************************************************************
02457   Begin         :       14.04.2003 / M. Hultsch
02458   Version       :       01.08.00 / 04.09.2003 / M. Hultsch
02459 
02460   Function              :       extracts the xml file header
02461 
02462   Parameters    :       char* cBuffer   - pointer to string with xml header
02463 
02464   Return value  :       FEDM_OK or error code (<0)
02465 ***************************************************************************/
02466 int FEDM_XMLBase::ReadXmlHeader(char* cBuffer)
02467 {
02468         bool bVersion = false;
02469         bool bEncoding = false;
02470         bool bStandalone = false;
02471         char* cToken;
02472         wchar_t wcBuffer[101];
02473 
02474         // extract xml version
02475         cToken = strtok(cBuffer, "<? =\">");
02476         while(cToken)
02477         {
02478                 if(strcmp(cToken, "version")==0)
02479                 {
02480                         bVersion = true;
02481                         cToken = strtok(NULL, "<? =\">");
02482                         continue;
02483                 }
02484 
02485                 if(strcmp(cToken, "encoding")==0)
02486                 {
02487                         bEncoding = true;
02488                         cToken = strtok(NULL, "<? =\">");
02489                         continue;
02490                 }
02491 
02492                 if(strcmp(cToken, "standalone")==0)
02493                 {
02494                         bStandalone = true;
02495                         cToken = strtok(NULL, "<? =\">");
02496                         continue;
02497                 }
02498 
02499                 if(bVersion)
02500                 {
02501                         if(strlen(cBuffer) <= 100)
02502                         {
02503 #if defined(__BORLANDC__) || defined(_MSC_VER)
02504                                 swprintf(wcBuffer, L"%S", cToken);
02505 #else
02506                                 swprintf(wcBuffer, 101, L"%s", cToken);
02507 #endif
02508                                 m_wsXmlVer = wcBuffer;
02509                         }
02510 
02511                         bVersion = false;
02512                 }
02513 
02514                 if(bEncoding)
02515                 {
02516                         if(strlen(cBuffer) <= 100)
02517                         {
02518 #if defined(__BORLANDC__) || defined(_MSC_VER)
02519                                 swprintf(wcBuffer, L"%S", cToken);
02520 #else
02521                                 swprintf(wcBuffer, 101, L"%s", cToken);
02522 #endif
02523                                 m_wsEncoding = wcBuffer;
02524                         }
02525 
02526                         bEncoding = false;
02527                 }
02528 
02529                 if(bStandalone)
02530                 {
02531                         if(strlen(cBuffer) <= 100)
02532                         {
02533 #if defined(__BORLANDC__) || defined(_MSC_VER)
02534                                 swprintf(wcBuffer, L"%S", cToken);
02535 #else
02536                                 swprintf(wcBuffer, 101, L"%s", cToken);
02537 #endif
02538                                 m_wsStandalone = wcBuffer;
02539                         }
02540 
02541                         bStandalone = false;
02542                 }
02543 
02544                 cToken = strtok(NULL, "<? =\">");
02545         }
02546 
02547         if( m_wsXmlVer.size() == 0 ||
02548                 m_wsEncoding.size() == 0 ||
02549                 m_wsStandalone.size() == 0 )
02550         {
02551                 FEDM_RETURN(FEDM_XML_ERROR_NO_XML_FILE);
02552         }
02553 
02554         FEDM_RETURN(FEDM_OK);
02555 }
02556 
02557 void FEDM_XMLBase::SetLastError(int iError)
02558 { 
02559         m_iLastError = iError;
02560 #if defined(_MSC_VER) && defined(_FEDM_TRACE) && defined(_DEBUG)
02561         if(iError != 0)
02562                 TRACE("Error in FEDM_XMLBase: %d\n", iError);
02563 #endif
02564 }
02565 
02566 int FEDM_XMLBase::GetLastError()
02567 {
02568         return m_iLastError;
02569 }
02570 
02571 /*void FEDM_XMLBase::SetComment(wstring sComment)
02572 {
02573         m_sXmlComment = sComment;
02574 }*/
02575 
02576 #endif // #ifdef _FEDM_XML_SUPPORT


rfid_drivers
Author(s): Raul Perula-Martinez
autogenerated on Thu Apr 2 2015 03:06:13