Diff of /trunk/src/qnd_xml.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 39 by harbaum, Fri Jan 16 20:01:07 2009 UTC revision 40 by harbaum, Sun Jan 18 19:43:20 2009 UTC
# Line 30  Line 30 
30  #include <ctype.h>  #include <ctype.h>
31  int isblank(int c);  int isblank(int c);
32    
 #define QND_XML_BUFFER_SIZE 1024  
33  typedef struct {  typedef struct {
34    gpointer userdata;    gpointer userdata;
35    
   FILE *file;  
36    int total, bytes_read;    int total, bytes_read;
37    
38    char buffer[QND_XML_BUFFER_SIZE], *cur;    char *buffer, *cur;
   int fill;  
39    
40    qnd_xml_stack_t *stack, *sp;    qnd_xml_stack_t *stack, *sp;
41    int mod;   // modifier (?, !, /) in element    int mod;   // modifier (?, !, /) in element
# Line 91  qnd_xml_entry_t *stack_pop(qnd_xml_conte Line 88  qnd_xml_entry_t *stack_pop(qnd_xml_conte
88    return cur;    return cur;
89  }  }
90    
 gboolean update_buffer(qnd_xml_context_t *context) {  
   
   /* if buffer is empty just fill it */  
   if(!context->fill) {  
     context->cur = context->buffer;  
     context->fill = fread(context->buffer, 1l,  
           QND_XML_BUFFER_SIZE, context->file);  
   
     if(context->fill < 0) {  
       printf("read error\n");  
       context->fill = 0;  
       return FALSE;  
     }  
     context->bytes_read += context->fill;  
     return TRUE;  
   }  
   
   /* shift remaining data down */  
   int offset = context->cur - context->buffer;  
   g_memmove(context->buffer, context->cur, QND_XML_BUFFER_SIZE - offset);  
   context->fill -= offset;  
   int bytes_read = fread(context->buffer + QND_XML_BUFFER_SIZE -  
                          offset, 1l, offset, context->file);  
   
   context->cur = context->buffer;  
   if(bytes_read < 0) {  
     printf("read error\n");  
     return FALSE;  
   }  
   
   context->bytes_read += bytes_read;  
   context->fill += bytes_read;  
   return TRUE;  
 }  
   
91  /*  /*
92     utf8:     utf8:
93     0xxxxxxx     0xxxxxxx
# Line 153  inline gboolean skip_char(qnd_xml_contex Line 115  inline gboolean skip_char(qnd_xml_contex
115  }  }
116    
117  gboolean skip_to_char(qnd_xml_context_t *context, char *chrs) {  gboolean skip_to_char(qnd_xml_context_t *context, char *chrs) {
118    do {    while(context->cur < context->buffer + context->total) {
119      while(context->cur < context->buffer + context->fill) {      if(strchr(chrs, current_char(context))) {
120        if(strchr(chrs, current_char(context))) {        return skip_char(context);
         return skip_char(context);  
       }  
       if(!skip_char(context)) return FALSE;  
121      }      }
122        if(!skip_char(context)) return FALSE;
123      /* try to get more data */    }
     if(!update_buffer(context))  
       return FALSE;  
   
   } while(context->fill);  
