Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions include/ada/url_search_params-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,19 @@ inline std::string url_search_params::to_string() const {
return out;
}

inline std::string url_search_params::to_raw_string() const {
std::string out{};
for (const auto &[key, value] : params) {
if (!out.empty()) {
out += "&";
}
out.append(key);
out += "=";
out.append(value);
}
return out;
}

inline void url_search_params::set(const std::string_view key,
const std::string_view value) {
const auto find = [&key](const auto &param) { return param.first == key; };
Expand Down
7 changes: 7 additions & 0 deletions include/ada/url_search_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ struct url_search_params {
*/
inline std::string to_string() const;

/**
* Returns a serialized query string without normalizing the key-value pairs.
* Unlike to_string(), this method does not apply additional transformations
* to the percent-encoded output.
*/
inline std::string to_raw_string() const;

/**
* Returns a simple JS-style iterator over all of the keys in this
* url_search_params. The keys in the iterator are not unique. The valid
Expand Down
1 change: 1 addition & 0 deletions include/ada_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ void ada_free_search_params(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);
ada_owned_string ada_search_params_to_raw_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,
Expand Down
12 changes: 12 additions & 0 deletions src/ada_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,18 @@ ada_owned_string ada_search_params_to_string(ada_url_search_params result) {
return owned;
}

ada_owned_string ada_search_params_to_raw_string(ada_url_search_params result) {
ada::result<ada::url_search_params>& r =
*(ada::result<ada::url_search_params>*)result;
if (!r) return ada_owned_string{nullptr, 0};
std::string out = r->to_raw_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;
Expand Down
42 changes: 42 additions & 0 deletions tests/ada_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,48 @@ TEST(ada_c, ada_url_search_params) {
SUCCEED();
}

TEST(ada_c, ada_search_params_to_raw_string) {
std::string input("a=b c&d=e+f");
auto out = ada_parse_search_params(input.c_str(), input.length());

// Note: + in input is decoded to space during parsing
// to_string normalizes spaces to +
ada_owned_string str = ada_search_params_to_string(out);
ASSERT_EQ(convert_string(str), "a=b+c&d=e+f");
ada_free_owned_string(str);

// to_raw_string outputs raw key/value without any encoding
ada_owned_string raw_str = ada_search_params_to_raw_string(out);
ASSERT_EQ(convert_string(raw_str), "a=b c&d=e f");
ada_free_owned_string(raw_str);

ada_free_search_params(out);

SUCCEED();
}

TEST(ada_c, ada_search_params_to_raw_string_remove) {
std::string input("a=%20&b=remove&c=2");
auto params = ada_parse_search_params(input.c_str(), input.length());

// Remove parameter "b"
ada_search_params_remove(params, "b", 1);

// to_string normalizes space to +
ada_owned_string str = ada_search_params_to_string(params);
ASSERT_EQ(convert_string(str), "a=+&c=2");
ada_free_owned_string(str);

// to_raw_string outputs raw key/value without any encoding
ada_owned_string raw_str = ada_search_params_to_raw_string(params);
ASSERT_EQ(convert_string(raw_str), "a= &c=2");
ada_free_owned_string(raw_str);

ada_free_search_params(params);

SUCCEED();
}

TEST(ada_c, ada_get_version) {
std::string_view raw = ada_get_version();
ada_version_components parsed = ada_get_version_components();
Expand Down
55 changes: 55 additions & 0 deletions tests/url_search_params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,3 +448,58 @@ TEST(url_search_params, sort_unicode_code_units_edge_case) {
ASSERT_EQ(keys.next(), "\xf0\x9f\x8c\x88\xef\xac\x83");
SUCCEED();
}

TEST(url_search_params, to_raw_string_no_normalization) {
auto params = ada::url_search_params();
params.append("a", "b c");
// to_string normalizes space to +
ASSERT_EQ(params.to_string(), "a=b+c");
// to_raw_string outputs raw key/value without any encoding
ASSERT_EQ(params.to_raw_string(), "a=b c");
SUCCEED();
}

TEST(url_search_params, to_raw_string_with_special_chars) {
auto params = ada::url_search_params();
params.append("key1", "value with spaces");
params.append("key2", "another value");
// to_string normalizes spaces to +
ASSERT_EQ(params.to_string(), "key1=value+with+spaces&key2=another+value");
// to_raw_string outputs raw key/value without any encoding
ASSERT_EQ(params.to_raw_string(),
"key1=value with spaces&key2=another value");
SUCCEED();
}

TEST(url_search_params, to_raw_string_with_accents) {
auto params = ada::url_search_params();
params.append("key1", "\u00E9t\u00E9");
params.append("key2", "C\u00E9line Dion++");
// to_string percent-encodes and normalizes spaces to +
ASSERT_EQ(params.to_string(),
"key1=%C3%A9t%C3%A9&key2=C%C3%A9line+Dion%2B%2B");
// to_raw_string outputs raw key/value without any encoding
ASSERT_EQ(params.to_raw_string(),
"key1=\u00E9t\u00E9&key2=C\u00E9line Dion++");
SUCCEED();
}

TEST(url_search_params, to_raw_string_empty_values) {
auto params = ada::url_search_params();
params.append("a", "");
params.append("", "b");
params.append("", "");
ASSERT_EQ(params.to_raw_string(), "a=&=b&=");
ASSERT_EQ(params.to_string(), "a=&=b&=");
SUCCEED();
}

TEST(url_search_params, with_ampersands) {
auto params = ada::url_search_params();
params.append("a", "&");
params.append("b", "?");
params.append("b", "+");
ASSERT_EQ(params.to_string(), "a=%26&b=%3F&b=%2B");
ASSERT_EQ(params.to_raw_string(), "a=&&b=?&b=+");
SUCCEED();
}
Loading