Skip to content

Commit

Permalink
Add ada_c API for url search params
Browse files Browse the repository at this point in the history
  • Loading branch information
jasnell committed Oct 9, 2023
1 parent 67da25c commit 60579dd
Show file tree
Hide file tree
Showing 3 changed files with 327 additions and 0 deletions.
60 changes: 60 additions & 0 deletions include/ada_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,64 @@ const ada_url_components* ada_get_components(ada_url result);
ada_owned_string ada_idna_to_unicode(const char* input, size_t length);
ada_owned_string ada_idna_to_ascii(const char* input, size_t length);

// url search params
typedef void* ada_url_search_params;
typedef void* ada_strings;
typedef void* ada_url_search_params_keys_iter;
typedef void* ada_url_search_params_values_iter;

typedef struct {
ada_string key;
ada_string value;
} ada_string_pair;

typedef void* ada_url_search_params_entries_iter;

ada_url_search_params ada_parse_search_params(const char* input, size_t length);
void ada_search_params_free(ada_url_search_params result);

size_t ada_search_params_size(ada_url_search_params result);
void ada_search_params_sort(ada_url_search_params result);
ada_owned_string ada_search_params_to_string(ada_url_search_params result);

void ada_search_params_append(ada_url_search_params result,
const char* key, size_t key_length,
const char* value, size_t value_length);
void ada_search_params_set(ada_url_search_params result,
const char* key, size_t key_length,
const char* value, size_t value_length);
void ada_search_params_remove(ada_url_search_params result,
const char* key, size_t key_length);
void ada_search_params_remove_value(ada_url_search_params result,
const char* key, size_t key_length,
const char* value, size_t value_length);
bool ada_search_params_has(ada_url_search_params result,
const char* key, size_t key_length);
bool ada_search_params_has_value(ada_url_search_params result,
const char* key, size_t key_length,
const char* value, size_t value_length);
ada_string ada_search_params_get(ada_url_search_params result,
const char* key, size_t key_length);
ada_strings ada_search_params_get_all(ada_url_search_params result,
const char* key, size_t key_length);
ada_url_search_params_keys_iter ada_search_params_get_keys(ada_url_search_params result);
ada_url_search_params_values_iter ada_search_params_get_values(ada_url_search_params result);
ada_url_search_params_entries_iter ada_search_params_get_entries(ada_url_search_params result);

void ada_strings_free(ada_strings result);
size_t ada_strings_size(ada_strings result);
ada_string ada_strings_get(ada_strings result, size_t index);

void ada_search_params_keys_iter_free(ada_url_search_params_keys_iter result);
ada_string ada_search_params_keys_iter_next(ada_url_search_params_keys_iter result);
bool ada_search_params_keys_iter_is_done(ada_url_search_params_keys_iter result);

void ada_search_params_values_iter_free(ada_url_search_params_values_iter result);
ada_string ada_search_params_values_iter_next(ada_url_search_params_values_iter result);
bool ada_search_params_values_iter_is_done(ada_url_search_params_values_iter result);

void ada_search_params_entries_iter_free(ada_url_search_params_entries_iter result);
ada_string_pair ada_search_params_entries_iter_next(ada_url_search_params_entries_iter result);
bool ada_search_params_entries_iter_is_done(ada_url_search_params_entries_iter result);

