/* SPDX-License-Identifier: GPL-3.0-or-later */ /* Copyright 2022 Ivan Polyakov */ #include "query.h" #include "utils.h" #include #include #include 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 = 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 = strsep(&tokens, "&\n")) && i < len) { char *param, *val; if (*p == '=') continue; param = strtok(p, "="); val = strtok(NULL, "="); if (param) { dest->items[i].key = strdup(param); dest->items[i].val = val ? 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; }