HTTP Parser and message builder / objects in plain C Snapshot
Functions
query.c File Reference
#include "query.h"
#include <string.h>
#include "sutils.h"

Go to the source code of this file.

Functions

static int QUERYSTRING_add (QUERYSTRING *query, char *name, char *value)
static int compare_entry (HASH_Entry *entry, void *key, ssize_t key_size)
int QUERYSTRING_init (QUERYSTRING *query, URI *uri)
int QUERYSTRING_free (QUERYSTRING *query)

Function Documentation

static int compare_entry ( HASH_Entry *  entry,
void *  key,
ssize_t  key_size 
) [static]

Definition at line 30 of file query.c.

{
  M_UNUSED(key_size);
  return strcmp( ((HASHNAMEVALUE *) entry)->name, key);
}
static int QUERYSTRING_add ( QUERYSTRING query,
char *  name,
char *  value 
) [static]

Definition at line 6 of file query.c.

{
  HASHNAMEVALUE *entry; 

  if (!name || !value) {
    if (name) {
      free(name);
    }
    if (value) {
      free(value);
    }
    return -1;
  }

  entry = (HASHNAMEVALUE *) malloc( sizeof( HASHNAMEVALUE ) );
  if (!entry) {
    return -1;
  }
  entry->name = name; //strdup( name );
  entry->value = value; //strdup( value );

  return HASH_insert( &query->name_to_value, &entry->entry, entry->name, -1 );
}
int QUERYSTRING_free ( QUERYSTRING query)

Definition at line 95 of file query.c.

{
  HASH_Entry *cur;
  HASHNAMEVALUE *nv;

  HASH_DELETEALL( cur, &query->name_to_value )
    nv = (HASHNAMEVALUE *) cur;
    free( nv->name );
    free( nv->value );
  HASH_DELETEALL_END
  HASH_free( &query->name_to_value );
  return 0;
}
int QUERYSTRING_init ( QUERYSTRING query,
URI uri 
)

Definition at line 36 of file query.c.

{
   char *start, *pos, *name;    
   int state = 0;
   size_t off;  
   char is_escaped_char;

   pos = uri->query;

   if (HASH_init( &query->name_to_value, 32, 1, compare_entry, 0 ) ) {
     return -1;
   }

   for( ; *pos != 0 ; ++pos ) {
      off = pos - uri->cdata;
      is_escaped_char = uri->cdata_is_escaped[ off ];

      switch(state) {
         case 0: // start parsing of name component.
           start = pos;
           state = 1;
         //break;

         case 1:
           if (is_escaped_char != 0 || *pos != '=') {
              break;
           }
           state = 2;
         //break;

         case 2: // end of name
           name = strdup_range(start, pos);
           state = 3;
           start = pos + 1;
           break;

        case 3:  // parsing the value component.
           if (is_escaped_char == 0 && *pos == '&') {
              state = 0;
              if (QUERYSTRING_add( query, name,  strdup_range(start, pos) ) ) {
                return -1;
              }
           }
           break;
      }
   }
   if (state <= 2) {
         if (QUERYSTRING_add( query,  strdup_range(start, pos), strdup("") ) ) {
                return -1;
         }

   } else {
         if (QUERYSTRING_add( query, name, strdup_range(start, pos) ) ) {
             return -1;
         }
   }
   return 0;
}