Advertisement
Guest User

xmlreader.c

a guest
Oct 4th, 2010
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 13.19 KB | None | 0 0
  1. /*
  2.  *******************************************************************************
  3.  * xmlreader.c
  4.  * Creation date: 01.11.2007
  5.  * Author:        Firoball
  6.  *
  7.  *******************************************************************************
  8.  * $Date: 2010-08-05 00:23:10 +0200 (Do, 05 Aug 2010) $
  9.  * $Revision: 4 $
  10.  * $Author: Firo $
  11.  *
  12.  *******************************************************************************
  13.  * Description
  14.  *
  15.  * Script for XML parser
  16.  *
  17.  * Comments
  18.  *
  19.  * for short descriptions see comments in xmlreader.h
  20.  *
  21.  *******************************************************************************
  22.  */
  23.  
  24. /* ----- INCLUDES ----- */
  25.  
  26.  
  27. #include <acknex.h>
  28.  
  29.  
  30. /* ----- EXTERNAL FUNCTIONS ----- */
  31.  
  32.  
  33. /* ----- XMLFILE ----- */
  34. XMLFILE* XMLFILE_create(char* pcFile)
  35. {
  36.     XMLFILE* psHost;
  37.     psHost = (XMLFILE*)malloc(sizeof(XMLFILE));
  38.     psHost->vFName = str_create(pcFile);
  39.     psHost->vFHndl = NULL;
  40.     psHost->psAnchor = NULL;
  41.        
  42.     return (psHost);
  43. }
  44.  
  45. void XMLFILE_remove(XMLFILE* psHost)
  46. {
  47.     int i;
  48.  
  49.     /* remove all allocated instances */
  50.     str_remove(psHost->vFName);
  51.     if (psHost->psAnchor != NULL)
  52.     {
  53.         XMLPAR_remove(psHost->psAnchor);   
  54.     }
  55.     free (psHost);
  56. }
  57.  
  58. XMLPAR* XMLFILE_parse(XMLFILE* psHost)
  59. {
  60.     psHost->vFHndl = file_open_game(psHost->vFName);
  61.     /* only read file if filename is valid and psAnchor is not yet allocated */
  62.     if ((psHost->vFHndl != NULL) && (psHost->psAnchor == NULL))
  63.     {
  64.         /* create psAnchor XMLPAR */
  65.         psHost->psAnchor = XMLPAR_create();
  66.         psHost->psAnchor->strTag = str_create("XML_root");
  67.         psHost->iTmp = XMLFILE__findNext(psHost);
  68.         do
  69.         {
  70.             psHost->iTmp = XMLFILE__read(psHost, psHost->psAnchor, psHost->iTmp);
  71.         }while (psHost->iTmp == XML_OPENTAG);
  72.  
  73.         file_close(psHost->vFHndl);
  74.         psHost->vFHndl = NULL;     
  75.     }
  76.     return (psHost->psAnchor);
  77. }
  78.  
  79.  
  80. /* ----- XMLPAR ----- */
  81. XMLPAR* XMLPAR_create()
  82. {
  83.     XMLPAR* psHost;
  84.     psHost = (XMLPAR*)malloc(sizeof(XMLPAR));
  85.     psHost->psTagList = NULL;
  86.     psHost->psAttribList = NULL;
  87.     psHost->strTag = NULL;
  88.     psHost->strContent = NULL;
  89.     psHost->psParent = NULL;
  90.    
  91.     return (psHost);
  92. }
  93.  
  94. void XMLPAR_remove(XMLPAR* psHost)
  95. {
  96.     int i;
  97.     str_remove(psHost->strTag);
  98.     /* single par - remove content */
  99.     if (psHost->strContent != NULL)
  100.         str_remove(psHost->strContent);
  101.  
  102.     /* remove all XMLPARs on list */
  103.     if (psHost->psTagList != NULL)
  104.     {
  105.         for (i = 0; i < LIST_items(psHost->psTagList); i++)
  106.             XMLPAR_remove((XMLPAR*)LIST_getItem(psHost->psTagList, i));
  107.         LIST_remove(psHost->psTagList);
  108.     }
  109.    
  110.     /* remove Attribute list */
  111.     if (psHost->psAttribList !=NULL)
  112.     {
  113.         for (i = 0; i < LIST_items(psHost->psAttribList); i++)
  114.             XMLATTRIB_remove((XMLATTRIB*)LIST_getItem(psHost->psAttribList, i));
  115.         LIST_remove(psHost->psAttribList); 
  116.     }
  117.  
  118.     free(psHost);
  119. }
  120.  
  121. void XMLPAR_getContent(XMLPAR* psHost, STRING* strTarget)
  122. {
  123.     if (psHost->strContent == NULL)
  124.         str_cpy(strTarget, "");
  125.     else
  126.         str_cpy(strTarget, psHost->strContent);
  127. }
  128.  
  129. void XMLPAR_getTag(XMLPAR* psHost, STRING* strTarget)
  130. {
  131.     if (psHost->strTag == NULL)
  132.         str_cpy(strTarget, "");
  133.     else
  134.         str_cpy(strTarget, psHost->strTag);
  135. }
  136.  
  137. STRING* XMLPAR_getPContent(XMLPAR* psHost)
  138. {
  139.     if (psHost->strContent != NULL)
  140.         return (psHost->strContent);
  141.     else
  142.         return (NULL);
  143. }
  144.  
  145. STRING* XMLPAR_getPTag(XMLPAR* psHost)
  146. {
  147.     if (psHost->strTag != NULL)
  148.         return (psHost->strTag);
  149.     else
  150.         return (NULL);
  151. }
  152.  
  153. XMLPAR* XMLPAR_getElementByTag(XMLPAR* psHost, STRING* strTag)
  154. {
  155.     int i;
  156.     XMLPAR* pXml;
  157.    
  158.     pXml = NULL;
  159.    
  160.     if (psHost->strTag != NULL)
  161.     {
  162.         /* at least one sub parameter found */
  163.         if ((psHost->psTagList != NULL) && (psHost->strContent == NULL))
  164.         {
  165.             for (i = 0; i < LIST_items(psHost->psTagList); i++)
  166.             {
  167.                 pXml = (XMLPAR*)LIST_getItem(psHost->psTagList, i);
  168.                 if (!str_cmp(pXml->strTag, strTag))
  169.                     /* tag not found */
  170.                     pXml = NULL;
  171.                 else
  172.                     /* tag found */
  173.                     break;
  174.             }
  175.         }
  176.     }
  177.            
  178.     return (pXml); 
  179. }
  180.  
  181. XMLPAR* XMLPAR_getElementByIndex(XMLPAR* psHost, int iIndex)
  182. {
  183.     XMLPAR* pXml;
  184.    
  185.     pXml = NULL;
  186.    
  187.     /* at least one sub parameter found */
  188.     if (psHost->psTagList != NULL) 
  189.     {
  190.         /* limit index to valid range */
  191.         iIndex = clamp(iIndex, 0, LIST_items(psHost->psTagList) - 1);
  192.         pXml = (XMLPAR*)LIST_getItem(psHost->psTagList, iIndex);
  193.     }
  194.     return (pXml);
  195. }
  196.  
  197. int XMLPAR_getTagElements(XMLPAR* psHost)
  198. {
  199.     if (psHost->psTagList != NULL)
  200.         return (LIST_items(psHost->psTagList));
  201.     else
  202.         return (0);
  203. }
  204.  
  205. int XMLPAR_getAttributeElements(XMLPAR* psHost)
  206. {
  207.     if (psHost->psAttribList != NULL)
  208.         return (LIST_items(psHost->psAttribList)); 
  209.     else
  210.         return (0);
  211. }
  212.  
  213.  
  214. /* ----- XMLATTRIB ----- */
  215. XMLATTRIB* XMLATTRIB_create()
  216. {
  217.     XMLATTRIB* psHost;
  218.     psHost = (XMLATTRIB*)malloc(sizeof(XMLATTRIB));
  219.     psHost->strTag = NULL;
  220.     psHost->strContent = NULL;
  221.    
  222.     return (psHost);
  223. }
  224.  
  225. void XMLATTRIB_remove(XMLATTRIB* psHost)
  226. {
  227.     str_remove(psHost->strTag);
  228.     str_remove(psHost->strContent);
  229.  
  230.     free(psHost);
  231. }
  232.  
  233. XMLATTRIB* XMLATTRIB_getElementByAttribute(XMLPAR* psHost, STRING* strTag)
  234. {
  235.     int i;
  236.     XMLATTRIB* pXml;
  237.    
  238.     pXml = NULL;
  239.    
  240.     /* at least one sub parameter found */
  241.     if (psHost->psAttribList != NULL)
  242.     {
  243.         for (i = 0; i < LIST_items(psHost->psAttribList); i++)
  244.         {
  245.             pXml = (XMLATTRIB*)LIST_getItem(psHost->psAttribList, i);
  246.             if (!str_cmp(pXml->strTag, strTag))
  247.                 /* tag not found */
  248.                 pXml = NULL;
  249.             else
  250.                 /* tag found */
  251.                 break;
  252.         }
  253.     }
  254.            
  255.     return (pXml); 
  256. }
  257.  
  258. XMLATTRIB* XMLATTRIB_getElementByIndex(XMLPAR* psHost, int iIndex)
  259. {
  260.     XMLATTRIB* pXml;
  261.    
  262.     pXml = NULL;
  263.    
  264.     /* at least one sub parameter found */
  265.     if (psHost->psAttribList != NULL)  
  266.     {
  267.         /* limit index to valid range */
  268.         iIndex = clamp(iIndex, 0, LIST_items(psHost->psAttribList) - 1);
  269.         pXml = (XMLATTRIB*)LIST_getItem(psHost->psAttribList, iIndex);
  270.     }
  271.     return (pXml);
  272. }
  273.  
  274. void XMLATTRIB_getContent(XMLATTRIB* psHost, STRING* strTarget)
  275. {
  276.     if (psHost->strContent == NULL)
  277.         str_cpy(strTarget, "");
  278.     else
  279.         str_cpy(strTarget, psHost->strContent);
  280. }
  281.  
  282. void XMLATTRIB_getAttribute(XMLATTRIB* psHost, STRING* strTarget)
  283. {
  284.     if (psHost->strTag == NULL)
  285.         str_cpy(strTarget, "");
  286.     else
  287.         str_cpy(strTarget, psHost->strTag);
  288. }
  289.  
  290. STRING* XMLATTRIB_getPContent(XMLATTRIB* psHost)
  291. {
  292.     if (psHost->strContent != NULL)
  293.         return (psHost->strContent);
  294.     else
  295.         return (NULL);
  296. }
  297.  
  298. STRING* XMLATTRIB_getPAttribute(XMLATTRIB* psHost)
  299. {
  300.     if (psHost->strTag != NULL)
  301.         return (psHost->strTag);
  302.     else
  303.         return (NULL);
  304. }
  305.  
  306.  
  307. /* ----- INTERNAL FUNCTIONS ----- */
  308.  
  309.  
  310. /* ----- XMLFILE ----- */
  311. int XMLFILE__read(XMLFILE* psHost, XMLPAR* parentPar, int ntag)
  312. {
  313.     /* create new XMLPAR and add it to list of parent */
  314.     XMLPAR* par;
  315.     par = XMLPAR_create();
  316.     par->psParent = parentPar;
  317.     if (parentPar->psTagList == NULL)
  318.         parentPar->psTagList = LIST_create();
  319.     LIST_append(parentPar->psTagList, (void*)par);
  320.  
  321.     if(ntag == XML_OPENTAG)
  322.     {
  323.         if (XMLFILE__readOpenTag(psHost, par))
  324.         {
  325.             /* no content was found */
  326.             par->strContent = str_create("");
  327.             par->psTagList = NULL;
  328.             ntag = XMLFILE__findNext(psHost);
  329.         }
  330.         else
  331.         {
  332.             ntag = XMLFILE__findNext(psHost);
  333.             switch(ntag)
  334.             {
  335.                 /* NOTE: readContent and read should be changed so text and tag mixtures can be read as well */
  336.                 case XML_CONTENT:
  337.                     XMLFILE__readContent(psHost, par);
  338.                     ntag = XMLFILE__findNext(psHost);
  339.                     break;
  340.                            
  341.                 case XML_OPENTAG:
  342.                     do
  343.                     {
  344.                         ntag = XMLFILE__read(psHost, par, ntag);
  345.                     }while(ntag == XML_OPENTAG);
  346.                     break;
  347.                            
  348.                 case XML_CLOSETAG:
  349.                     /* no content was found */
  350.                     par->strContent = str_create("");
  351.                     par->psTagList = NULL;
  352.                     break;
  353.                            
  354.                 default:
  355.                     /* invalid file */
  356.                     ntag = XML_EOF;
  357.                     break; 
  358.             }
  359.  
  360.             if (ntag == XML_CLOSETAG)
  361.             {
  362.                 XMLFILE__readCloseTag(psHost);
  363.                 ntag = XMLFILE__findNext(psHost);
  364.             }
  365.             else
  366.                 /* invalid file */
  367.                 ntag = XML_EOF;
  368.         }
  369.  
  370.     }
  371.     else
  372.         /* invalid file */
  373.         ntag = XML_EOF;
  374.            
  375.     return (ntag);
  376. }
  377.    
  378. void XMLFILE__readTagAttrib(XMLFILE* psHost, XMLPAR* par)
  379. {
  380.     /* create new XMLATTRIB and add it to list of parent */
  381.     XMLATTRIB *attrib;
  382.  
  383.     attrib = XMLATTRIB_create();
  384.     attrib->psParent = par;
  385.     attrib->strTag = str_create("");
  386.     attrib->strContent = str_create("");
  387.     if (par->psAttribList == NULL)
  388.         par->psAttribList = LIST_create();
  389.     LIST_append(par->psAttribList, (void*)attrib);
  390.     psHost->cTmp[1] = '\0';
  391.    
  392.     /* read attribute tag */
  393.     do
  394.     {
  395.         psHost->cTmp[0] = file_asc_read(psHost->vFHndl);
  396.         if ((psHost->cTmp[0] > 32) && (psHost->cTmp[0] != EOF) && (psHost->cTmp[0] != '='))
  397.         {
  398.             str_cat(attrib->strTag, psHost->cTmp);
  399.         }
  400.     }
  401.     while((psHost->cTmp[0] != EOF) && (psHost->cTmp[0] != 32) && (psHost->cTmp[0] != '=')
  402.         && (psHost->cTmp[0] != '/') && (psHost->cTmp[0] != '>'));
  403.  
  404.     /* dummy read unnecessary bytes like spaces, " and = */
  405.     if ((psHost->cTmp[0] == '=') || (psHost->cTmp[0] == 32))
  406.     {
  407.         do
  408.         {
  409.             psHost->cTmp[0] = file_asc_read(psHost->vFHndl);
  410.         }
  411.         while((psHost->cTmp[0] != EOF) && (psHost->cTmp[0] != 34) && (psHost->cTmp[0] != '/') && (psHost->cTmp[0] != '>'));
  412.     }
  413.  
  414.     /* read attribute strContent */
  415.     if (psHost->cTmp[0] == 34)  /* 34 = " */
  416.     {
  417.         do
  418.         {
  419.             psHost->cTmp[0] = file_asc_read(psHost->vFHndl);
  420.             if ((psHost->cTmp[0] >= 32) && (psHost->cTmp[0] != EOF) && (psHost->cTmp[0] != 34))
  421.             {
  422.                 str_cat(attrib->strContent, psHost->cTmp);
  423.             }
  424.         }
  425.         while((psHost->cTmp[0] != EOF) && (psHost->cTmp[0] != 34) && (psHost->cTmp[0] != '/') && (psHost->cTmp[0] != '>'));
  426.     }
  427. //  printf("attribute: [%s], content: [%s]", (attrib->strTag)->chars, (attrib->strContent)->chars);
  428. }
  429.  
  430. int XMLFILE__readOpenTag(XMLFILE* psHost, XMLPAR* par)
  431. {
  432.     par->strTag = str_create("");
  433.     psHost->cTmp[1] = '\0';
  434.     do
  435.     {
  436.         psHost->cTmp[0] = file_asc_read(psHost->vFHndl);
  437.         /* check for valid byte and add it to tag string */
  438.        
  439.         if (psHost->cTmp[0] == 32 || psHost->cTmp[0] == '\n')
  440.         {
  441.             /* possible attribute tag detected */
  442.             do
  443.             {
  444.                 /* dummy read unnecessary bytes */
  445.                 do
  446.                 {
  447.                     psHost->cTmp[0] = file_asc_read(psHost->vFHndl);
  448.                 }
  449.                 while((psHost->cTmp[0] != EOF) && psHost->cTmp[0] <= 32);
  450.    
  451.                 /* check whether next character is attribute name or tag element */
  452.                 if((psHost->cTmp[0] != EOF) && (psHost->cTmp[0] != '/') && (psHost->cTmp[0] != '>'))
  453.                 {
  454.                     file_seek(psHost->vFHndl, -1, 1);
  455.                     XMLFILE__readTagAttrib(psHost, par);
  456.                 }
  457.             }while((psHost->cTmp[0] != EOF) && (psHost->cTmp[0] != '/') && (psHost->cTmp[0] != '>'));
  458.         }
  459.         else
  460.         {
  461.             if ((psHost->cTmp[0] >= 32) && (psHost->cTmp[0] != EOF) && (psHost->cTmp[0] != '/') && (psHost->cTmp[0] != '>'))
  462.             {
  463.                 str_cat(par->strTag, psHost->cTmp);
  464.             }
  465.         }
  466.     }while((psHost->cTmp[0] != EOF) && (psHost->cTmp[0] != '/') && (psHost->cTmp[0] != '>'));
  467. //printf ("tagname: [%s]", (par->strTag)->chars);          
  468.  
  469.     switch ((int)psHost->cTmp[0])
  470.     {
  471.         case '/':
  472.             do
  473.             {
  474.                 psHost->cTmp[0]  = file_asc_read(psHost->vFHndl);
  475.             }while((psHost->cTmp[0]  != '>') && (psHost->cTmp[0]  != EOF));
  476.        
  477.             psHost->iTmp = 1;   /* tag is empty */
  478.             break;
  479.            
  480.         case EOF:
  481.             psHost->iTmp = 1;   /* tag is empty */
  482.             break;
  483.        
  484.         default:
  485.             psHost->iTmp = 0;   /* tag has content */          
  486.             break;
  487.     }
  488.            
  489.     return (psHost->iTmp);
  490. }
  491.  
  492. void XMLFILE__readCloseTag(XMLFILE* psHost)
  493. {
  494.     /* just read in the closetag - no further action */
  495.     do
  496.     {
  497.         psHost->cTmp[0] = file_asc_read(psHost->vFHndl);
  498.     }while((psHost->cTmp[0] != EOF) && (psHost->cTmp[0] != '>'));
  499. }
  500.  
  501. void XMLFILE__readContent(XMLFILE* psHost, XMLPAR* par)
  502. {
  503.     par->strContent = str_create("");
  504.     psHost->cTmp[1] = '\0';
  505.    
  506.     do
  507.     {
  508.         psHost->cTmp[0] = file_asc_read(psHost->vFHndl);
  509.         /* check for valid byte and add it to tag string */
  510.         if ((psHost->cTmp[0] >= 32) && (psHost->cTmp[0] != EOF) && (psHost->cTmp[0] != '<'))
  511.         {
  512.             str_cat(par->strContent, psHost->cTmp);
  513.         }          
  514.     }while((psHost->cTmp[0] != EOF) && (psHost->cTmp[0] != '<'));
  515.     str_cat(par->strContent, "\0");    
  516.     file_seek(psHost->vFHndl, -1, 1);
  517.    
  518. }
  519.  
  520. int XMLFILE__findNext(XMLFILE* psHost)
  521. {
  522.     psHost->iTmp = XML_NOTAG;
  523.    
  524.     while(psHost->iTmp == XML_NOTAG)
  525.     {
  526.         /* search first useful sign */
  527.         do
  528.         {
  529.             psHost->cTmp[0] = file_asc_read(psHost->vFHndl);
  530.         }while((psHost->cTmp[0] < 32) && (psHost->cTmp[0] != EOF));
  531.        
  532.         /* evaluate finding*/
  533.         if (psHost->cTmp[0] == '<')
  534.         {
  535.             /* skip control bytes */
  536.             do
  537.             {
  538.                 psHost->cTmp[0] = file_asc_read(psHost->vFHndl);
  539.             }while((psHost->cTmp[0] < 32) && (psHost->cTmp[0] != EOF));
  540.             switch ((int)psHost->cTmp[0])
  541.             {
  542.                 case '/':   /* closing tag */
  543.                     psHost->iTmp = XML_CLOSETAG;
  544.                     break;
  545.                    
  546.                 case '!':
  547.                 case '?':   /* comment tag - skip and continue searching */
  548.                     XMLFILE__readCloseTag(psHost);  //ugly
  549.                     psHost->iTmp = XML_NOTAG;
  550.                     break;
  551.                    
  552.                 case EOF:   /* end of file */
  553.                     psHost->iTmp = XML_EOF;
  554.                     break;
  555.                    
  556.                 default:        /* opening tag */
  557.                     psHost->iTmp = XML_OPENTAG;
  558.                     /* set file pointer to previous byte */
  559.                     file_seek(psHost->vFHndl, -1, 1);
  560.                     break;
  561.             }
  562.         }
  563.         else
  564.         {
  565.             /* end of file check */
  566.             if (psHost->iTmp != EOF)
  567.             {
  568.                 /* tag content found */
  569.                 psHost->iTmp = XML_CONTENT;
  570.                 file_seek(psHost->vFHndl, -1, 1);
  571.             }
  572.             else
  573.                 psHost->iTmp = XML_EOF;
  574.         }
  575.     }
  576.    
  577.     return (psHost->iTmp);
  578. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement