|
|
|
/* 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;
|
|
|
|
}
|