HTTP Parser and message builder / objects in plain C Snapshot
|
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