#ifndef SRC_NODE_BOB_H_ #define SRC_NODE_BOB_H_ #include 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; template using Next = std::function; template class Source { public: virtual int Pull( Next next, int options, T* data, size_t count, size_t max_count_hint = kMaxCountHint) = 0; }; template class SourceImpl : public Source { public: int Pull( Next 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 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_