• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef SRC_NODE_BOB_H_
2 #define SRC_NODE_BOB_H_
3 
4 #include <functional>
5 
6 namespace node {
7 namespace bob {
8 
9 constexpr size_t kMaxCountHint = 16;
10 
11 // Negative status codes indicate error conditions.
12 enum Status : int {
13   // Indicates that an attempt was made to pull after end.
14   STATUS_EOS = -1,
15 
16   // Indicates the end of the stream. No additional
17   // data will be available and the consumer should stop
18   // pulling.
19   STATUS_END = 0,
20 
21   // Indicates that there is additional data available
22   // and the consumer may continue to pull.
23   STATUS_CONTINUE = 1,
24 
25   // Indicates that there is no additional data available
26   // but the stream has not ended. The consumer should not
27   // continue to pull but may resume pulling later when
28   // data is available.
29   STATUS_BLOCK = 2,
30 
31   // Indicates that there is no additional data available
32   // but the stream has not ended and the source will call
33   // next again later when data is available. STATUS_WAIT
34   // must not be used with the OPTIONS_SYNC option.
35   STATUS_WAIT = 3,
36 };
37 
38 enum Options : int {
39   OPTIONS_NONE = 0,
40 
41   // Indicates that the consumer is requesting the end
42   // of the stream.
43   OPTIONS_END = 1,
44 
45   // Indicates that the consumer requires the source to
46   // invoke Next synchronously. If the source is
47   // unable to provide data immediately but the
48   // stream has not yet ended, it should call Next
49   // using STATUS_BLOCK. When not set, the source
50   // may call Next asynchronously.
51   OPTIONS_SYNC = 2
52 };
53 
54 // There are Sources and there are Consumers.
55 //
56 // Consumers get data by calling Source::Pull,
57 // optionally passing along a status and allocated
58 // buffer space for the source to fill, and a Next
59 // function the Source will call when data is
60 // available.
61 //
62 // The source calls Next to deliver the data. It can
63 // choose to either use the allocated buffer space
64 // provided by the consumer or it can allocate its own
65 // buffers and push those instead. If it allocates
66 // its own, it can send a Done function that the
67 // Sink will call when it is done consuming the data.
68 using Done = std::function<void(size_t)>;
69 template <typename T>
70 using Next = std::function<void(int, const T*, size_t count, Done done)>;
71 
72 template <typename T>
73 class Source {
74  public:
75   virtual int Pull(
76       Next<T> next,
77       int options,
78       T* data,
79       size_t count,
80       size_t max_count_hint = kMaxCountHint) = 0;
81 };
82 
83 
84 template <typename T>
85 class SourceImpl : public Source<T> {
86  public:
87   int Pull(
88       Next<T> next,
89       int options,
90       T* data,
91       size_t count,
92       size_t max_count_hint = kMaxCountHint) override;
93 
is_eos()94   bool is_eos() const { return eos_; }
95 
96  protected:
97   virtual int DoPull(
98       Next<T> next,
99       int options,
100       T* data,
101       size_t count,
102       size_t max_count_hint) = 0;
103 
104  private:
105   bool eos_ = false;
106 };
107 
108 }  // namespace bob
109 }  // namespace node
110 
111 #endif  // SRC_NODE_BOB_H_
112