Skip to content

Commit 5d77089

Browse files
authored
Merge pull request #12 from TkTech/2.0.0
v2.0.0
2 parents be08bd7 + 7192c21 commit 5d77089

File tree

6 files changed

+163
-96
lines changed

6 files changed

+163
-96
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ jobs:
5050
fail-fast: true
5151
matrix:
5252
os: [ubuntu-22.04, windows-2022, macos-13]
53-
py: ["cp37", "cp38", "cp39", "cp310", "cp311", "cp312", "pp37", "pp38", "pp39"]
53+
py: ["cp39", "cp310", "cp311", "cp312", "cp313", "pp39", "pp310"]
5454

5555
steps:
5656
- uses: actions/[email protected]

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
fail-fast: false
1717
matrix:
1818
os: [ubuntu-22.04, macos-13, windows-2022]
19-
python-version: [3.7, 3.8, 3.9, "3.10", "3.11", "3.12"]
19+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
2020

2121
steps:
2222
- uses: actions/[email protected]

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,23 @@ url.search = "?q=canada&safe=off"
6060
print(url) # https://google.com/search?q=canada&safe=off
6161
```
6262

63+
`can_ada` also supports the `URLSearchParams` API:
64+
65+
```python
66+
from can_ada import URLSearchParams
67+
68+
params = URLSearchParams("q=canada&safe=off")
69+
params.append("page", "2")
70+
params.append("page", "3")
71+
params["q"] = "usa"
72+
print(params) # q=usa&safe=off&page=2&page=3
73+
print(params.has("q")) # True
74+
print(params.get("page")) # 2
75+
print(params.get_all("page")) # [2, 3]
76+
print(params.keys()) # ["q", "safe", "page"]
77+
print(params.values()) # ["usa", "off", "2", "3"]
78+
```
79+
6380
## Performance
6481

6582
We find that `can_ada` is typically ~4x faster than urllib:

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
]
3333
},
3434
zip_safe=False,
35-
python_requires=">=3.7",
35+
python_requires=">=3.9",
3636
)

src/ada.cpp

Lines changed: 83 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* auto-generated on 2024-06-18 17:01:23 -0400. Do not edit! */
1+
/* auto-generated on 2024-09-02 20:07:32 -0400. Do not edit! */
22
/* begin file src/ada.cpp */
33
#include "ada.h"
44
/* begin file src/checkers.cpp */
@@ -9795,6 +9795,10 @@ ADA_POP_DISABLE_WARNINGS
97959795

97969796
namespace ada::unicode {
97979797

9798+
constexpr bool is_tabs_or_newline(char c) noexcept {
9799+
return c == '\r' || c == '\n' || c == '\t';
9800+
}
9801+
97989802
constexpr uint64_t broadcast(uint8_t v) noexcept {
97999803
return 0x101010101010101ull * v;
98009804
}
@@ -9829,13 +9833,8 @@ ada_really_inline bool has_tabs_or_newline(
98299833
std::string_view user_input) noexcept {
98309834
// first check for short strings in which case we do it naively.
98319835
if (user_input.size() < 16) { // slow path
9832-
for (size_t i = 0; i < user_input.size(); i++) {
9833-
if (user_input[i] == '\r' || user_input[i] == '\n' ||
9834-
user_input[i] == '\t') {
9835-
return true;
9836-
}
9837-
}
9838-
return false;
9836+
return std::any_of(user_input.begin(), user_input.end(),
9837+
is_tabs_or_newline);
98399838
}
98409839
// fast path for long strings (expected to be common)
98419840
size_t i = 0;
@@ -9873,13 +9872,8 @@ ada_really_inline bool has_tabs_or_newline(
98739872
std::string_view user_input) noexcept {
98749873
// first check for short strings in which case we do it naively.
98759874
if (user_input.size() < 16) { // slow path
9876-
for (size_t i = 0; i < user_input.size(); i++) {
9877-
if (user_input[i] == '\r' || user_input[i] == '\n' ||
9878-
user_input[i] == '\t') {
9879-
return true;
9880-
}
9881-
}
9882-
return false;
9875+
return std::any_of(user_input.begin(), user_input.end(),
9876+
is_tabs_or_newline);
98839877
}
98849878
// fast path for long strings (expected to be common)
98859879
size_t i = 0;
@@ -10264,10 +10258,6 @@ std::string percent_encode(const std::string_view input,
1026410258
return out;
1026510259
}
1026610260

10267-
std::string to_unicode(std::string_view input) {
10268-
return ada::idna::to_unicode(input);
10269-
}
10270-
1027110261
} // namespace ada::unicode
1027210262
/* end file src/unicode.cpp */
1027310263
/* begin file src/serializers.cpp */
@@ -11563,21 +11553,21 @@ ada_really_inline bool url::parse_scheme(const std::string_view input) {
1156311553
// If url's scheme is not a special scheme and buffer is a special scheme,
1156411554
// then return.
1156511555
if (is_special() != is_input_special) {
11566-
return true;
11556+
return false;
1156711557
}
1156811558

1156911559
// If url includes credentials or has a non-null port, and buffer is
1157011560
// "file", then return.
1157111561
if ((has_credentials() || port.has_value()) &&
1157211562
parsed_type == ada::scheme::type::FILE) {
11573-
return true;
11563+
return false;
1157411564
}
1157511565

1157611566
// If url's scheme is "file" and its host is an empty host, then return.
1157711567
// An empty host is the empty string.
1157811568
if (type == ada::scheme::type::FILE && host.has_value() &&
1157911569
host.value().empty()) {
11580-
return true;
11570+
return false;
1158111571
}
1158211572
}
1158311573

@@ -12187,7 +12177,7 @@ result_type parse_url_impl(std::string_view user_input,
1218712177
if (!url.is_valid) {
1218812178
return url;
1218912179
}
12190-
if constexpr (result_type_is_ada_url_aggregator) {
12180+
if constexpr (result_type_is_ada_url_aggregator && store_values) {
1219112181
// Most of the time, we just need user_input.size().
1219212182
// In some instances, we may need a bit more.
1219312183
///////////////////////////
@@ -12204,9 +12194,6 @@ result_type parse_url_impl(std::string_view user_input,
1220412194
helpers::leading_zeroes(uint32_t(1 | user_input.size()))) +
1220512195
1;
1220612196
url.reserve(reserve_capacity);
12207-
//
12208-
//
12209-
//
1221012197
}
1221112198
std::string tmp_buffer;
1221212199
std::string_view internal_input;
@@ -12429,32 +12416,36 @@ result_type parse_url_impl(std::string_view user_input,
1242912416
password_token_seen =
1243012417
password_token_location != std::string_view::npos;
1243112418

12432-
if (!password_token_seen) {
12433-
if constexpr (result_type_is_ada_url) {
12434-
url.username += unicode::percent_encode(
12435-
authority_view, character_sets::USERINFO_PERCENT_ENCODE);
12436-
} else {
12437-
url.append_base_username(unicode::percent_encode(
12438-
authority_view, character_sets::USERINFO_PERCENT_ENCODE));
12439-
}
12440-
} else {
12441-
if constexpr (result_type_is_ada_url) {
12442-
url.username += unicode::percent_encode(
12443-
authority_view.substr(0, password_token_location),
12444-
character_sets::USERINFO_PERCENT_ENCODE);
12445-
url.password += unicode::percent_encode(
12446-
authority_view.substr(password_token_location + 1),
12447-
character_sets::USERINFO_PERCENT_ENCODE);
12419+
if constexpr (store_values) {
12420+
if (!password_token_seen) {
12421+
if constexpr (result_type_is_ada_url) {
12422+
url.username += unicode::percent_encode(
12423+
authority_view,
12424+
character_sets::USERINFO_PERCENT_ENCODE);
12425+
} else {
12426+
url.append_base_username(unicode::percent_encode(
12427+
authority_view,
12428+
character_sets::USERINFO_PERCENT_ENCODE));
12429+
}
1244812430
} else {
12449-
url.append_base_username(unicode::percent_encode(
12450-
authority_view.substr(0, password_token_location),
12451-
character_sets::USERINFO_PERCENT_ENCODE));
12452-
url.append_base_password(unicode::percent_encode(
12453-
authority_view.substr(password_token_location + 1),
12454-
character_sets::USERINFO_PERCENT_ENCODE));
12431+
if constexpr (result_type_is_ada_url) {
12432+
url.username += unicode::percent_encode(
12433+
authority_view.substr(0, password_token_location),
12434+
character_sets::USERINFO_PERCENT_ENCODE);
12435+
url.password += unicode::percent_encode(
12436+
authority_view.substr(password_token_location + 1),
12437+
character_sets::USERINFO_PERCENT_ENCODE);
12438+
} else {
12439+
url.append_base_username(unicode::percent_encode(
12440+
authority_view.substr(0, password_token_location),
12441+
character_sets::USERINFO_PERCENT_ENCODE));
12442+
url.append_base_password(unicode::percent_encode(
12443+
authority_view.substr(password_token_location + 1),
12444+
character_sets::USERINFO_PERCENT_ENCODE));
12445+
}
1245512446
}
1245612447
}
12457-
} else {
12448+
} else if constexpr (store_values) {
1245812449
if constexpr (result_type_is_ada_url) {
1245912450
url.password += unicode::percent_encode(
1246012451
authority_view, character_sets::USERINFO_PERCENT_ENCODE);
@@ -12481,8 +12472,10 @@ result_type parse_url_impl(std::string_view user_input,
1248112472
break;
1248212473
}
1248312474
if (end_of_authority == input_size) {
12484-
if (fragment.has_value()) {
12485-
url.update_unencoded_base_hash(*fragment);
12475+
if constexpr (store_values) {
12476+
if (fragment.has_value()) {
12477+
url.update_unencoded_base_hash(*fragment);
12478+
}
1248612479
}
1248712480
return url;
1248812481
}
@@ -12797,9 +12790,11 @@ result_type parse_url_impl(std::string_view user_input,
1279712790
// Optimization: Avoiding going into PATH state improves the
1279812791
// performance of urls ending with /.
1279912792
if (input_position == input_size) {
12800-
url.update_base_pathname("/");
12801-
if (fragment.has_value()) {
12802-
url.update_unencoded_base_hash(*fragment);
12793+
if constexpr (store_values) {
12794+
url.update_base_pathname("/");
12795+
if (fragment.has_value()) {
12796+
url.update_unencoded_base_hash(*fragment);
12797+
}
1280312798
}
1280412799
return url;
1280512800
}
@@ -13045,8 +13040,10 @@ result_type parse_url_impl(std::string_view user_input,
1304513040
ada::unreachable();
1304613041
}
1304713042
}
13048-
if (fragment.has_value()) {
13049-
url.update_unencoded_base_hash(*fragment);
13043+
if constexpr (store_values) {
13044+
if (fragment.has_value()) {
13045+
url.update_unencoded_base_hash(*fragment);
13046+
}
1305013047
}
1305113048
return url;
1305213049
}
@@ -13218,21 +13215,21 @@ template <bool has_state_override>
1321813215
// If url's scheme is not a special scheme and buffer is a special scheme,
1321913216
// then return.
1322013217
if (is_special() != is_input_special) {
13221-
return true;
13218+
return false;
1322213219
}
1322313220

1322413221
// If url includes credentials or has a non-null port, and buffer is
1322513222
// "file", then return.
1322613223
if ((has_credentials() || components.port != url_components::omitted) &&
1322713224
parsed_type == ada::scheme::type::FILE) {
13228-
return true;
13225+
return false;
1322913226
}
1323013227

1323113228
// If url's scheme is "file" and its host is an empty host, then return.
1323213229
// An empty host is the empty string.
1323313230
if (type == ada::scheme::type::FILE &&
1323413231
components.host_start == components.host_end) {
13235-
return true;
13232+
return false;
1323613233
}
1323713234
}
1323813235

@@ -13833,7 +13830,8 @@ bool url_aggregator::set_hostname(const std::string_view input) {
1383313830
return "null";
1383413831
}
1383513832

13836-
[[nodiscard]] std::string_view url_aggregator::get_username() const noexcept {
13833+
[[nodiscard]] std::string_view url_aggregator::get_username() const noexcept
13834+
ada_lifetime_bound {
1383713835
ada_log("url_aggregator::get_username");
1383813836
if (has_non_empty_username()) {
1383913837
return helpers::substring(buffer, components.protocol_end + 2,
@@ -13842,7 +13840,8 @@ bool url_aggregator::set_hostname(const std::string_view input) {
1384213840
return "";
1384313841
}
1384413842

13845-
[[nodiscard]] std::string_view url_aggregator::get_password() const noexcept {
13843+
[[nodiscard]] std::string_view url_aggregator::get_password() const noexcept
13844+
ada_lifetime_bound {
1384613845
ada_log("url_aggregator::get_password");
1384713846
if (has_non_empty_password()) {
1384813847
return helpers::substring(buffer, components.username_end + 1,
@@ -13851,7 +13850,8 @@ bool url_aggregator::set_hostname(const std::string_view input) {
1385113850
return "";
1385213851
}
1385313852

13854-
[[nodiscard]] std::string_view url_aggregator::get_port() const noexcept {
13853+
[[nodiscard]] std::string_view url_aggregator::get_port() const noexcept
13854+
ada_lifetime_bound {
1385513855
ada_log("url_aggregator::get_port");
1385613856
if (components.port == url_components::omitted) {
1385713857
return "";
@@ -13860,7 +13860,8 @@ bool url_aggregator::set_hostname(const std::string_view input) {
1386013860
components.pathname_start);
1386113861
}
1386213862

13863-
[[nodiscard]] std::string_view url_aggregator::get_hash() const noexcept {
13863+
[[nodiscard]] std::string_view url_aggregator::get_hash() const noexcept
13864+
ada_lifetime_bound {
1386413865
ada_log("url_aggregator::get_hash");
1386513866
// If this's URL's fragment is either null or the empty string, then return
1386613867
// the empty string. Return U+0023 (#), followed by this's URL's fragment.
@@ -13873,7 +13874,8 @@ bool url_aggregator::set_hostname(const std::string_view input) {
1387313874
return helpers::substring(buffer, components.hash_start);
1387413875
}
1387513876

13876-
[[nodiscard]] std::string_view url_aggregator::get_host() const noexcept {
13877+
[[nodiscard]] std::string_view url_aggregator::get_host() const noexcept
13878+
ada_lifetime_bound {
1387713879
ada_log("url_aggregator::get_host");
1387813880
// Technically, we should check if there is a hostname, but
1387913881
// the code below works even if there isn't.
@@ -13891,7 +13893,8 @@ bool url_aggregator::set_hostname(const std::string_view input) {
1389113893
return helpers::substring(buffer, start, components.pathname_start);
1389213894
}
1389313895

13894-
[[nodiscard]] std::string_view url_aggregator::get_hostname() const noexcept {
13896+
[[nodiscard]] std::string_view url_aggregator::get_hostname() const noexcept
13897+
ada_lifetime_bound {
1389513898
ada_log("url_aggregator::get_hostname");
1389613899
// Technically, we should check if there is a hostname, but
1389713900
// the code below works even if there isn't.
@@ -13905,7 +13908,8 @@ bool url_aggregator::set_hostname(const std::string_view input) {
1390513908
return helpers::substring(buffer, start, components.host_end);
1390613909
}
1390713910

13908-
[[nodiscard]] std::string_view url_aggregator::get_pathname() const noexcept {
13911+
[[nodiscard]] std::string_view url_aggregator::get_pathname() const noexcept
13912+
ada_lifetime_bound {
1390913913
ada_log("url_aggregator::get_pathname pathname_start = ",
1391013914
components.pathname_start, " buffer.size() = ", buffer.size(),
1391113915
" components.search_start = ", components.search_start,
@@ -13919,7 +13923,8 @@ bool url_aggregator::set_hostname(const std::string_view input) {
1391913923
return helpers::substring(buffer, components.pathname_start, ending_index);
1392013924
}
1392113925

13922-
[[nodiscard]] std::string_view url_aggregator::get_search() const noexcept {
13926+
[[nodiscard]] std::string_view url_aggregator::get_search() const noexcept
13927+
ada_lifetime_bound {
1392313928
ada_log("url_aggregator::get_search");
1392413929
// If this's URL's query is either null or the empty string, then return the
1392513930
// empty string. Return U+003F (?), followed by this's URL's query.
@@ -13936,7 +13941,8 @@ bool url_aggregator::set_hostname(const std::string_view input) {
1393613941
return helpers::substring(buffer, components.search_start, ending_index);
1393713942
}
1393813943

13939-
[[nodiscard]] std::string_view url_aggregator::get_protocol() const noexcept {
13944+
[[nodiscard]] std::string_view url_aggregator::get_protocol() const noexcept
13945+
ada_lifetime_bound {
1394013946
ada_log("url_aggregator::get_protocol");
1394113947
return helpers::substring(buffer, 0, components.protocol_end);
1394213948
}
@@ -15421,6 +15427,15 @@ void ada_search_params_sort(ada_url_search_params result) {
1542115427
}
1542215428
}
1542315429

15430+
void ada_search_params_reset(ada_url_search_params result, const char* input,
15431+
size_t length) {
15432+
ada::result<ada::url_search_params>& r =
15433+
*(ada::result<ada::url_search_params>*)result;
15434+
if (r) {
15435+
r->reset(std::string_view(input, length));
15436+
}
15437+
}
15438+
1542415439
void ada_search_params_append(ada_url_search_params result, const char* key,
1542515440
size_t key_length, const char* value,
1542615441
size_t value_length) {

0 commit comments

Comments
 (0)