#endif // ADA_C_H
192 changes: 192 additions & 0 deletions src/ada_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ ada::result<ada::url_aggregator>& get_instance(void* result) noexcept {

extern "C" {
typedef void* ada_url;
typedef void* ada_url_search_params;
typedef void* ada_strings;
typedef void* ada_url_search_params_keys_iter;
typedef void* ada_url_search_params_values_iter;
typedef void* ada_url_search_params_entries_iter;

struct ada_string {
const char* data;
Expand All @@ -17,6 +22,11 @@ struct ada_owned_string {
size_t length;
};

struct ada_string_pair {
ada_string key;
ada_string value;
};

ada_string ada_string_create(const char* data, size_t length) {
ada_string out{};
out.data = data;
Expand Down Expand Up @@ -456,4 +466,186 @@ ada_owned_string ada_idna_to_ascii(const char* input, size_t length) {
return owned;
}

ada_url_search_params ada_parse_search_params(const char *input, size_t length) {
return new ada::result<ada::url_search_params>(
ada::url_search_params(std::string_view(input, length)));
}

void ada_search_params_free(ada_url_search_params result) {
ada::result<ada::url_search_params>* r =
(ada::result<ada::url_search_params>*)result;
delete r;
}

ada_owned_string ada_search_params_to_string(ada_url_search_params result) {
ada::result<ada::url_search_params>& r = *(ada::result<ada::url_search_params>*)result;
std::string out = r->to_string();
ada_owned_string owned{};
owned.length = out.size();
owned.data = new char[owned.length];
memcpy((void*)owned.data, out.data(), owned.length);
return owned;
}

size_t ada_search_params_size(ada_url_search_params result) {
ada::result<ada::url_search_params>& r = *(ada::result<ada::url_search_params>*)result;
return r->size();
}

void ada_search_params_sort(ada_url_search_params result) {
ada::result<ada::url_search_params>& r = *(ada::result<ada::url_search_params>*)result;
r->sort();
}

void ada_search_params_append(ada_url_search_params result,
const char* key, size_t key_length,
const char* value, size_t value_length) {
ada::result<ada::url_search_params>& r = *(ada::result<ada::url_search_params>*)result;
r->append(std::string_view(key, key_length), std::string_view(value, value_length));
}

void ada_search_params_set(ada_url_search_params result,
const char* key, size_t key_length,
const char* value, size_t value_length) {
ada::result<ada::url_search_params>& r = *(ada::result<ada::url_search_params>*)result;
r->set(std::string_view(key, key_length), std::string_view(value, value_length));
}

void ada_search_params_remove(ada_url_search_params result,
const char* key, size_t key_length) {
ada::result<ada::url_search_params>& r = *(ada::result<ada::url_search_params>*)result;
r->remove(std::string_view(key, key_length));
}

void ada_search_params_remove_value(ada_url_search_params result,
const char* key, size_t key_length,
const char* value, size_t value_length) {
ada::result<ada::url_search_params>& r = *(ada::result<ada::url_search_params>*)result;
r->remove(std::string_view(key, key_length), std::string_view(value, value_length));
}

bool ada_search_params_has(ada_url_search_params result,
const char* key, size_t key_length) {
ada::result<ada::url_search_params>& r = *(ada::result<ada::url_search_params>*)result;
return r->has(std::string_view(key, key_length));
}

bool ada_search_params_has_value(ada_url_search_params result,
const char* key, size_t key_length,
const char* value, size_t value_length) {
ada::result<ada::url_search_params>& r = *(ada::result<ada::url_search_params>*)result;
return r->has(std::string_view(key, key_length), std::string_view(value, value_length));
}

ada_string ada_search_params_get(ada_url_search_params result,
const char* key, size_t key_length) {
ada::result<ada::url_search_params>& r = *(ada::result<ada::url_search_params>*)result;
auto found = r->get(std::string_view(key, key_length));
if (!found.has_value()) return ada_string_create(NULL, 0);
return ada_string_create(found->data(), found->length());
}

ada_strings ada_search_params_get_all(ada_url_search_params result,
const char* key, size_t key_length) {
ada::result<ada::url_search_params>& r = *(ada::result<ada::url_search_params>*)result;
return new ada::result<std::vector<std::string>>(r->get_all(std::string_view(key, key_length)));
}

ada_url_search_params_keys_iter ada_search_params_get_keys(ada_url_search_params result) {
ada::result<ada::url_search_params>& r = *(ada::result<ada::url_search_params>*)result;
return new ada::result<ada::url_search_params_keys_iter>(r->get_keys());
}

ada_url_search_params_values_iter ada_search_params_get_values(ada_url_search_params result) {
ada::result<ada::url_search_params>& r = *(ada::result<ada::url_search_params>*)result;
return new ada::result<ada::url_search_params_values_iter>(r->get_values());
}

ada_url_search_params_entries_iter ada_search_params_get_entries(ada_url_search_params result) {
ada::result<ada::url_search_params>& r = *(ada::result<ada::url_search_params>*)result;
return new ada::result<ada::url_search_params_entries_iter>(r->get_entries());
}

void ada_strings_free(ada_strings result) {
ada::result<std::vector<std::string>>* r =
(ada::result<std::vector<std::string>>*)result;
delete r;
}

size_t ada_strings_size(ada_strings result) {
ada::result<std::vector<std::string>>* r =
(ada::result<std::vector<std::string>>*)result;
return (*r)->size();
}

ada_string ada_strings_get(ada_strings result, size_t index) {
ada::result<std::vector<std::string>>* r =
(ada::result<std::vector<std::string>>*)result;
std::string_view view = (*r)->at(index);
return ada_string_create(view.data(), view.length());
}

void ada_search_params_keys_iter_free(ada_url_search_params_keys_iter result) {
ada::result<ada::url_search_params_keys_iter>* r =
(ada::result<ada::url_search_params_keys_iter>*)result;
delete r;
}

ada_string ada_search_params_keys_iter_next(ada_url_search_params_keys_iter result) {
ada::result<ada::url_search_params_keys_iter>* r =
(ada::result<ada::url_search_params_keys_iter>*)result;
auto next = (*r)->next();
if (!next.has_value()) return ada_string_create(NULL, 0);
return ada_string_create(next->c_str(), next->length());
}

bool ada_search_params_keys_iter_is_done(ada_url_search_params_keys_iter result) {
ada::result<ada::url_search_params_keys_iter>* r =
(ada::result<ada::url_search_params_keys_iter>*)result;
return (*r)->is_done();
}

void ada_search_params_values_iter_free(ada_url_search_params_values_iter result) {
ada::result<ada::url_search_params_values_iter>* r =
(ada::result<ada::url_search_params_values_iter>*)result;
delete r;
}

ada_string ada_search_params_values_iter_next(ada_url_search_params_values_iter result) {
ada::result<ada::url_search_params_values_iter>* r =
(ada::result<ada::url_search_params_values_iter>*)result;
auto next = (*r)->next();
if (!next.has_value()) return ada_string_create(NULL, 0);
return ada_string_create(next->c_str(), next->length());
}

bool ada_search_params_values_iter_is_done(ada_url_search_params_values_iter result) {
ada::result<ada::url_search_params_values_iter>* r =
(ada::result<ada::url_search_params_values_iter>*)result;
return (*r)->is_done();
}

void ada_search_params_entries_iter_free(ada_url_search_params_entries_iter result) {
ada::result<ada::url_search_params_entries_iter>* r =
(ada::result<ada::url_search_params_entries_iter>*)result;
delete r;
}

ada_string_pair ada_search_params_entries_iter_next(ada_url_search_params_entries_iter result) {
ada::result<ada::url_search_params_entries_iter>* r =
(ada::result<ada::url_search_params_entries_iter>*)result;
auto next = (*r)->next();
if (!next.has_value()) return { ada_string_create(NULL, 0), ada_string_create(NULL, 0) };
return ada_string_pair {
ada_string_create(next->first.c_str(), next->first.length()),
ada_string_create(next->second.c_str(), next->second.length())
};
}

bool ada_search_params_entries_iter_is_done(ada_url_search_params_entries_iter result) {
ada::result<ada::url_search_params_entries_iter>* r =
(ada::result<ada::url_search_params_entries_iter>*)result;
return (*r)->is_done();
}

} // extern "C"
75 changes: 75 additions & 0 deletions tests/ada_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,78 @@ TEST(ada_c, ada_get_scheme_type) {
ada_free(out);
SUCCEED();
}

TEST(ada_c, ada_url_search_params) {
std::string_view input;
ada_url_search_params out;

input = "a=b&c=d&c=e&f=g";
out = ada_parse_search_params(input.data(), input.size());

ASSERT_EQ(ada_search_params_size(out), 4);

std::string key = "key1";
std::string value = "value1";
std::string value2 = "value2";
ada_search_params_append(out, key.c_str(), key.length(), value.c_str(), value.length());
ASSERT_EQ(ada_search_params_size(out), 5);

ada_search_params_set(out, key.c_str(), key.length(), value2.c_str(), value2.length());
ASSERT_EQ(ada_search_params_size(out), 5);

ASSERT_TRUE(ada_search_params_has(out, key.c_str(), key.length()));
ASSERT_FALSE(ada_search_params_has_value(out, key.c_str(), key.length(),
value.c_str(), value.length()));
ASSERT_TRUE(ada_search_params_has_value(out, key.c_str(), key.length(),
value2.c_str(), value2.length()));

ada_strings result = ada_search_params_get_all(out, key.c_str(), key.length());
ASSERT_EQ(ada_strings_size(result), 1);
ada_strings_free(result);

ada_url_search_params_keys_iter keys = ada_search_params_get_keys(out);
ada_url_search_params_values_iter values = ada_search_params_get_values(out);
ada_url_search_params_entries_iter entries = ada_search_params_get_entries(out);

ASSERT_FALSE(ada_search_params_keys_iter_is_done(keys));
ASSERT_FALSE(ada_search_params_values_iter_is_done(values));
ASSERT_FALSE(ada_search_params_entries_iter_is_done(entries));

ASSERT_EQ(convert_string(ada_search_params_keys_iter_next(keys)), "a");
ASSERT_EQ(convert_string(ada_search_params_keys_iter_next(keys)), "c");
ASSERT_EQ(convert_string(ada_search_params_keys_iter_next(keys)), "c");
ASSERT_EQ(convert_string(ada_search_params_keys_iter_next(keys)), "f");
ASSERT_EQ(convert_string(ada_search_params_keys_iter_next(keys)), "key1");
ASSERT_TRUE(ada_search_params_keys_iter_is_done(keys));

ASSERT_EQ(convert_string(ada_search_params_values_iter_next(values)), "b");
ASSERT_EQ(convert_string(ada_search_params_values_iter_next(values)), "d");
ASSERT_EQ(convert_string(ada_search_params_values_iter_next(values)), "e");
ASSERT_EQ(convert_string(ada_search_params_values_iter_next(values)), "g");
ASSERT_EQ(convert_string(ada_search_params_values_iter_next(values)), "value2");
ASSERT_TRUE(ada_search_params_values_iter_is_done(values));

ada_string_pair pair = ada_search_params_entries_iter_next(entries);
ASSERT_EQ(convert_string(pair.value), "b");
ASSERT_EQ(convert_string(pair.key), "a");

pair = ada_search_params_entries_iter_next(entries);
ASSERT_EQ(convert_string(pair.value), "d");
ASSERT_EQ(convert_string(pair.key), "c");

while (!ada_search_params_entries_iter_is_done(entries)) {
ada_search_params_entries_iter_next(entries);
}

ada_search_params_remove(out, key.c_str(), key.length());
ada_search_params_remove_value(out, key.c_str(), key.length(), value.c_str(), value.length());

ASSERT_EQ(convert_string(ada_search_params_to_string(out)), "a=b&c=d&c=e&f=g");

ada_search_params_keys_iter_free(keys);
ada_search_params_values_iter_free(values);
ada_search_params_entries_iter_free(entries);
ada_search_params_free(out);

SUCCEED();
}

0 comments on commit 60579dd

Please sign in to comment.