utils: fragment_range: add a fragment iterator for FragmentedView
A stylistic change. Iterators are the idiomatic way to iterate in C++.
This commit is contained in:
@@ -266,8 +266,8 @@ private:
|
||||
}
|
||||
template<typename CharOutputIterator>
|
||||
static void write_value(managed_bytes_view val, CharOutputIterator& out) {
|
||||
for (; !val.empty(); val.remove_current()) {
|
||||
out = std::copy(val.current_fragment().begin(), val.current_fragment().end(), out);
|
||||
for (bytes_view frag : fragment_range(val)) {
|
||||
out = std::copy(frag.begin(), frag.end(), out);
|
||||
}
|
||||
}
|
||||
template <typename CharOutputIterator>
|
||||
|
||||
@@ -500,8 +500,8 @@ public:
|
||||
[[gnu::always_inline]]
|
||||
operator managed_bytes() && {
|
||||
managed_bytes mb(managed_bytes::initialized_later(), _stream.size());
|
||||
for (managed_bytes_mutable_view v = mb; !v.empty(); v.remove_current()) {
|
||||
_stream.read(reinterpret_cast<char*>(v.current_fragment().data()), v.current_fragment().size());
|
||||
for (bytes_mutable_view frag : fragment_range(managed_bytes_mutable_view(mb))) {
|
||||
_stream.read(reinterpret_cast<char*>(frag.data()), frag.size());
|
||||
}
|
||||
return mb;
|
||||
}
|
||||
@@ -533,8 +533,8 @@ struct serializer<bytes> {
|
||||
template<typename Output>
|
||||
static void write(Output& out, const managed_bytes& mb) {
|
||||
safe_serialize_as_uint32(out, uint32_t(mb.size()));
|
||||
for (managed_bytes_view v = mb; !v.empty(); v.remove_current()) {
|
||||
out.write(reinterpret_cast<const char*>(v.current_fragment().data()), v.current_fragment().size());
|
||||
for (bytes_view frag : fragment_range(managed_bytes_view(mb))) {
|
||||
out.write(reinterpret_cast<const char*>(frag.data()), frag.size());
|
||||
}
|
||||
}
|
||||
template<typename Output>
|
||||
|
||||
@@ -306,8 +306,8 @@ inline void write(sstable_version_types v, W& out, bytes_view s) {
|
||||
template <typename W>
|
||||
requires Writer<W>
|
||||
inline void write(sstable_version_types v, W& out, managed_bytes_view s) {
|
||||
for (; !s.empty(); s.remove_current()) {
|
||||
out.write(reinterpret_cast<const char*>(s.current_fragment().data()), s.current_fragment().size());
|
||||
for (bytes_view fragment : fragment_range(s)) {
|
||||
write(v, out, fragment);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
4
types.cc
4
types.cc
@@ -1477,8 +1477,8 @@ struct validate_visitor {
|
||||
}
|
||||
void operator()(const ascii_type_impl&) {
|
||||
// ASCII can be validated independently for each fragment
|
||||
for (View fv = v; fv.size_bytes() > 0; fv.remove_current()) {
|
||||
if (!utils::ascii::validate(fv.current_fragment())) {
|
||||
for (bytes_view frag : fragment_range(v)) {
|
||||
if (!utils::ascii::validate(frag)) {
|
||||
throw marshal_exception("Validation failed - non-ASCII character in an ASCII string");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,6 +179,41 @@ concept FragmentedMutableView = requires (T view) {
|
||||
requires std::is_same_v<typename T::fragment_type, bytes_mutable_view>;
|
||||
};
|
||||
|
||||
template<FragmentedView View>
|
||||
struct fragment_range {
|
||||
View view;
|
||||
class fragment_iterator {
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
using value_type = typename View::fragment_type;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = const value_type*;
|
||||
using reference = const value_type&;
|
||||
View _view;
|
||||
value_type _current;
|
||||
public:
|
||||
fragment_iterator() : _view(value_type()) {}
|
||||
fragment_iterator(const View& v) : _view(v) {
|
||||
_current = _view.current_fragment();
|
||||
}
|
||||
fragment_iterator& operator++() {
|
||||
_view.remove_current();
|
||||
_current = _view.current_fragment();
|
||||
return *this;
|
||||
}
|
||||
fragment_iterator operator++(int) {
|
||||
fragment_iterator i(*this);
|
||||
++(*this);
|
||||
return i;
|
||||
}
|
||||
reference operator*() const { return _current; }
|
||||
pointer operator->() const { return &_current; }
|
||||
bool operator==(const fragment_iterator& i) const { return _view.size_bytes() == i._view.size_bytes(); }
|
||||
};
|
||||
fragment_range(const View& v) : view(v) {}
|
||||
fragment_iterator begin() const { return fragment_iterator(view); }
|
||||
fragment_iterator end() const { return fragment_iterator(); }
|
||||
};
|
||||
|
||||
template<FragmentedView View>
|
||||
requires (!FragmentRange<View>)
|
||||
bytes linearized(View v)
|
||||
|
||||
@@ -451,8 +451,8 @@ struct appending_hash<managed_bytes_view> {
|
||||
template<Hasher Hasher>
|
||||
void operator()(Hasher& h, managed_bytes_view v) const {
|
||||
feed_hash(h, v.size_bytes());
|
||||
for (; !v.empty(); v.remove_current()) {
|
||||
h.update(reinterpret_cast<const char*>(v.current_fragment().data()), v.current_fragment().size());
|
||||
for (bytes_view frag : fragment_range(v)) {
|
||||
h.update(reinterpret_cast<const char*>(frag.data()), frag.size());
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -481,8 +481,8 @@ inline bool operator==(const managed_bytes_view& a, const managed_bytes_view& b)
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const managed_bytes_view& v) {
|
||||
for (managed_bytes_view mbv; !mbv.empty(); mbv.remove_current()) {
|
||||
os << to_hex(mbv.current_fragment());
|
||||
for (bytes_view frag : fragment_range(v)) {
|
||||
os << to_hex(frag);
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
@@ -74,8 +74,7 @@ std::optional<size_t> validate_with_error_position_fragmented(FragmentedView aut
|
||||
size_t partial_filled = 0;
|
||||
size_t partial_more_needed = 0;
|
||||
size_t bytes_validated = 0;
|
||||
for (; fv.size_bytes(); fv.remove_current()) {
|
||||
bytes_view frag = fv.current_fragment();
|
||||
for (bytes_view frag : fragment_range(fv)) {
|
||||
auto data = reinterpret_cast<const uint8_t*>(frag.data());
|
||||
auto len = frag.size();
|
||||
if (partial_more_needed) {
|
||||
|
||||
Reference in New Issue
Block a user