blob: 74571608f3ae569b5574218e4d832bc5da8cd494 [file] [log] [blame]
#ifndef SRC_NODE_BOB_H_
#define SRC_NODE_BOB_H_
#include <functional>
namespace node {
namespace bob {
constexpr size_t kMaxCountHint = 16;
// Negative status codes indicate error conditions.
enum Status : int {
// Indicates that an attempt was made to pull after end.
STATUS_EOS = -1,
// Indicates the end of the stream. No additional
// data will be available and the consumer should stop
// pulling.
STATUS_END = 0,
// Indicates that there is additional data available
// and the consumer may continue to pull.
STATUS_CONTINUE = 1,
// Indicates that there is no additional data available
// but the stream has not ended. The consumer should not
// continue to pull but may resume pulling later when
// data is available.
STATUS_BLOCK = 2,
// Indicates that there is no additional data available
// but the stream has not ended and the source will call
// next again later when data is available. STATUS_WAIT
// must not be used with the OPTIONS_SYNC option.
STATUS_WAIT = 3,
};
enum Options : int {
OPTIONS_NONE = 0,
// Indicates that the consumer is requesting the end
// of the stream.
OPTIONS_END = 1,
// Indicates that the consumer requires the source to
// invoke Next synchronously. If the source is
// unable to provide data immediately but the
// stream has not yet ended, it should call Next
// using STATUS_BLOCK. When not set, the source
// may call Next asynchronously.
OPTIONS_SYNC = 2
};
// There are Sources and there are Consumers.
//
// Consumers get data by calling Source::Pull,
// optionally passing along a status and allocated
// buffer space for the source to fill, and a Next
// function the Source will call when data is
// available.
//
// The source calls Next to deliver the data. It can
// choose to either use the allocated buffer space
// provided by the consumer or it can allocate its own
// buffers and push those instead. If it allocates
// its own, it can send a Done function that the
// Sink will call when it is done consuming the data.
using Done = std::function<void(size_t)>;
template <typename T>
using Next = std::function<void(int, const T*, size_t count, Done done)>;
template <typename T>
class Source {
public:
virtual int Pull(
Next<T> next,
int options,
T* data,
size_t count,
size_t max_count_hint = kMaxCountHint) = 0;
};
template <typename T>
class SourceImpl : public Source<T> {
public:
int Pull(
Next<T> next,
int options,
T* data,
size_t count,
size_t max_count_hint = kMaxCountHint) override;
bool is_eos() const { return eos_; }
protected:
virtual int DoPull(
Next<T> next,
int options,
T* data,
size_t count,
size_t max_count_hint) = 0;
private:
bool eos_ = false;
};
} // namespace bob
} // namespace node
#endif // SRC_NODE_BOB_H_