You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

71 lines
2.2KB

  1. #pragma once
  2. #include <neo/buffer_concepts.hpp>
  3. #include <neo/const_buffer.hpp>
  4. #include <neo/mutable_buffer.hpp>
  5. #include <algorithm>
  6. #include <cstddef>
  7. #include <cstring>
  8. namespace neo {
  9. template <typename Seq>
  10. constexpr std::size_t buffer_size(const Seq& seq) {
  11. auto iter = buffer_sequence_begin(seq);
  12. const auto stop = buffer_sequence_end(seq);
  13. std::size_t size = 0;
  14. while (iter != stop) {
  15. size += static_cast<std::size_t>(iter->size());
  16. ++iter;
  17. }
  18. return size;
  19. }
  20. template <mutable_buffer_sequence MutableSeq, const_buffer_sequence ConstSeq>
  21. constexpr std::size_t
  22. buffer_copy(const MutableSeq& dest, const ConstSeq& src, std::size_t max_copy) {
  23. auto remaining_to_copy = max_copy;
  24. std::size_t n_copied = 0;
  25. auto dest_iter = buffer_sequence_begin(dest);
  26. const auto dest_stop = buffer_sequence_end(dest);
  27. auto src_iter = buffer_sequence_begin(src);
  28. const auto src_stop = buffer_sequence_end(dest);
  29. std::size_t src_offset = 0;
  30. std::size_t dest_offset = 0;
  31. while (dest_iter != dest_stop && src_iter != src_stop && remaining_to_copy) {
  32. const_buffer src_buf = *src_iter + src_offset;
  33. mutable_buffer dest_buf = *dest_iter + dest_offset;
  34. const auto copy_now
  35. = std::min(src_buf.size(), std::min(dest_buf.size(), remaining_to_copy));
  36. std::memcpy(dest_buf.data(), src_buf.data(), copy_now);
  37. n_copied += copy_now;
  38. src_buf += n_copied;
  39. dest_buf += n_copied;
  40. src_offset += n_copied;
  41. dest_offset += n_copied;
  42. if (src_buf.size() == 0) {
  43. ++src_iter;
  44. src_offset = 0;
  45. }
  46. if (dest_buf.size() == 0) {
  47. ++dest_iter;
  48. dest_offset = 0;
  49. }
  50. }
  51. return 0;
  52. }
  53. template <typename MutableSeq, typename ConstSeq>
  54. constexpr std::size_t buffer_copy(const MutableSeq& dest, const ConstSeq& src) {
  55. auto src_size = buffer_size(src);
  56. auto dest_size = buffer_size(dest);
  57. auto min_size = (src_size > dest_size) ? dest_size : src_size;
  58. return buffer_copy(dest, src, min_size);
  59. }
  60. } // namespace neo