Add ConstParser.
GitOrigin-RevId: 58ef5b7e6d2568729228c11a3a495794f98566ad
This commit is contained in:
parent
5ca0a72ddf
commit
84b33cd6a8
@ -375,7 +375,7 @@ static Status check_mtime(std::string &conversion, CSlice original_path) {
|
|||||||
if (original_path.empty()) {
|
if (original_path.empty()) {
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
Parser parser(conversion);
|
ConstParser parser(conversion);
|
||||||
if (!parser.skip_start_with("#mtime#")) {
|
if (!parser.skip_start_with("#mtime#")) {
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
@ -45,9 +45,9 @@ string HttpUrl::get_url() const {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<HttpUrl> parse_url(MutableSlice url, HttpUrl::Protocol default_protocol) {
|
Result<HttpUrl> parse_url(Slice url, HttpUrl::Protocol default_protocol) {
|
||||||
// url == [https?://][userinfo@]host[:port]
|
// url == [https?://][userinfo@]host[:port]
|
||||||
Parser parser(url);
|
ConstParser parser(url);
|
||||||
string protocol_str = to_lower(parser.read_till_nofail(':'));
|
string protocol_str = to_lower(parser.read_till_nofail(':'));
|
||||||
|
|
||||||
HttpUrl::Protocol protocol;
|
HttpUrl::Protocol protocol;
|
||||||
@ -61,7 +61,7 @@ Result<HttpUrl> parse_url(MutableSlice url, HttpUrl::Protocol default_protocol)
|
|||||||
return Status::Error("Unsupported URL protocol");
|
return Status::Error("Unsupported URL protocol");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
parser = Parser(url);
|
parser = ConstParser(url);
|
||||||
protocol = default_protocol;
|
protocol = default_protocol;
|
||||||
}
|
}
|
||||||
Slice userinfo_host_port = parser.read_till_nofail("/?#");
|
Slice userinfo_host_port = parser.read_till_nofail("/?#");
|
||||||
|
@ -36,8 +36,7 @@ class HttpUrl {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO Slice instead of MutableSlice
|
Result<HttpUrl> parse_url(Slice url,
|
||||||
Result<HttpUrl> parse_url(MutableSlice url,
|
|
||||||
HttpUrl::Protocol default_protocol = HttpUrl::Protocol::HTTP) TD_WARN_UNUSED_RESULT;
|
HttpUrl::Protocol default_protocol = HttpUrl::Protocol::HTTP) TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
StringBuilder &operator<<(StringBuilder &sb, const HttpUrl &url);
|
StringBuilder &operator<<(StringBuilder &sb, const HttpUrl &url);
|
||||||
|
@ -17,14 +17,17 @@
|
|||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
class Parser {
|
namespace detail {
|
||||||
|
|
||||||
|
template <class SliceT>
|
||||||
|
class ParserImpl {
|
||||||
public:
|
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();
|
other.clear();
|
||||||
}
|
}
|
||||||
Parser &operator=(Parser &&other) {
|
ParserImpl &operator=(ParserImpl &&other) {
|
||||||
if (&other == this) {
|
if (&other == this) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -34,9 +37,9 @@ class Parser {
|
|||||||
other.clear();
|
other.clear();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Parser(const Parser &) = delete;
|
ParserImpl(const ParserImpl &) = delete;
|
||||||
Parser &operator=(const Parser &) = delete;
|
ParserImpl &operator=(const ParserImpl &) = delete;
|
||||||
~Parser() = default;
|
~ParserImpl() = default;
|
||||||
|
|
||||||
bool empty() const {
|
bool empty() const {
|
||||||
return ptr_ == end_;
|
return ptr_ == end_;
|
||||||
@ -47,57 +50,57 @@ class Parser {
|
|||||||
status_ = Status::OK();
|
status_ = Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
MutableSlice read_till_nofail(char c) {
|
SliceT read_till_nofail(char c) {
|
||||||
if (status_.is_error()) {
|
if (status_.is_error()) {
|
||||||
return MutableSlice();
|
return SliceT();
|
||||||
}
|
}
|
||||||
char *till = static_cast<char *>(std::memchr(ptr_, c, end_ - ptr_));
|
auto till = static_cast<decltype(ptr_)>(std::memchr(ptr_, c, end_ - ptr_));
|
||||||
if (till == nullptr) {
|
if (till == nullptr) {
|
||||||
till = end_;
|
till = end_;
|
||||||
}
|
}
|
||||||
MutableSlice result(ptr_, till);
|
SliceT result(ptr_, till);
|
||||||
ptr_ = till;
|
ptr_ = till;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
MutableSlice read_till_nofail(Slice str) {
|
SliceT read_till_nofail(Slice str) {
|
||||||
if (status_.is_error()) {
|
if (status_.is_error()) {
|
||||||
return MutableSlice();
|
return SliceT();
|
||||||
}
|
}
|
||||||
char *best_till = end_;
|
auto best_till = end_;
|
||||||
for (auto c : str) {
|
for (auto c : str) {
|
||||||
char *till = static_cast<char *>(std::memchr(ptr_, c, end_ - ptr_));
|
auto till = static_cast<decltype(ptr_)>(std::memchr(ptr_, c, end_ - ptr_));
|
||||||
if (till != nullptr && till < best_till) {
|
if (till != nullptr && till < best_till) {
|
||||||
best_till = till;
|
best_till = till;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MutableSlice result(ptr_, best_till);
|
SliceT result(ptr_, best_till);
|
||||||
ptr_ = best_till;
|
ptr_ = best_till;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F>
|
template <class F>
|
||||||
MutableSlice read_while(const F &f) {
|
SliceT read_while(const F &f) {
|
||||||
auto save_ptr = ptr_;
|
auto save_ptr = ptr_;
|
||||||
while (ptr_ != end_ && f(*ptr_)) {
|
while (ptr_ != end_ && f(*ptr_)) {
|
||||||
ptr_++;
|
ptr_++;
|
||||||
}
|
}
|
||||||
return MutableSlice(save_ptr, ptr_);
|
return SliceT(save_ptr, ptr_);
|
||||||
}
|
}
|
||||||
MutableSlice read_all() {
|
SliceT read_all() {
|
||||||
auto save_ptr = ptr_;
|
auto save_ptr = ptr_;
|
||||||
ptr_ = end_;
|
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()) {
|
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) {
|
if (ptr_ == end_ || ptr_[0] != c) {
|
||||||
status_ = Status::Error(PSLICE() << "Read till " << tag("char", c) << " failed");
|
status_ = Status::Error(PSLICE() << "Read till " << tag("char", c) << " failed");
|
||||||
return MutableSlice();
|
return SliceT();
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -147,13 +150,13 @@ class Parser {
|
|||||||
void skip_whitespaces() {
|
void skip_whitespaces() {
|
||||||
skip_till_not(" \t\r\n");
|
skip_till_not(" \t\r\n");
|
||||||
}
|
}
|
||||||
MutableSlice read_word() {
|
SliceT read_word() {
|
||||||
skip_whitespaces();
|
skip_whitespaces();
|
||||||
return read_till_nofail(" \t\r\n");
|
return read_till_nofail(" \t\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
MutableSlice data() const {
|
SliceT data() const {
|
||||||
return MutableSlice(ptr_, end_);
|
return SliceT(ptr_, end_);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status &status() {
|
Status &status() {
|
||||||
@ -181,9 +184,14 @@ class Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char *ptr_;
|
decltype(std::declval<SliceT>().begin()) ptr_;
|
||||||
char *end_;
|
decltype(std::declval<SliceT>().end()) end_;
|
||||||
Status status_;
|
Status status_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
using Parser = detail::ParserImpl<MutableSlice>;
|
||||||
|
using ConstParser = detail::ParserImpl<Slice>;
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -100,7 +100,7 @@ class RegressionTesterImpl : public RegressionTester {
|
|||||||
|
|
||||||
Status load_db(CSlice path) {
|
Status load_db(CSlice path) {
|
||||||
TRY_RESULT(data, read_file(path));
|
TRY_RESULT(data, read_file(path));
|
||||||
Parser parser(data.as_slice());
|
ConstParser parser(data.as_slice());
|
||||||
auto db_magic = parser.read_word();
|
auto db_magic = parser.read_word();
|
||||||
if (db_magic != magic()) {
|
if (db_magic != magic()) {
|
||||||
return Status::Error(PSLICE() << "Wrong magic " << db_magic);
|
return Status::Error(PSLICE() << "Wrong magic " << db_magic);
|
||||||
|
Reference in New Issue
Block a user