HTTP Parser and message builder / objects in plain C Snapshot
query.c
Go to the documentation of this file.
00001 #include "query.h"
00002 #include <string.h>
00003 #include "sutils.h"
00004 
00005 
00006 static int QUERYSTRING_add(QUERYSTRING *query, char *name, char *value )
00007 {
00008   HASHNAMEVALUE *entry; 
00009 
00010   if (!name || !value) {
00011     if (name) {
00012       free(name);
00013     }
00014     if (value) {
00015       free(value);
00016     }
00017     return -1;
00018   }
00019 
00020   entry = (HASHNAMEVALUE *) malloc( sizeof( HASHNAMEVALUE ) );
00021   if (!entry) {
00022     return -1;
00023   }
00024   entry->name = name; //strdup( name );
00025   entry->value = value; //strdup( value );
00026 
00027   return HASH_insert( &query->name_to_value, &entry->entry, entry->name, -1 );
00028 }
00029 
00030 static int compare_entry(HASH_Entry *entry, void *key, ssize_t key_size)
00031 {
00032   M_UNUSED(key_size);
00033   return strcmp( ((HASHNAMEVALUE *) entry)->name, key);
00034 }
00035 
00036 int QUERYSTRING_init(QUERYSTRING *query, URI *uri)
00037 {
00038    char *start, *pos, *name;    
00039    int state = 0;
00040    size_t off;  
00041    char is_escaped_char;
00042 
00043    pos = uri->query;
00044 
00045    if (HASH_init( &query->name_to_value, 32, 1, compare_entry, 0 ) ) {
00046      return -1;
00047    }
00048 
00049    for( ; *pos != 0 ; ++pos ) {
00050       off = pos - uri->cdata;
00051       is_escaped_char = uri->cdata_is_escaped[ off ];
00052 
00053       switch(state) {
00054          case 0: // start parsing of name component.
00055            start = pos;
00056            state = 1;
00057          //break;
00058 
00059          case 1:
00060            if (is_escaped_char != 0 || *pos != '=') {
00061               break;
00062            }
00063            state = 2;
00064          //break;
00065 
00066          case 2: // end of name
00067            name = strdup_range(start, pos);
00068            state = 3;
00069            start = pos + 1;
00070            break;
00071 
00072         case 3:  // parsing the value component.
00073            if (is_escaped_char == 0 && *pos == '&') {
00074               state = 0;
00075               if (QUERYSTRING_add( query, name,  strdup_range(start, pos) ) ) {
00076                 return -1;
00077               }
00078            }
00079            break;
00080       }
00081    }
00082    if (state <= 2) {
00083          if (QUERYSTRING_add( query,  strdup_range(start, pos), strdup("") ) ) {
00084                 return -1;
00085          }
00086 
00087    } else {
00088          if (QUERYSTRING_add( query, name, strdup_range(start, pos) ) ) {
00089              return -1;
00090          }
00091    }
00092    return 0;
00093 }
00094 
00095 int QUERYSTRING_free(QUERYSTRING *query )
00096 {
00097   HASH_Entry *cur;
00098   HASHNAMEVALUE *nv;
00099 
00100   HASH_DELETEALL( cur, &query->name_to_value )
00101     nv = (HASHNAMEVALUE *) cur;
00102     free( nv->name );
00103     free( nv->value );
00104   HASH_DELETEALL_END
00105   HASH_free( &query->name_to_value );
00106   return 0;
00107 }
00108 
00109