diff --git a/include/ada_c.h b/include/ada_c.h index 040915518..fdceb99a3 100644 --- a/include/ada_c.h +++ b/include/ada_c.h @@ -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 diff --git a/src/ada_c.cpp b/src/ada_c.cpp index 664371baa..049856376 100644 --- a/src/ada_c.cpp +++ b/src/ada_c.cpp @@ -6,6 +6,11 @@ ada::result& 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; @@ -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; @@ -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(std::string_view(input, length))); +} + +void ada_search_params_free(ada_url_search_params result) { + ada::result* r = + (ada::result*)result; + delete r; +} + +ada_owned_string ada_search_params_to_string(ada_url_search_params result) { + ada::result& r = *(ada::result*)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& r = *(ada::result*)result; + return r->size(); +} + +void ada_search_params_sort(ada_url_search_params result) { + ada::result& r = *(ada::result*)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& r = *(ada::result*)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& r = *(ada::result*)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& r = *(ada::result*)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& r = *(ada::result*)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& r = *(ada::result*)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& r = *(ada::result*)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& r = *(ada::result*)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& r = *(ada::result*)result; + return new ada::result>(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& r = *(ada::result*)result; + return new ada::result(r->get_keys()); +} + +ada_url_search_params_values_iter ada_search_params_get_values(ada_url_search_params result) { + ada::result& r = *(ada::result*)result; + return new ada::result(r->get_values()); +} + +ada_url_search_params_entries_iter ada_search_params_get_entries(ada_url_search_params result) { + ada::result& r = *(ada::result*)result; + return new ada::result(r->get_entries()); +} + +void ada_strings_free(ada_strings result) { + ada::result>* r = + (ada::result>*)result; + delete r; +} + +size_t ada_strings_size(ada_strings result) { + ada::result>* r = + (ada::result>*)result; + return (*r)->size(); +} + +ada_string ada_strings_get(ada_strings result, size_t index) { + ada::result>* r = + (ada::result>*)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* r = + (ada::result*)result; + delete r; +} + +ada_string ada_search_params_keys_iter_next(ada_url_search_params_keys_iter result) { + ada::result* r = + (ada::result*)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* r = + (ada::result*)result; + return (*r)->is_done(); +} + +void ada_search_params_values_iter_free(ada_url_search_params_values_iter result) { + ada::result* r = + (ada::result*)result; + delete r; +} + +ada_string ada_search_params_values_iter_next(ada_url_search_params_values_iter result) { + ada::result* r = + (ada::result*)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* r = + (ada::result*)result; + return (*r)->is_done(); +} + +void ada_search_params_entries_iter_free(ada_url_search_params_entries_iter result) { + ada::result* r = + (ada::result*)result; + delete r; +} + +ada_string_pair ada_search_params_entries_iter_next(ada_url_search_params_entries_iter result) { + ada::result* r = + (ada::result*)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* r = + (ada::result*)result; + return (*r)->is_done(); +} + } // extern "C" diff --git a/tests/ada_c.cpp b/tests/ada_c.cpp index c1208fdc0..8127fee4a 100644 --- a/tests/ada_c.cpp +++ b/tests/ada_c.cpp @@ -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(); +}