1
- /* auto-generated on 2023-02-07 17:26:54 -0500. Do not edit! */
1
+ /* auto-generated on 2023-02-22 14:24:01 -0500. Do not edit! */
2
2
// dofile: invoked with prepath=/Users/yagiz/Developer/url-parser/src, filename=ada.cpp
3
3
/* begin file src/ada.cpp */
4
4
#include " ada.h"
@@ -635,33 +635,37 @@ namespace ada::serializers {
635
635
}
636
636
637
637
std::string ipv6 (const std::array<uint16_t , 8 >& address) noexcept {
638
- size_t compress_length = 0 ;
639
- size_t compress = 0 ;
638
+ size_t compress_length = 0 ; // The length of a long sequence of zeros.
639
+ size_t compress = 0 ; // The start of a long sequence of zeros.
640
640
find_longest_sequence_of_ipv6_pieces (address, compress, compress_length);
641
641
642
642
if (compress_length <= 1 ) {
643
643
// Optimization opportunity: Find a faster way then snprintf for imploding and return here.
644
644
compress = compress_length = 8 ;
645
645
}
646
646
647
- std::string output{} ;
647
+ std::string output ( 4 * 8 + 7 + 2 , ' \0 ' ) ;
648
648
size_t piece_index = 0 ;
649
- char buf[5 ];
650
-
649
+ char *point = output.data ();
650
+ char *point_end = output.data () + output.size ();
651
+ *point++ = ' [' ;
651
652
while (true ) {
652
653
if (piece_index == compress) {
653
- output.append (" ::" , piece_index == 0 ? 2 : 1 );
654
- if ((piece_index = piece_index + compress_length) == 8 ) break ;
654
+ *point++ = ' :' ;
655
+ // If we skip a value initially, we need to write '::', otherwise
656
+ // a single ':' will do since it follows a previous ':'.
657
+ if (piece_index == 0 ) { *point++ = ' :' ; }
658
+ piece_index += compress_length;
659
+ if (piece_index == 8 ) { break ; }
655
660
}
656
-
657
- // Optimization opportunity: Get rid of snprintf.
658
- snprintf (buf, 5 , " %x" , address[piece_index]);
659
- output += buf;
660
- if (++piece_index == 8 ) break ;
661
- output.push_back (' :' );
661
+ point = std::to_chars (point, point_end, address[piece_index], 16 ).ptr ;
662
+ piece_index++;
663
+ if (piece_index == 8 ) { break ; }
664
+ *point++ = ' :' ;
662
665
}
663
-
664
- return " [" + output + " ]" ;
666
+ *point++ = ' ]' ;
667
+ output.resize (point - output.data ());
668
+ return output;
665
669
}
666
670
667
671
std::string ipv4 (const uint64_t address) noexcept {
@@ -1651,7 +1655,16 @@ namespace ada {
1651
1655
if (trimmed.empty ()) { port = std::nullopt; return true ; }
1652
1656
// Input should not start with control characters.
1653
1657
if (ada::unicode::is_c0_control_or_space (trimmed.front ())) { return false ; }
1654
- return parse_port (trimmed);
1658
+ // Input should contain at least one ascii digit.
1659
+ if (input.find_first_of (" 0123456789" ) == std::string_view::npos) { return false ; }
1660
+
1661
+ // Revert changes if parse_port fails.
1662
+ std::optional<uint16_t > previous_port = port;
1663
+ parse_port (trimmed);
1664
+ if (is_valid) { return true ; }
1665
+ port = previous_port;
1666
+ is_valid = true ;
1667
+ return false ;
1655
1668
}
1656
1669
1657
1670
void url::set_hash (const std::string_view input) {
@@ -1692,7 +1705,7 @@ namespace ada {
1692
1705
return parse_path (input);
1693
1706
}
1694
1707
1695
- bool url::set_host (const std::string_view input) {
1708
+ bool url::set_host_or_hostname (const std::string_view input, bool override_hostname ) {
1696
1709
if (has_opaque_path) { return false ; }
1697
1710
1698
1711
std::optional<std::string> previous_host = host;
@@ -1713,7 +1726,7 @@ namespace ada {
1713
1726
// Otherwise, if c is U+003A (:) and insideBrackets is false, then:
1714
1727
// Note: we cannot access *pointer safely if (pointer == pointer_end).
1715
1728
if ((pointer != new_host.end ()) && (*pointer == ' :' ) && !inside_brackets) {
1716
- // TODO: The next 2 lines is the only difference between set_host and set_hostname. Let's simplify it.
1729
+ if (override_hostname) { return false ; }
1717
1730
std::string_view buffer (&*(pointer + 1 ));
1718
1731
if (!buffer.empty ()) { set_port (buffer); }
1719
1732
}
@@ -1761,70 +1774,12 @@ namespace ada {
1761
1774
return true ;
1762
1775
}
1763
1776
1764
- bool url::set_hostname (const std::string_view input) {
1765
- if (has_opaque_path) { return false ; }
1766
-
1767
- std::optional<std::string> previous_host = host;
1768
-
1769
- std::string_view::iterator input_pointer_end = std::find (input.begin (), input.end (), ' #' );
1770
- std::string _host (input.data (), std::distance (input.begin (), input_pointer_end));
1771
- helpers::remove_ascii_tab_or_newline (_host);
1772
- std::string_view new_host (_host);
1773
-
1774
- // If url's scheme is "file", then set state to file host state, instead of host state.
1775
- if (get_scheme_type () != ada::scheme::type::FILE) {
1776
- std::string_view host_view (_host.data (), _host.length ());
1777
- bool inside_brackets{false };
1778
- size_t location = helpers::get_host_delimiter_location (*this , host_view, inside_brackets);
1779
- std::string_view::iterator pointer = (location != std::string_view::npos) ? new_host.begin () + location : new_host.end ();
1780
-
1781
- // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
1782
- // Note: we cannot access *pointer safely if (pointer == pointer_end).
1783
- if ((pointer != new_host.end ()) && (*pointer == ' :' ) && !inside_brackets) {
1784
- // If buffer is the empty string, validation error, return failure.
1785
- return false ;
1786
- }
1787
- // If url is special and host_view is the empty string, validation error, return failure.
1788
- else if (host_view.empty () && is_special ()) {
1789
- return false ;
1790
- }
1791
- // Otherwise, if state override is given, host_view is the empty string,
1792
- // and either url includes credentials or url’s port is non-null, return.
1793
- else if (host_view.empty () && (includes_credentials () || port.has_value ())) {
1794
- return true ;
1795
- }
1796
-
1797
- // Let host be the result of host parsing host_view with url is not special.
1798
- if (host_view.empty ()) {
1799
- host = " " ;
1800
- return true ;
1801
- }
1802
-
1803
- bool succeeded = parse_host (host_view);
1804
- if (!succeeded) { host = previous_host; }
1805
- return succeeded;
1806
- }
1807
-
1808
- size_t location = new_host.find_first_of (" /\\ ?" );
1809
- if (location != std::string_view::npos) { new_host.remove_suffix (new_host.length () - location); }
1810
-
1811
- if (new_host.empty ()) {
1812
- // Set url’s host to the empty string.
1813
- host = " " ;
1814
- }
1815
- else {
1816
- // Let host be the result of host parsing buffer with url is not special.
1817
- if (!parse_host (new_host)) {
1818
- host = previous_host;
1819
- return false ;
1820
- }
1777
+ bool url::set_host (const std::string_view input) {
1778
+ return set_host_or_hostname (input, false );
1779
+ }
1821
1780
1822
- // If host is "localhost", then set host to the empty string.
1823
- if (host.has_value () && host.value () == " localhost" ) {
1824
- host = " " ;
1825
- }
1826
- }
1827
- return true ;
1781
+ bool url::set_hostname (const std::string_view input) {
1782
+ return set_host_or_hostname (input, true );
1828
1783
}
1829
1784
1830
1785
bool url::set_protocol (const std::string_view input) {
@@ -1849,15 +1804,16 @@ namespace ada {
1849
1804
ada::result out = ada::parse (input);
1850
1805
1851
1806
if (out) {
1852
- set_protocol (out->get_protocol ());
1853
- set_username (out->get_username ());
1854
- set_password (out->get_password ());
1855
- set_host (out->get_host ());
1856
- set_hostname (out->get_hostname ());
1857
- set_port (out->get_port ());
1858
- set_pathname (out->get_pathname ());
1859
- set_hash (out->get_hash ());
1860
- set_search (out->get_search ());
1807
+ username = out->username ;
1808
+ password = out->password ;
1809
+ host = out->host ;
1810
+ port = out->port ;
1811
+ path = out->path ;
1812
+ query = out->query ;
1813
+ fragment = out->fragment ;
1814
+ type = out->type ;
1815
+ non_special_scheme = out->non_special_scheme ;
1816
+ has_opaque_path = out->has_opaque_path ;
1861
1817
}
1862
1818
1863
1819
return out.has_value ();
@@ -1989,7 +1945,8 @@ namespace ada::parser {
1989
1945
case ada::state::NO_SCHEME: {
1990
1946
ada_log (" NO_SCHEME " , helpers::substring (url_data, input_position));
1991
1947
// If base is null, or base has an opaque path and c is not U+0023 (#), validation error, return failure.
1992
- if (base_url == nullptr || (base_url->has_opaque_path && (input_position != input_size))) {
1948
+ // SCHEME state updates the state to NO_SCHEME and validates url_data is not empty.
1949
+ if (base_url == nullptr || (base_url->has_opaque_path && url_data[input_position] != ' #' )) {
1993
1950
ada_log (" NO_SCHEME validation error" );
1994
1951
url.is_valid = false ;
1995
1952
return url;
0 commit comments