IOStreamBuf (istream/basic_streambuf adaptor for IOBuf)#554
Conversation
It takes about 4 minutes; the rest of the suite takes around 10 seconds. Still builds during `make check` and can be executed manually.
Allows chained IOBufs to be read via std::istream without having to coalesce them into a single contiguous buffer first. Works with any single-byte type, eg. `char` or `uint8_t`. Not currently usable on multi-byte types like `wchar_t` due to the extra complexity involved in recomposing multi-byte characters that are split across IOBuf boundaries. (static_assert prevents use with multi-byte types.) Currently read-only; cannot be used with a `std::ostream`.
|
@Orvid has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
|
|
Orvid
left a comment
There was a problem hiding this comment.
Via @yfeldblum:
A bunch of style nits to make this conform to the standard Folly style. I mention each nit category only once, but each mention refers implicitly to many occurrences in that category.
| @@ -0,0 +1,264 @@ | |||
| #include <folly/Likely.h> | |||
There was a problem hiding this comment.
Via @yfeldblum:
Missing an include guard (
#pragma oncepreferably) and a license header.
| class IOStreamBuf : public std::basic_streambuf<CharT, Traits> { | ||
| // Due to having to merge single-byte subsets of CharT across IOBuf | ||
| // boundaries, prevent the use of IOStreamBuf on multi-byte types for now. | ||
| static_assert(sizeof(CharT) == 1, |
There was a problem hiding this comment.
Via @yfeldblum:
Style. If the arguments must be broken across lines, then each one goes on its own line, and each one is indented +4. Here and elsewhere.
| * must ensure that the IOBuf provided lasts at least as long as the | ||
| * IOStreamBuf. | ||
| */ | ||
| IOStreamBuf(const folly::IOBuf* head); |
There was a problem hiding this comment.
Via our internal linter:
Single-argument constructor
IOStreamBuf(const folly::IOBuf* head)may inadvertently be used as a type conversion constructor. Prefix the function with theexplicitkeyword to avoid this, or add an/* implicit */comment to suppress this warning.
In this case, marking it as explicit is the correct solution.
| */ | ||
| IOStreamBuf(const folly::IOBuf* head); | ||
|
|
||
| IOStreamBuf(const IOStreamBuf&) = default; |
There was a problem hiding this comment.
Via @yfeldblum:
Style. Prefer const-on-the-right in new code.
IOStreamBuf const&. Here and elsewhere.
|
|
||
| IOStreamBuf(const IOStreamBuf&) = default; | ||
| IOStreamBuf& operator=(const IOStreamBuf&) = default; | ||
| void swap(IOStreamBuf<CharT,Traits>&); |
There was a problem hiding this comment.
Via @yfeldblum:
Style.
,(with space) between template arguments. Here and elsewhere.
|
|
||
| } | ||
|
|
||
| #include "IOStreamBuf-inl.h" |
There was a problem hiding this comment.
Via @yfeldblum:
Style. Include with the full include path, ie.
folly/io/IOStreamBuf-inl.h.
| template <typename CharT, typename Traits> | ||
| typename IOStreamBuf<CharT,Traits>::int_type | ||
| IOStreamBuf<CharT,Traits>::pbackfail(int_type c) { | ||
| if (this->gptr() != this->eback()) |
There was a problem hiding this comment.
Via @yfeldblum:
Style.
ifrequires{}. Here and elsewhere.
| const IOBuf* prev = gcur_; | ||
| do { | ||
| prev = prev->prev(); | ||
| } while (prev->length() == 0 && prev != head_); |
There was a problem hiding this comment.
Via @yfeldblum:
Can also use
std::find_ifhere.
There was a problem hiding this comment.
Looks like IOBuf::Iterator is a forward-only iterator whereas this code needs to iterate backwards to the head. Furthermore it needs access to the IOBuf object itself but the IOBuf::Iterator only exposes a ByteRange (ie. the data within the IOBuf).
|
|
||
| template <typename CharT, typename Traits> | ||
| typename IOStreamBuf<CharT,Traits>::pos_type | ||
| IOStreamBuf<CharT,Traits>::seekoff(off_type off, |
There was a problem hiding this comment.
Via @yfeldblum:
This is very long. At the very least, split it into three private member functions for the three possible values of
way, since the implementations for the three code paths share no code.
| iobuf_cursor_test_LDADD = $(ldadd) | ||
|
|
||
| compression_test_SOURCES = CompressionTest.cpp | ||
| compression_test_LDADD = $(top_builddir)/libfolly.la \ |
There was a problem hiding this comment.
Via @yfeldblum:
Can drop the first entry to the next line, for style.
|
Thanks for all the feedback. I'll send an update when time permits. |
Avoids unintentional implicit construction.
Adjusted indentation of each line to a single tab to match top-level Makefile.am.
No functional code change; just refactoring.
facebook-github-bot
left a comment
There was a problem hiding this comment.
Orvid has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
Allows chained
IOBufs to be read viastd::istreamwithout having to coalesce them into a single contiguous buffer first.Works with any single-byte type, eg.
charoruint8_t. Not currently usable on multi-byte types likewchar_tdue to the extra complexity involved in recomposing multi-byte characters that are split acrossIOBufboundaries. (static_assertprevents use with multi-byte types.)Currently read-only; cannot be used with a
std::ostream.Depends the
io/test/Makefile.amchanges in #550. I've included the two necessary commits in this pull request. Happy to resubmit this after #550 completes review if that's preferred.There are probably good performance reasons to avoid using this in general — and perhaps that should be noted in the header — but it could be useful in conjunction with APIs that can read from an
istream. My use for this was with Proxygen: passing an incoming message body (chainedIOBuf) to a 3rd party API.The use of a
.tccfile for the implementation of most of the templated functions is unusual for Folly but I wanted to keep them out of the general header. It could easily be renamed to…-impl.hor whatever the preferred style is.