Fixed the permfind command

This commit is contained in:
WolverinDEV 2020-04-02 14:10:32 +02:00
parent 889477c646
commit c879f3b776

View File

@ -156,6 +156,66 @@ namespace ts {
std::vector<std::string_view> flags{}; std::vector<std::string_view> flags{};
}; };
class command_builder_bulk {
template <typename vector_t>
friend class command_builder_impl;
public:
inline void put(const std::string_view& key, const std::string_view& value) {
size_t begin, end;
if(impl::value_raw_impl(this->bulk, key, begin, &end)) {
std::string result{};
result.reserve(this->bulk.size());
result.append(this->bulk, 0, begin - key.size() - 1); /* key incl = */
result.append(this->bulk, end + 1); /* get rid of the space */
this->bulk = result;
}
this->impl_put_unchecked(key, value);
}
template <typename T, std::enable_if_t<!(std::is_same<T, std::string_view>::value || std::is_same<T, std::string>::value), int> = 1>
inline void put(const std::string_view& key, const T& value) {
static_assert(converter<T>::supported, "Target type isn't supported!");
static_assert(!converter<T>::supported || converter<T>::to_string, "Target type dosn't support building");
auto data = converter<T>::to_string(value);
this->put(key, std::string_view{data});
}
/* directly puts data without checking for duplicates */
inline void put_unchecked(const std::string_view& key, const std::string_view& value) {
this->impl_put_unchecked(key, value);
}
inline void put_unchecked(const std::string_view& key, const std::string& value) {
this->put_unchecked(key, std::string_view{value});
}
template <typename T, std::enable_if_t<!(std::is_same<T, std::string_view>::value || std::is_same<T, std::string>::value), int> = 1>
inline void put_unchecked(const std::string_view& key, const T& value) {
static_assert(converter<T>::supported, "Target type isn't supported!");
static_assert(!converter<T>::supported || converter<T>::to_string, "Target type dosn't support building");
auto data = converter<T>::to_string(value);
this->put_unchecked(key, std::string_view{data});
}
private:
bool& flag_changed;
std::string& bulk;
explicit command_builder_bulk(bool& change_flag, std::string& bulk) : flag_changed{change_flag}, bulk{bulk} {}
void impl_put_unchecked(const std::string_view& key, const std::string_view& value) {
auto escaped_value = ts::query::escape(std::string{value});
this->bulk.reserve(this->bulk.length() + key.size() + escaped_value.size() + 2);
this->bulk.append(key);
if(!escaped_value.empty()) {
this->bulk.append("=");
this->bulk.append(escaped_value);
}
this->bulk.append(" ");
this->flag_changed = true;
}
};
template <typename vector_t = std::vector<std::string>> template <typename vector_t = std::vector<std::string>>
class command_builder_impl { class command_builder_impl {
public: public:
@ -169,7 +229,7 @@ namespace ts {
} }
inline std::string build(bool with_empty = false) const { inline std::string build(bool with_empty = false) const {
if(this->builded.has_value()) if(this->builded.has_value() && !this->flag_changed)
return this->builded.value(); return this->builded.value();
std::string result{}; std::string result{};
@ -189,74 +249,35 @@ namespace ts {
this->builded = result.substr(0, result.length() - 1); this->builded = result.substr(0, result.length() - 1);
else else
this->builded = result; this->builded = result;
this->flag_changed = false;
return this->builded.value(); return this->builded.value();
} }
inline void reserve_bulks(size_t count) { this->bulks.reserve(count); } inline void reserve_bulks(size_t count) { this->bulks.reserve(count); }
inline void put(size_t index, const std::string_view& key, const std::string_view& value) { [[nodiscard]] inline command_builder_bulk bulk(size_t index) {
while(this->bulks.size() <= index) while(this->bulks.size() <= index)
this->bulks.emplace_back("").reserve(expected_bulk_size); this->bulks.emplace_back("").reserve(expected_bulk_size);
auto& data = this->bulks[index]; return command_builder_bulk{this->flag_changed, this->bulks[index]};
size_t begin, end;
if(impl::value_raw_impl(data, key, begin, &end)) {
std::string result{};
result.reserve(data.size());
result.append(data, 0, begin - key.size() - 1); /* key incl = */
result.append(data, end + 1); /* get rid of the space */
data = result;
}
this->impl_put_unchecked(data, index, key, value);
} }
template <typename T, std::enable_if_t<!(std::is_same<T, std::string_view>::value || std::is_same<T, std::string>::value), int> = 1> template <typename T>
inline void put(size_t index, const std::string_view& key, const T& value) { inline void put(size_t index, const std::string_view& key, const T& value) {
static_assert(converter<T>::supported, "Target type isn't supported!"); this->bulk(index).put(key, value);
static_assert(!converter<T>::supported || converter<T>::to_string, "Target type dosn't support building");
auto data = converter<T>::to_string(value);
this->put(index, key, std::string_view{data});
} }
/* directly puts data without checking for duplicates */ /* directly puts data without checking for duplicates */
inline void put_unchecked(size_t index, const std::string_view& key, const std::string_view& value) { template <typename T>
while(this->bulks.size() <= index)
this->bulks.emplace_back("").reserve(expected_bulk_size);
this->impl_put_unchecked(this->bulks[index], index, key, value);
}
inline void put_unchecked(size_t index, const std::string_view& key, const std::string& value) {
this->put_unchecked(index, key, std::string_view{value});
}
template <typename T, std::enable_if_t<!(std::is_same<T, std::string_view>::value || std::is_same<T, std::string>::value), int> = 1>
inline void put_unchecked(size_t index, const std::string_view& key, const T& value) { inline void put_unchecked(size_t index, const std::string_view& key, const T& value) {
static_assert(converter<T>::supported, "Target type isn't supported!"); this->bulk(index).put_unchecked(key, value);
static_assert(!converter<T>::supported || converter<T>::to_string, "Target type dosn't support building");
auto data = converter<T>::to_string(value);
this->put_unchecked(index, key, std::string_view{data});
} }
private: private:
command_builder_impl(size_t expected, size_t identifier, typename vector_t::iterator begin, typename vector_t::iterator end) : expected_bulk_size{expected}, _identifier{identifier}, bulks{begin, end} {} command_builder_impl(size_t expected, std::string identifier, typename vector_t::iterator begin, typename vector_t::iterator end) : expected_bulk_size{expected}, _identifier{std::move(identifier)}, bulks{begin, end} {}
void impl_put_unchecked(std::string& data, size_t index, const std::string_view& key, const std::string_view& value) {
auto escaped_value = ts::query::escape(std::string{value});
data.reserve(data.length() + key.size() + escaped_value.size() + 2);
data.append(key);
if(!escaped_value.empty()) {
data.append("=");
data.append(escaped_value);
}
data.append(" ");
this->builded.reset();
}
const size_t expected_bulk_size; const size_t expected_bulk_size;
const std::string _identifier; const std::string _identifier;
mutable bool flag_changed{false};
mutable std::optional<std::string> builded{}; mutable std::optional<std::string> builded{};
vector_t bulks{}; vector_t bulks{};
}; };