C and C++ web framework.
http://rapida.vilor.one/docs
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.1 KiB
91 lines
2.1 KiB
/* SPDX-License-Identifier: GPL-3.0-or-later */ |
|
/* Copyright 2022 Ivan Polyakov */ |
|
|
|
#include "query.h" |
|
#include "utils.h" |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <string.h> |
|
|
|
int rpd_query_parse(rpd_keyval *dest, const char *src) |
|
{ |
|
int len = count_char_entries(src, '='); |
|
if (!len) { |
|
dest->items = NULL; |
|
dest->capacity = 0; |
|
dest->size = 0; |
|
return 0; |
|
} |
|
|
|
char *query = rpd_strdup(src); |
|
if (!query) |
|
return 1; |
|
|
|
dest->items = realloc(dest->items, sizeof(rpd_keyval_item *) * len); |
|
if (!dest->items) |
|
return 2; |
|
dest->capacity = len; |
|
|
|
char *tokens = query, *p = query; |
|
int i = 0; |
|
while ((p = rpd_strsep(&tokens, "&\n")) && i < len) { |
|
char *param, *val; |
|
|
|
if (*p == '=') |
|
continue; |
|
param = strtok(p, "="); |
|
val = strtok(NULL, "="); |
|
|
|
if (param) { |
|
dest->items[i].key = rpd_strdup(param); |
|
dest->items[i].val = val ? rpd_strdup(val) : NULL; |
|
i++; |
|
} |
|
} |
|
|
|
dest->size = i; |
|
dest->capacity = i; |
|
free(query); |
|
return 0; |
|
} |
|
|
|
char *rpd_query_str(const rpd_keyval *query) |
|
{ |
|
size_t len = 0; |
|
rpd_keyval_item *item; |
|
for (int i = 0; i < query->size; i++) { |
|
item = &query->items[i]; |
|
if (!item->key || !item->val) |
|
continue; |
|
len += strlen(item->key) + strlen(item->val); |
|
} |
|
|
|
/* len + number of key-val delimeters + terminating char */ |
|
size_t size = len + (query->size - 1) + 1; |
|
if (size <= 0) |
|
return NULL; |
|
|
|
char *buff = (char *) malloc(sizeof(char) * size); |
|
if (!buff) |
|
return NULL; |
|
buff[size - 1] = '\0'; |
|
|
|
size_t offset = 0; |
|
for (int i = 0; i < query->size; i++) { |
|
item = &query->items[i]; |
|
if (!item->key || !item->val) |
|
continue; |
|
offset += sprintf(buff + offset, "%s=%s", item->key, item->val); |
|
|
|
if (i + 1 < query->size) { |
|
buff[offset] = '&'; |
|
offset++; |
|
} |
|
} |
|
|
|
if (buff[offset - 1] == '&') { |
|
buff[offset - 1] = '\0'; |
|
} |
|
|
|
return buff; |
|
}
|
|
|