Advertisement
Guest User

Untitled

a guest
Jul 31st, 2011
623
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.10 KB | None | 0 0
  1. #include "xmlparser.h"
  2.  
  3.  
  4. // ----- DEFINES ----- //
  5. #define XML_UNKNOW              -1
  6. #define XML_DUNNOHANDLE         -2
  7. #define XML_OPEN_NODE           1
  8. #define XML_CLOSE_NODE          2
  9. #define XML_NODE_NAME           3
  10. #define XML_SPECIAL_NODE        4
  11. #define XML_NAME_DELIMITER      5
  12. #define XML_ATTR_START          6
  13. #define XML_ATTR_DELIMITER      7
  14. #define XML_NODE_END            8
  15. #define XML_CLOSE_END_NODE      9
  16.  
  17.  
  18. // ----- STRUCTS ----- //
  19. typedef struct xml_reader_{
  20.     char reading_tag;
  21.     char quote_read;
  22.     char node_ending;
  23.  
  24.     int lvl;
  25.  
  26.     long cur_pos;
  27.  
  28.     char read_buffer[1024];
  29.     char name_buffer[1024];
  30. }xml_reader_;
  31.  
  32. xml_reader_ xml_reader = {0};
  33.  
  34. typedef struct ret_{
  35.     int ret;
  36.     char ch;
  37. }ret_;
  38.  
  39.  
  40. // ----- PROTOTYPES ----- //
  41. void XML_FreeList( void );
  42. struct ret_ XML_GetChar( void );
  43. struct xml_node *XML_RecursiveSearchNode(char *name, struct xml_node *node);
  44.  
  45.  
  46. // ----- VARIABLES -----//
  47. char xml_path[1024];
  48.  
  49. char *xml_buffer = NULL;
  50. long xml_size = 0;
  51.  
  52.  
  53. struct xml_node *main_tree = NULL;
  54. struct xml_node *current_node = NULL;
  55.  
  56. // ----- CODE ----- //
  57.  
  58. //! Abrir el archivo para parsear posteriormente
  59. //! path: Ruta relativa o hard coded hacia el xml
  60. //TODO: No guardar en buffer, leer char a char!
  61. int XML_Open(char *path){
  62.     FILE *fp = fopen(path, "r");
  63.     if(!fp)
  64.         return -1;
  65.  
  66.     strcpy(xml_path, path);
  67.  
  68.     fseek(fp, 0, SEEK_END);
  69.     xml_size = ftell(fp);
  70.     rewind(fp);
  71.  
  72.     xml_buffer = (char*)malloc(xml_size+1);
  73.     if(!xml_buffer)
  74.         return -2;
  75.  
  76.     fread(xml_buffer, 1, xml_size, fp);
  77.  
  78.     fclose(fp);
  79.  
  80.     return 0;
  81. }
  82.  
  83.  
  84. struct ret_ XML_GetChar(){
  85.     char ch = xml_buffer[xml_reader.cur_pos++];
  86.     struct ret_ ret;
  87.     ret.ch = ch;
  88.  
  89.     if(xml_reader.quote_read == 1 && ch != '"'){
  90.         ret.ret = XML_NODE_NAME;
  91.         goto endfunc;
  92.     }
  93.     if(xml_reader.reading_tag == 0){
  94.         switch(ch){
  95.             case '<':
  96.                 xml_reader.reading_tag = 1;
  97.  
  98.                 if(xml_buffer[xml_reader.cur_pos] == '/'){
  99.                     xml_reader.node_ending = 1;
  100.                     ret.ret = XML_NODE_END;
  101.                 }else{                 
  102.                     xml_reader.node_ending = 0;
  103.                     ret.ret = XML_OPEN_NODE;
  104.                 }
  105.  
  106.                 goto endfunc;
  107.             default:
  108.                 ret.ret = XML_UNKNOW;
  109.                 goto endfunc;
  110.         }
  111.     }else{
  112.         if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')){
  113.             ret.ret = XML_NODE_NAME;
  114.             goto endfunc;
  115.         }else{
  116.             switch(ch){
  117.                 case '>':      
  118.                     xml_reader.reading_tag = 0;
  119.                     if(xml_buffer[xml_reader.cur_pos-2] == '/')
  120.                         ret.ret = XML_CLOSE_END_NODE;
  121.                     else
  122.                         ret.ret = XML_CLOSE_NODE;
  123.                     goto endfunc;
  124.                 case '?':
  125.                     ret.ret = XML_SPECIAL_NODE;
  126.                     goto endfunc;                  
  127.                 case ' ':
  128.                     ret.ret = XML_NAME_DELIMITER;
  129.                     goto endfunc;      
  130.                 case '=':
  131.                     ret.ret = XML_ATTR_START;
  132.                     goto endfunc;  
  133.                 case '"':
  134.                     xml_reader.quote_read = !xml_reader.quote_read;
  135.                     ret.ret = XML_ATTR_DELIMITER;
  136.                     goto endfunc;  
  137.             }
  138.         }
  139.     }
  140.  
  141.  
  142. endfunc:
  143.     return ret;
  144. }
  145.  
  146. struct xml_node *XML_ParseAll(){
  147.     char action = 0;
  148.     char ignore = 0;
  149.     int buffer_pos = 0;
  150.  
  151.     memset(xml_reader.read_buffer, 0, 1024);
  152.     memset(xml_reader.name_buffer, 0, 1024);
  153.     xml_reader.reading_tag = 0;
  154.     xml_reader.quote_read = 0;
  155.  
  156.     struct xml_node_attr *last_attr = NULL;
  157.     struct xml_node_attr *first_attr = NULL;
  158.  
  159.     while(xml_reader.cur_pos < xml_size){
  160.         struct ret_ ret = XML_GetChar();
  161.        
  162.         if(ignore && ret.ret != XML_SPECIAL_NODE)
  163.             continue;
  164.  
  165.         switch(ret.ret){
  166.             case XML_SPECIAL_NODE:
  167.                 ignore = !ignore;
  168.                 break;
  169.             case XML_OPEN_NODE:
  170.                
  171.                 if(!main_tree){
  172.                     main_tree = current_node = (struct xml_node*)malloc(sizeof(struct xml_node));                  
  173.                     memset(current_node, 0, sizeof(struct xml_node));
  174.                 }else if(current_node->closed){
  175.                     current_node->next = (struct xml_node*)malloc(sizeof(struct xml_node));
  176.                     memset(current_node->next, 0, sizeof(struct xml_node));
  177.                     current_node->next->parent = current_node->parent;
  178.                     current_node->next->last = current_node;
  179.                     current_node = current_node->next;
  180.                 }else{
  181.                     current_node->child = (struct xml_node*)malloc(sizeof(struct xml_node));
  182.                     memset(current_node->child, 0, sizeof(struct xml_node));
  183.                     current_node->child->parent = current_node;
  184.                     current_node = current_node->child;
  185.                 }
  186.  
  187.                 action = 0;
  188.                 break;
  189.             case XML_NODE_NAME:
  190.                 xml_reader.read_buffer[buffer_pos++] = ret.ch;
  191.                 break;
  192.             case XML_NAME_DELIMITER:{
  193.                 if(buffer_pos > 0){
  194.                    
  195.                     if(action == 0)
  196.                         strcpy(xml_reader.name_buffer, xml_reader.read_buffer);
  197.  
  198.                     memset(xml_reader.read_buffer, 0, 1024);
  199.                     buffer_pos = 0;
  200.  
  201.                 }
  202.             }break;
  203.  
  204.             case XML_ATTR_START:{
  205.                 struct xml_node_attr *temp_attr = (struct xml_node_attr*)malloc(sizeof(struct xml_node_attr));
  206.                 memset(temp_attr, 0, sizeof(struct xml_node_attr));
  207.  
  208.                 temp_attr->name = (char*)malloc(buffer_pos);
  209.                 strcpy(temp_attr->name, xml_reader.read_buffer);
  210.                            
  211.                 if(last_attr != NULL)
  212.                     last_attr->next = temp_attr;
  213.                 last_attr = temp_attr;
  214.  
  215.                 if(first_attr == NULL)
  216.                     first_attr = last_attr;
  217.  
  218.                 memset(xml_reader.read_buffer, 0, 1024);
  219.                 buffer_pos = 0;
  220.             }break;
  221.  
  222.             case XML_ATTR_DELIMITER:
  223.                 if(xml_reader.quote_read == 0){
  224.  
  225.                     last_attr->value = (char*)malloc(buffer_pos);
  226.                     strcpy(last_attr->value, xml_reader.read_buffer);
  227.                
  228.                     memset(xml_reader.read_buffer, 0, 1024);
  229.                     buffer_pos = 0;
  230.                 }
  231.                 break;
  232.  
  233.             case XML_CLOSE_END_NODE:
  234.             case XML_CLOSE_NODE:
  235.                 if(xml_reader.node_ending == 0){
  236.                     current_node->name = (char*)malloc(buffer_pos);
  237.                     if(strlen(xml_reader.name_buffer) > 0)
  238.                         strcpy(current_node->name, xml_reader.name_buffer);
  239.                     else
  240.                         strcpy(current_node->name, xml_reader.read_buffer);
  241.  
  242.                     current_node->level = xml_reader.lvl;
  243.                     current_node->attrs = first_attr;                                          
  244.                     current_node->start_pos = xml_reader.cur_pos;
  245.                 }                  
  246.                                                
  247.                 memset(xml_reader.name_buffer, 0, 1024);
  248.                 memset(xml_reader.read_buffer, 0, 1024);
  249.                 buffer_pos = 0;
  250.  
  251.                 first_attr = NULL;
  252.                 last_attr = NULL;
  253.  
  254.                 if(ret.ret == XML_CLOSE_END_NODE){
  255.                     current_node->closed = 1;
  256.                     current_node->end_pos = xml_reader.cur_pos;
  257.                 }
  258.  
  259.                 break;
  260.  
  261.             case XML_NODE_END:
  262.                 while(current_node->closed == 1)
  263.                     current_node = current_node->parent;
  264.  
  265.                 current_node->closed = 1;
  266.                 current_node->end_pos = xml_reader.cur_pos;
  267.  
  268.                 memset(xml_reader.name_buffer, 0, 1024);
  269.                 memset(xml_reader.read_buffer, 0, 1024);
  270.                 buffer_pos = 0;
  271.  
  272.                 break;
  273.  
  274.             default:
  275.                 break;
  276.         }
  277.     }
  278.    
  279.     return main_tree;
  280. }
  281.  
  282. struct xml_node *XML_RecursiveSearchNode(char *name, struct xml_node *node){
  283.     if(strcmp(name, node->name) == 0)
  284.         return node;
  285.  
  286.     struct xml_node *ret = NULL;
  287.  
  288.     if(node->child)
  289.         ret = XML_RecursiveSearchNode(name, node->child);
  290.  
  291.     if(ret)
  292.         return ret;
  293.  
  294.     if(node->next)
  295.         ret = XML_RecursiveSearchNode(name, node->next);
  296.        
  297.     if(ret)
  298.         return ret;
  299.  
  300.     return NULL;
  301. }
  302.  
  303. struct xml_node *XML_SearchNodeFrom(char *name, struct xml_node *start){
  304.     return XML_RecursiveSearchNode(name, start);
  305. }
  306. struct xml_node *XML_SearchNode(char *name){
  307.     return XML_RecursiveSearchNode(name, main_tree);
  308. }
  309.  
  310. struct xml_node *XML_GetChild(struct xml_node *node){
  311.     return node->child;
  312. }
  313.  
  314. struct xml_node *XML_GetNextNode(struct xml_node *node){
  315.     return node->next;
  316. }
  317.  
  318. struct xml_node_attr *XML_GetNodeAttr(struct xml_node *node, char *name){
  319.     struct xml_node_attr *iterator = node->attrs;
  320.     while(iterator != NULL){
  321.         if(strcmp(iterator->name, name) == 0)
  322.             return iterator;
  323.         iterator = iterator->next;
  324.     }
  325.  
  326.     return NULL;
  327. }
  328.  
  329. char *XML_GetNodeValue(struct xml_node *node){
  330.     if(node->value == NULL){
  331.         int len = node->end_pos - node->start_pos - 1;
  332.         char *buffer =(char*)malloc(len);
  333.         memcpy(buffer, &xml_buffer[node->start_pos], len);
  334.         buffer[len] = '\0';
  335.         node->value = buffer;
  336.     }
  337.     return node->value;
  338. }
  339.  
  340. void XML_RecursiveFreeNode(xml_node *node){
  341.     if(node->child)
  342.         XML_RecursiveFreeNode(node->child);
  343.  
  344.     if(node->next)
  345.         XML_RecursiveFreeNode(node->next);
  346.  
  347.     free(node);
  348.     node = NULL;
  349. }
  350.  
  351. //! Liberar la memoria ocupada por xml_buffer
  352. void XML_EndParse(char free_tree){
  353.     free(xml_buffer);
  354.  
  355.     if(free_tree)
  356.         XML_RecursiveFreeNode(main_tree);
  357.  
  358.     main_tree = current_node = NULL;
  359. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement