| 69 | } |
| 70 | |
| 71 | virtual ssize_t read(char *buf, size_t len) override { |
| 72 | size_t left = len; |
| 73 | ssize_t r = 0; |
| 74 | size_t off = 0; |
| 75 | while (left > 0) { |
| 76 | if (!_cache_ptr) { |
| 77 | _cache_ptr.emplace(); |
| 78 | r = zero_copy_read(*_cache_ptr); |
| 79 | if (r <= 0) { |
| 80 | _cache_ptr.reset(); |
| 81 | if (r == -EAGAIN) |
| 82 | break; |
| 83 | return r; |
| 84 | } |
| 85 | } |
| 86 | if (_cache_ptr->length() <= left) { |
| 87 | _cache_ptr->copy_out(0, _cache_ptr->length(), buf+off); |
| 88 | left -= _cache_ptr->length(); |
| 89 | off += _cache_ptr->length(); |
| 90 | _cache_ptr.reset(); |
| 91 | } else { |
| 92 | _cache_ptr->copy_out(0, left, buf+off); |
| 93 | _cache_ptr->set_offset(_cache_ptr->offset() + left); |
| 94 | _cache_ptr->set_length(_cache_ptr->length() - left); |
| 95 | left = 0; |
| 96 | break; |
| 97 | } |
| 98 | } |
| 99 | return len - left ? len - left : -EAGAIN; |
| 100 | } |
| 101 | |
| 102 | private: |
| 103 | ssize_t zero_copy_read(bufferptr &data) { |
no test coverage detected