diff --git a/td/telegram/files/FileGenerateManager.cpp b/td/telegram/files/FileGenerateManager.cpp index 7a75496b..e94933aa 100644 --- a/td/telegram/files/FileGenerateManager.cpp +++ b/td/telegram/files/FileGenerateManager.cpp @@ -375,7 +375,7 @@ static Status check_mtime(std::string &conversion, CSlice original_path) { if (original_path.empty()) { return Status::OK(); } - Parser parser(conversion); + ConstParser parser(conversion); if (!parser.skip_start_with("#mtime#")) { return Status::OK(); } diff --git a/tdutils/td/utils/HttpUrl.cpp b/tdutils/td/utils/HttpUrl.cpp index 1a71549c..b21314bf 100644 --- a/tdutils/td/utils/HttpUrl.cpp +++ b/tdutils/td/utils/HttpUrl.cpp @@ -45,9 +45,9 @@ string HttpUrl::get_url() const { return result; } -Result parse_url(MutableSlice url, HttpUrl::Protocol default_protocol) { +Result parse_url(Slice url, HttpUrl::Protocol default_protocol) { // url == [https?://][userinfo@]host[:port] - Parser parser(url); + ConstParser parser(url); string protocol_str = to_lower(parser.read_till_nofail(':')); HttpUrl::Protocol protocol; @@ -61,7 +61,7 @@ Result parse_url(MutableSlice url, HttpUrl::Protocol default_protocol) return Status::Error("Unsupported URL protocol"); } } else { - parser = Parser(url); + parser = ConstParser(url); protocol = default_protocol; } Slice userinfo_host_port = parser.read_till_nofail("/?#"); diff --git a/tdutils/td/utils/HttpUrl.h b/tdutils/td/utils/HttpUrl.h index 4cff1e6b..f265f95b 100644 --- a/tdutils/td/utils/HttpUrl.h +++ b/tdutils/td/utils/HttpUrl.h @@ -36,8 +36,7 @@ class HttpUrl { } }; -// TODO Slice instead of MutableSlice -Result parse_url(MutableSlice url, +Result parse_url(Slice url, HttpUrl::Protocol default_protocol = HttpUrl::Protocol::HTTP) TD_WARN_UNUSED_RESULT; StringBuilder &operator<<(StringBuilder &sb, const HttpUrl &url); diff --git a/tdutils/td/utils/Parser.h b/tdutils/td/utils/Parser.h index 5d10849b..d783b22d 100644 --- a/tdutils/td/utils/Parser.h +++ b/tdutils/td/utils/Parser.h @@ -17,14 +17,17 @@ namespace td { -class Parser { +namespace detail { + +template +class ParserImpl { public: - explicit Parser(MutableSlice data) : ptr_(data.begin()), end_(data.end()), status_() { + explicit ParserImpl(SliceT data) : ptr_(data.begin()), end_(data.end()), status_() { } - Parser(Parser &&other) : ptr_(other.ptr_), end_(other.end_), status_(std::move(other.status_)) { + ParserImpl(ParserImpl &&other) : ptr_(other.ptr_), end_(other.end_), status_(std::move(other.status_)) { other.clear(); } - Parser &operator=(Parser &&other) { + ParserImpl &operator=(ParserImpl &&other) { if (&other == this) { return *this; } @@ -34,9 +37,9 @@ class Parser { other.clear(); return *this; } - Parser(const Parser &) = delete; - Parser &operator=(const Parser &) = delete; - ~Parser() = default; + ParserImpl(const ParserImpl &) = delete; + ParserImpl &operator=(const ParserImpl &) = delete; + ~ParserImpl() = default; bool empty() const { return ptr_ == end_; @@ -47,57 +50,57 @@ class Parser { status_ = Status::OK(); } - MutableSlice read_till_nofail(char c) { + SliceT read_till_nofail(char c) { if (status_.is_error()) { - return MutableSlice(); + return SliceT(); } - char *till = static_cast(std::memchr(ptr_, c, end_ - ptr_)); + auto till = static_cast(std::memchr(ptr_, c, end_ - ptr_)); if (till == nullptr) { till = end_; } - MutableSlice result(ptr_, till); + SliceT result(ptr_, till); ptr_ = till; return result; } - MutableSlice read_till_nofail(Slice str) { + SliceT read_till_nofail(Slice str) { if (status_.is_error()) { - return MutableSlice(); + return SliceT(); } - char *best_till = end_; + auto best_till = end_; for (auto c : str) { - char *till = static_cast(std::memchr(ptr_, c, end_ - ptr_)); + auto till = static_cast(std::memchr(ptr_, c, end_ - ptr_)); if (till != nullptr && till < best_till) { best_till = till; } } - MutableSlice result(ptr_, best_till); + SliceT result(ptr_, best_till); ptr_ = best_till; return result; } template - MutableSlice read_while(const F &f) { + SliceT read_while(const F &f) { auto save_ptr = ptr_; while (ptr_ != end_ && f(*ptr_)) { ptr_++; } - return MutableSlice(save_ptr, ptr_); + return SliceT(save_ptr, ptr_); } - MutableSlice read_all() { + SliceT read_all() { auto save_ptr = ptr_; ptr_ = end_; - return MutableSlice(save_ptr, ptr_); + return SliceT(save_ptr, ptr_); } - MutableSlice read_till(char c) { + SliceT read_till(char c) { if (status_.is_error()) { - return MutableSlice(); + return SliceT(); } - MutableSlice res = read_till_nofail(c); + SliceT res = read_till_nofail(c); if (ptr_ == end_ || ptr_[0] != c) { status_ = Status::Error(PSLICE() << "Read till " << tag("char", c) << " failed"); - return MutableSlice(); + return SliceT(); } return res; } @@ -147,13 +150,13 @@ class Parser { void skip_whitespaces() { skip_till_not(" \t\r\n"); } - MutableSlice read_word() { + SliceT read_word() { skip_whitespaces(); return read_till_nofail(" \t\r\n"); } - MutableSlice data() const { - return MutableSlice(ptr_, end_); + SliceT data() const { + return SliceT(ptr_, end_); } Status &status() { @@ -181,9 +184,14 @@ class Parser { } private: - char *ptr_; - char *end_; + decltype(std::declval().begin()) ptr_; + decltype(std::declval().end()) end_; Status status_; }; +} // namespace detail + +using Parser = detail::ParserImpl; +using ConstParser = detail::ParserImpl; + } // namespace td diff --git a/tdutils/td/utils/tests.cpp b/tdutils/td/utils/tests.cpp index 7980f07c..31accc81 100644 --- a/tdutils/td/utils/tests.cpp +++ b/tdutils/td/utils/tests.cpp @@ -100,7 +100,7 @@ class RegressionTesterImpl : public RegressionTester { Status load_db(CSlice path) { TRY_RESULT(data, read_file(path)); - Parser parser(data.as_slice()); + ConstParser parser(data.as_slice()); auto db_magic = parser.read_word(); if (db_magic != magic()) { return Status::Error(PSLICE() << "Wrong magic " << db_magic);