1#pragma once
2
3#include <vector>
4
5#include <IO/ReadBuffer.h>
6
7
8namespace DB
9{
10
11/** Reads from the concatenation of multiple ReadBuffers
12 */
13class ConcatReadBuffer : public ReadBuffer
14{
15public:
16 using ReadBuffers = std::vector<ReadBuffer *>;
17
18protected:
19 ReadBuffers buffers;
20 ReadBuffers::iterator current;
21
22 bool nextImpl() override
23 {
24 if (buffers.end() == current)
25 return false;
26
27 /// First reading
28 if (working_buffer.size() == 0 && (*current)->hasPendingData())
29 {
30 working_buffer = Buffer((*current)->position(), (*current)->buffer().end());
31 return true;
32 }
33
34 if (!(*current)->next())
35 {
36 ++current;
37 if (buffers.end() == current)
38 return false;
39
40 /// We skip the filled up buffers; if the buffer is not filled in, but the cursor is at the end, then read the next piece of data.
41 while ((*current)->eof())
42 {
43 ++current;
44 if (buffers.end() == current)
45 return false;
46 }
47 }
48
49 working_buffer = Buffer((*current)->position(), (*current)->buffer().end());
50 return true;
51 }
52
53public:
54 ConcatReadBuffer(const ReadBuffers & buffers_) : ReadBuffer(nullptr, 0), buffers(buffers_), current(buffers.begin()) {}
55
56 ConcatReadBuffer(ReadBuffer & buf1, ReadBuffer & buf2) : ReadBuffer(nullptr, 0)
57 {
58 buffers.push_back(&buf1);
59 buffers.push_back(&buf2);
60 current = buffers.begin();
61 }
62};
63
64}
65