iov.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Vectored I/O utils
  2. //
  3. // Platform: ISO C++ 98/11 - POSIX
  4. // $Id$
  5. //
  6. // (c) __vic 2012
  7. #ifndef __VIC_POSIX_IOV_H
  8. #define __VIC_POSIX_IOV_H
  9. #include<__vic/defs.h>
  10. #include<sys/uio.h>
  11. #include<limits.h> // for IOV_MAX
  12. #include<cassert>
  13. namespace __vic { namespace posix {
  14. //////////////////////////////////////////////////////////////////////////////
  15. template<unsigned N>
  16. class ovectors
  17. {
  18. ::iovec v[N], *next_;
  19. size_t total_;
  20. #if __cpp_static_assert
  21. static_assert(N <= IOV_MAX, "ovector cannot be greater than IOV_MAX");
  22. #else
  23. typedef char assert_size_is_not_too_big[N <= IOV_MAX ? 1 : -1];
  24. #endif
  25. public:
  26. ovectors() : next_(v), total_(0) {}
  27. void push_back(const void *p, size_t n)
  28. {
  29. assert(size() < max_size());
  30. next_->iov_base = const_cast<void *>(p);
  31. next_->iov_len = n;
  32. next_++;
  33. total_ += n;
  34. }
  35. void pop_back()
  36. {
  37. assert(!empty());
  38. next_--;
  39. total_ -= next_->iov_len;
  40. }
  41. ::iovec *ptr() { return v; }
  42. const ::iovec *ptr() const { return v; }
  43. unsigned size() const { return next_ - v; }
  44. bool full() const { return next_ == v + N; }
  45. bool empty() const { return next_ == v; }
  46. void clear() { next_ = v; total_ = 0; }
  47. static __VIC_CONSTEXPR_FUNC unsigned max_size() { return N; }
  48. size_t total_bytes() const { return total_; }
  49. };
  50. //////////////////////////////////////////////////////////////////////////////
  51. // TODO: class ivectors
  52. //----------------------------------------------------------------------------
  53. inline size_t total(const ::iovec *v, unsigned v_len)
  54. {
  55. size_t res = 0;
  56. for(; v_len--; v++) res += v->iov_len;
  57. return res;
  58. }
  59. //----------------------------------------------------------------------------
  60. template<unsigned vsize>
  61. inline size_t total(const ::iovec (&v)[vsize])
  62. {
  63. return total(v, vsize);
  64. }
  65. //----------------------------------------------------------------------------
  66. void cut_prefix(::iovec *& , unsigned & , size_t );
  67. void writev_all(int , ::iovec * , unsigned , size_t );
  68. //----------------------------------------------------------------------------
  69. template<unsigned vsize>
  70. inline void writev_all(int fd, ovectors<vsize> &v)
  71. {
  72. writev_all(fd, v.ptr(), v.size(), v.total_bytes());
  73. }
  74. //----------------------------------------------------------------------------
  75. }} // namespace
  76. #endif // header guard