124    
125    /* if we get here the system was unable to fill the buffer */    /* if we get here the system was unable to fill the buffer */
126    return FALSE;    return FALSE;
127  }  }
128    
129  gboolean buffer_overflow(qnd_xml_context_t *context) {  gboolean buffer_overflow(qnd_xml_context_t *context) {
130    return(!(context->cur < context->buffer + context->fill));    return(!(context->cur < context->buffer + context->total));
131  }  }
132    
133  gboolean get_element_name(qnd_xml_context_t *context) {  gboolean get_element_name(qnd_xml_context_t *context) {
134    
   /* drop everything before element from buffer */  
   if(!update_buffer(context)) return FALSE;  
   
135    char *start = context->cur;    char *start = context->cur;
136    
137    if(buffer_overflow(context) || !isalpha(current_char(context))) {    if(buffer_overflow(context) || !isalpha(current_char(context))) {
# Line 296  gboolean skip_white(qnd_xml_context_t *c Line 248  gboolean skip_white(qnd_xml_context_t *c
248  gboolean get_attributes(qnd_xml_context_t *context) {  gboolean get_attributes(qnd_xml_context_t *context) {
249    /* drop everything before element from buffer */    /* drop everything before element from buffer */
250    
   if(!update_buffer(context)) return FALSE;  
251    if(!skip_white(context)) return FALSE;    if(!skip_white(context)) return FALSE;
252    
253    while(isalpha(current_char(context))) {    while(isalpha(current_char(context))) {
# Line 330  void attributes_free(qnd_xml_context_t * Line 281  void attributes_free(qnd_xml_context_t *
281  void qnd_xml_cleanup(qnd_xml_context_t *context) {  void qnd_xml_cleanup(qnd_xml_context_t *context) {
282    /* todo: clean stack */    /* todo: clean stack */
283    
284    if(context->file) fclose(context->file);    if(context->buffer) g_free(context->buffer);
285    g_free(context);    g_free(context);
286  }  }
287    
# Line 396  gboolean get_element(qnd_xml_context_t * Line 347  gboolean get_element(qnd_xml_context_t *
347  }  }
348    
349  gpointer qnd_xml_parse(char *name, qnd_xml_entry_t *root, gpointer userdata) {  gpointer qnd_xml_parse(char *name, qnd_xml_entry_t *root, gpointer userdata) {
350      FILE *file = NULL;
351    qnd_xml_context_t *context = g_new0(qnd_xml_context_t, 1);    qnd_xml_context_t *context = g_new0(qnd_xml_context_t, 1);
352    context->cur = context->buffer;    context->cur = context->buffer;
353    context->userdata = userdata;    context->userdata = userdata;
# Line 412  gpointer qnd_xml_parse(char *name, qnd_x Line 364  gpointer qnd_xml_parse(char *name, qnd_x
364    }    }
365    
366    /* open file */    /* open file */
367    context->file = g_fopen(name, "r");    file = g_fopen(name, "r");
368    if(!context->file) {    if(!file) {
369      printf("unable to open file\n");      printf("unable to open file\n");
370      qnd_xml_cleanup(context);      qnd_xml_cleanup(context);
371      return FALSE;      return FALSE;
# Line 422  gpointer qnd_xml_parse(char *name, qnd_x Line 374  gpointer qnd_xml_parse(char *name, qnd_x
374    printf("file is open\n");    printf("file is open\n");
375    
376    /* get file length */    /* get file length */
377    fseek(context->file, 0l, SEEK_END);    fseek(file, 0l, SEEK_END);
378    context->total = ftell(context->file);    context->total = ftell(file);
379    fseek(context->file, 0l, SEEK_SET);    fseek(file, 0l, SEEK_SET);
380    
381    printf("file length is %d bytes\n", context->total);    printf("file length is %d bytes\n", context->total);
382    
383      /* load entire file into buffer */
384      context->buffer = g_malloc(context->total);
385      fread(context->buffer, 1l, context->total, file);
386      fclose(file);
387      context->cur = context->buffer;
388    
389      setlocale(LC_NUMERIC, "C");
390    
391    gboolean error = FALSE;    gboolean error = FALSE;
392    do    do
393      error = !get_element(context);      error = !get_element(context);
394    while(!error && !context->done);    while(!error && !context->done);
395    
396      setlocale(LC_NUMERIC, "");
397    
398    if(error) printf("parser ended with error\n");    if(error) printf("parser ended with error\n");
399    else      printf("parser ended successfully\n");    else      printf("parser ended successfully\n");
400    
# Line 464  char *qnd_xml_get_prop_str(qnd_xml_attri Line 426  char *qnd_xml_get_prop_str(qnd_xml_attri
426    if(value) return g_strdup(value);    if(value) return g_strdup(value);
427    return NULL;    return NULL;
428  }  }
429    
430    /* strtof this is c99 */
431    float strtof(const char *nptr, char **endptr);
432    
433    gboolean qnd_xml_get_prop_float(qnd_xml_attribute_t *attr, char *name,
434                                     float *dest) {
435      char *value = qnd_xml_get_prop(attr, name);
436      if(!value) return FALSE;
437      *dest = strtof(value, NULL);
438      return TRUE;
439    }
440    
441  gboolean qnd_xml_get_prop_double(qnd_xml_attribute_t *attr, char *name,  gboolean qnd_xml_get_prop_double(qnd_xml_attribute_t *attr, char *name,
442                                   double *dest) {                                   double *dest) {

Legend:
Removed from v.39  
changed lines
  Added in v.40