mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-15 17:43:51 +01:00
Merge pull request #20197 from benpicco/coap_iterate_uri_query
nanocoap: add coap_iterate_uri_query()
This commit is contained in:
commit
4f9f755f99
@ -987,6 +987,31 @@ static inline ssize_t coap_get_uri_query_string(coap_pkt_t *pkt, char *target,
|
||||
bool coap_find_uri_query(coap_pkt_t *pkt, const char *key,
|
||||
const char **value, size_t *len);
|
||||
|
||||
/**
|
||||
* @brief Iterate over a packet's URI Query options
|
||||
*
|
||||
* This expects that the Uri-Query options follow the widespread format `key=value`
|
||||
* or just `key`
|
||||
*
|
||||
* Key and Value will be copied into the supplied buffers as a NULL-terminated
|
||||
* string.
|
||||
*
|
||||
* @param[in] pkt packet to read from
|
||||
* @param[out] ctx opaque, must be set to `NULL` on first call
|
||||
* @param[out] key Output buffer for the key
|
||||
* @param[in] key_len_max Size of the key output buffer
|
||||
* @param[out] value Output buffer for the value
|
||||
* @param[in] value_len_max Size of the value output buffer
|
||||
*
|
||||
* @return 2 if key and value were found
|
||||
* @return 1 if key was found
|
||||
* @return 0 if no key was found
|
||||
* @return -E2BIG if key or value does not fit the supplied space
|
||||
*/
|
||||
int coap_iterate_uri_query(coap_pkt_t *pkt, void **ctx,
|
||||
char *key, size_t key_len_max,
|
||||
char *value, size_t value_len_max);
|
||||
|
||||
/**
|
||||
* @brief Iterate over a packet's options
|
||||
*
|
||||
|
||||
@ -407,6 +407,56 @@ ssize_t coap_opt_get_string(coap_pkt_t *pkt, uint16_t optnum,
|
||||
return (int)(max_len - left);
|
||||
}
|
||||
|
||||
int coap_iterate_uri_query(coap_pkt_t *pkt, void **opt_pos,
|
||||
char *key, size_t key_len_max,
|
||||
char *value, size_t value_len_max)
|
||||
{
|
||||
int len;
|
||||
void *key_data = coap_iterate_option(pkt, COAP_OPT_URI_QUERY,
|
||||
(uint8_t **)opt_pos, &len);
|
||||
if (!key_data) {
|
||||
return 0; /* No key found */
|
||||
}
|
||||
|
||||
const char *value_data = memchr(key_data, '=', len);
|
||||
|
||||
size_t key_len, value_len;
|
||||
|
||||
if (value_data) {
|
||||
key_len = (uintptr_t)value_data - (uintptr_t)key_data;
|
||||
value_data += 1;
|
||||
value_len = len - key_len - 1;
|
||||
} else {
|
||||
key_len = len;
|
||||
value_data = NULL;
|
||||
value_len = 0;
|
||||
|
||||
if (value && value_len_max) {
|
||||
value[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (key_len >= key_len_max) {
|
||||
return -E2BIG;
|
||||
}
|
||||
memcpy(key, key_data, key_len);
|
||||
key[key_len] = 0;
|
||||
|
||||
if (!value_data) {
|
||||
return 1; /* Key was found but no values */
|
||||
}
|
||||
if (!value) {
|
||||
return 2; /* Key and values found */
|
||||
}
|
||||
|
||||
if (value_len >= value_len_max) {
|
||||
return -E2BIG;
|
||||
}
|
||||
memcpy(value, value_data, value_len);
|
||||
value[value_len] = 0;
|
||||
return 2; /* Key and values found */
|
||||
}
|
||||
|
||||
int coap_get_blockopt(coap_pkt_t *pkt, uint16_t option, uint32_t *blknum, uint8_t *szx)
|
||||
{
|
||||
uint8_t *optpos = coap_find_option(pkt, option);
|
||||
|
||||
@ -67,6 +67,8 @@ static void test_nanocoap__hdr_2(void)
|
||||
char path[] = "/test/abcd/efgh?foo=bar&baz=blub";
|
||||
unsigned char path_tmp[64] = {0};
|
||||
char query_tmp[64] = {0};
|
||||
char key[8];
|
||||
char value[8];
|
||||
|
||||
uint8_t *pktpos = &buf[0];
|
||||
uint16_t lastonum = 0;
|
||||
@ -86,6 +88,25 @@ static void test_nanocoap__hdr_2(void)
|
||||
res = coap_get_uri_query_string(&pkt, query_tmp, sizeof(query_tmp));
|
||||
TEST_ASSERT_EQUAL_INT(sizeof("&foo=bar&baz=blub"), res);
|
||||
TEST_ASSERT_EQUAL_STRING("&foo=bar&baz=blub", (char *)query_tmp);
|
||||
|
||||
void *pos = NULL;
|
||||
|
||||
res = coap_iterate_uri_query(&pkt, &pos, key, sizeof(key), value, 3);
|
||||
TEST_ASSERT_EQUAL_INT(-E2BIG, res);
|
||||
res = coap_iterate_uri_query(&pkt, &pos, key, 3, value, sizeof(value));
|
||||
TEST_ASSERT_EQUAL_INT(-E2BIG, res);
|
||||
|
||||
pos = NULL;
|
||||
res = coap_iterate_uri_query(&pkt, &pos, key, sizeof(key), value, sizeof(value));
|
||||
TEST_ASSERT_EQUAL_INT(2, res);
|
||||
TEST_ASSERT_EQUAL_STRING("foo", key);
|
||||
TEST_ASSERT_EQUAL_STRING("bar", value);
|
||||
res = coap_iterate_uri_query(&pkt, &pos, key, sizeof(key), value, sizeof(value));
|
||||
TEST_ASSERT_EQUAL_INT(2, res);
|
||||
TEST_ASSERT_EQUAL_STRING("baz", key);
|
||||
TEST_ASSERT_EQUAL_STRING("blub", value);
|
||||
res = coap_iterate_uri_query(&pkt, &pos, key, sizeof(key), value, sizeof(value));
|
||||
TEST_ASSERT_EQUAL_INT(0, res);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -347,10 +368,12 @@ static void test_nanocoap__get_multi_query(void)
|
||||
coap_pkt_t pkt;
|
||||
uint16_t msgid = 0xABCD;
|
||||
uint8_t token[2] = {0xDA, 0xEC};
|
||||
char key1[] = "ab";
|
||||
char val1[] = "cde";
|
||||
char key2[] = "f";
|
||||
char qs[] = "ab=cde&f";
|
||||
const char key1[] = "ab";
|
||||
const char val1[] = "cde";
|
||||
const char key2[] = "f";
|
||||
const char qs[] = "ab=cde&f";
|
||||
char key[8];
|
||||
char value[8];
|
||||
|
||||
size_t len = coap_build_hdr((coap_hdr_t *)&buf[0], COAP_TYPE_NON,
|
||||
&token[0], 2, COAP_METHOD_GET, msgid);
|
||||
@ -386,6 +409,18 @@ static void test_nanocoap__get_multi_query(void)
|
||||
TEST_ASSERT_EQUAL_INT((uintptr_t)NULL, (uintptr_t)val);
|
||||
TEST_ASSERT(!coap_find_uri_query(&pkt, "cde", &val, &val_len));
|
||||
TEST_ASSERT(coap_find_uri_query(&pkt, "ab", NULL, 0));
|
||||
|
||||
void *pos = NULL;
|
||||
int res = coap_iterate_uri_query(&pkt, &pos, key, sizeof(key), value, sizeof(value));
|
||||
TEST_ASSERT_EQUAL_INT(2, res);
|
||||
TEST_ASSERT_EQUAL_STRING("ab", key);
|
||||
TEST_ASSERT_EQUAL_STRING("cde", value);
|
||||
res = coap_iterate_uri_query(&pkt, &pos, key, sizeof(key), value, sizeof(value));
|
||||
TEST_ASSERT_EQUAL_INT(1, res);
|
||||
TEST_ASSERT_EQUAL_STRING("f", key);
|
||||
TEST_ASSERT_EQUAL_STRING("", value);
|
||||
res = coap_iterate_uri_query(&pkt, &pos, key, sizeof(key), value, sizeof(value));
|
||||
TEST_ASSERT_EQUAL_INT(0, res);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user