Skip to content

IOStreamBuf (istream/basic_streambuf adaptor for IOBuf)#554

Open
tedjp wants to merge 15 commits into
facebook:mainfrom
tedjp:iostreambuf-fb
Open

IOStreamBuf (istream/basic_streambuf adaptor for IOBuf)#554
tedjp wants to merge 15 commits into
facebook:mainfrom
tedjp:iostreambuf-fb

Conversation

@tedjp

@tedjp tedjp commented Mar 1, 2017

Copy link
Copy Markdown
Contributor

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.

Depends the io/test/Makefile.am changes 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 (chained IOBuf) to a 3rd party API.

The use of a .tcc file 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.h or whatever the preferred style is.

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`.
@facebook-github-bot

Copy link
Copy Markdown
Contributor

@Orvid has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@Orvid

Orvid commented Mar 3, 2017

Copy link
Copy Markdown
Contributor

-inl.h is the preferred style for Folly.

@Orvid Orvid left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Via @yfeldblum:

Missing an include guard (#pragma once preferably) and a license header.

Comment thread folly/io/IOStreamBuf.h Outdated
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,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread folly/io/IOStreamBuf.h Outdated
* must ensure that the IOBuf provided lasts at least as long as the
* IOStreamBuf.
*/
IOStreamBuf(const folly::IOBuf* head);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 the explicit keyword to avoid this, or add an /* implicit */ comment to suppress this warning.

In this case, marking it as explicit is the correct solution.

Comment thread folly/io/IOStreamBuf.h Outdated
*/
IOStreamBuf(const folly::IOBuf* head);

IOStreamBuf(const IOStreamBuf&) = default;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Via @yfeldblum:

Style. Prefer const-on-the-right in new code. IOStreamBuf const&. Here and elsewhere.

Comment thread folly/io/IOStreamBuf.h Outdated

IOStreamBuf(const IOStreamBuf&) = default;
IOStreamBuf& operator=(const IOStreamBuf&) = default;
void swap(IOStreamBuf<CharT,Traits>&);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Via @yfeldblum:

Style. , (with space) between template arguments. Here and elsewhere.

Comment thread folly/io/IOStreamBuf.h Outdated

}

#include "IOStreamBuf-inl.h"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Via @yfeldblum:

Style. Include with the full include path, ie. folly/io/IOStreamBuf-inl.h.

Comment thread folly/io/IOStreamBuf-inl.h Outdated
template <typename CharT, typename Traits>
typename IOStreamBuf<CharT,Traits>::int_type
IOStreamBuf<CharT,Traits>::pbackfail(int_type c) {
if (this->gptr() != this->eback())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Via @yfeldblum:

Style. if requires {}. Here and elsewhere.

const IOBuf* prev = gcur_;
do {
prev = prev->prev();
} while (prev->length() == 0 && prev != head_);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Via @yfeldblum:

Can also use std::find_if here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment thread folly/io/IOStreamBuf-inl.h Outdated

template <typename CharT, typename Traits>
typename IOStreamBuf<CharT,Traits>::pos_type
IOStreamBuf<CharT,Traits>::seekoff(off_type off,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread folly/io/test/Makefile.am Outdated
iobuf_cursor_test_LDADD = $(ldadd)

compression_test_SOURCES = CompressionTest.cpp
compression_test_LDADD = $(top_builddir)/libfolly.la \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Via @yfeldblum:

Can drop the first entry to the next line, for style.

@tedjp

tedjp commented Mar 17, 2017

Copy link
Copy Markdown
Contributor Author

Thanks for all the feedback. I'll send an update when time permits.

@facebook-github-bot facebook-github-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Orvid has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment