// // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once #include "td/utils/Slice-decl.h" #include "td/utils/logging.h" #include namespace td { /*** MutableSlice ***/ inline MutableSlice::MutableSlice() : MutableSlice(const_cast(""), static_cast(0)) { } inline MutableSlice::MutableSlice(char *s, size_t len) : s_(s), len_(len) { CHECK(s_ != nullptr); } inline MutableSlice::MutableSlice(unsigned char *s, size_t len) : s_(reinterpret_cast(s)), len_(len) { CHECK(s_ != nullptr); } inline MutableSlice::MutableSlice(string &s) : MutableSlice(&s[0], s.size()) { } inline MutableSlice::MutableSlice(char *s, char *t) : MutableSlice(s, t - s) { } inline MutableSlice::MutableSlice(unsigned char *s, unsigned char *t) : MutableSlice(s, t - s) { } inline size_t MutableSlice::size() const { return len_; } inline MutableSlice &MutableSlice::remove_prefix(size_t prefix_len) { CHECK(prefix_len <= len_); s_ += prefix_len; len_ -= prefix_len; return *this; } inline MutableSlice &MutableSlice::remove_suffix(size_t suffix_len) { CHECK(suffix_len <= len_); len_ -= suffix_len; return *this; } inline MutableSlice &MutableSlice::truncate(size_t size) { if (len_ > size) { len_ = size; } return *this; } inline MutableSlice MutableSlice::copy() const { return *this; } inline bool MutableSlice::empty() const { return len_ == 0; } inline char *MutableSlice::data() const { return s_; } inline char *MutableSlice::begin() const { return s_; } inline unsigned char *MutableSlice::ubegin() const { return reinterpret_cast(s_); } inline char *MutableSlice::end() const { return s_ + len_; } inline unsigned char *MutableSlice::uend() const { return reinterpret_cast(s_) + len_; } inline string MutableSlice::str() const { return string(begin(), size()); } inline MutableSlice MutableSlice::substr(size_t from) const { CHECK(from <= len_); return MutableSlice(s_ + from, len_ - from); } inline MutableSlice MutableSlice::substr(size_t from, size_t size) const { CHECK(from <= len_); return MutableSlice(s_ + from, min(size, len_ - from)); } inline size_t MutableSlice::find(char c) const { for (size_t pos = 0; pos < len_; pos++) { if (s_[pos] == c) { return pos; } } return static_cast(-1); } inline size_t MutableSlice::rfind(char c) const { for (size_t pos = len_; pos-- > 0;) { if (s_[pos] == c) { return pos; } } return static_cast(-1); } inline void MutableSlice::copy_from(Slice from) { CHECK(size() >= from.size()); std::memcpy(ubegin(), from.ubegin(), from.size()); } inline char &MutableSlice::back() { CHECK(1 <= len_); return s_[len_ - 1]; } inline char &MutableSlice::operator[](size_t i) { return s_[i]; } /*** Slice ***/ inline Slice::Slice() : Slice("", static_cast(0)) { } inline Slice::Slice(const MutableSlice &other) : Slice(other.begin(), other.size()) { } inline Slice::Slice(const char *s, size_t len) : s_(s), len_(len) { CHECK(s_ != nullptr); } inline Slice::Slice(const unsigned char *s, size_t len) : s_(reinterpret_cast(s)), len_(len) { CHECK(s_ != nullptr); } inline Slice::Slice(const string &s) : Slice(s.c_str(), s.size()) { } inline Slice::Slice(const char *s, const char *t) : Slice(s, t - s) { } inline Slice::Slice(const unsigned char *s, const unsigned char *t) : Slice(s, t - s) { } inline size_t Slice::size() const { return len_; } inline Slice &Slice::remove_prefix(size_t prefix_len) { CHECK(prefix_len <= len_); s_ += prefix_len; len_ -= prefix_len; return *this; } inline Slice &Slice::remove_suffix(size_t suffix_len) { CHECK(suffix_len <= len_); len_ -= suffix_len; return *this; } inline Slice &Slice::truncate(size_t size) { if (len_ > size) { len_ = size; } return *this; } inline Slice Slice::copy() const { return *this; } inline bool Slice::empty() const { return len_ == 0; } inline const char *Slice::data() const { return s_; } inline const char *Slice::begin() const { return s_; } inline const unsigned char *Slice::ubegin() const { return reinterpret_cast(s_); } inline const char *Slice::end() const { return s_ + len_; } inline const unsigned char *Slice::uend() const { return reinterpret_cast(s_) + len_; } inline string Slice::str() const { return string(begin(), size()); } inline Slice Slice::substr(size_t from) const { CHECK(from <= len_); return Slice(s_ + from, len_ - from); } inline Slice Slice::substr(size_t from, size_t size) const { CHECK(from <= len_); return Slice(s_ + from, min(size, len_ - from)); } inline size_t Slice::find(char c) const { for (size_t pos = 0; pos < len_; pos++) { if (s_[pos] == c) { return pos; } } return static_cast(-1); } inline size_t Slice::rfind(char c) const { for (size_t pos = len_; pos-- > 0;) { if (s_[pos] == c) { return pos; } } return static_cast(-1); } inline char Slice::back() const { CHECK(1 <= len_); return s_[len_ - 1]; } inline char Slice::operator[](size_t i) const { return s_[i]; } inline bool operator==(const Slice &a, const Slice &b) { return a.size() == b.size() && std::memcmp(a.data(), b.data(), a.size()) == 0; } inline bool operator!=(const Slice &a, const Slice &b) { return !(a == b); } inline MutableCSlice::MutableCSlice(char *s, char *t) : MutableSlice(s, t) { CHECK(*t == '\0'); } inline CSlice::CSlice(const char *s, const char *t) : Slice(s, t) { CHECK(*t == '\0'); } inline std::size_t SliceHash::operator()(Slice slice) const { // simple string hash std::size_t result = 0; constexpr std::size_t MUL = 123456789; for (auto c : slice) { result = result * MUL + c; } return result; } } // namespace td