An iterator of Buffers that makes sure there is no straddling CRLF sequence.
| 91 | |
| 92 | // An iterator of Buffers that makes sure there is no straddling CRLF sequence. |
| 93 | class CSVBufferIterator { |
| 94 | public: |
| 95 | static Iterator<std::shared_ptr<Buffer>> Make( |
| 96 | Iterator<std::shared_ptr<Buffer>> buffer_iterator) { |
| 97 | Transformer<std::shared_ptr<Buffer>, std::shared_ptr<Buffer>> fn = |
| 98 | CSVBufferIterator(); |
| 99 | return MakeTransformedIterator(std::move(buffer_iterator), fn); |
| 100 | } |
| 101 | |
| 102 | static AsyncGenerator<std::shared_ptr<Buffer>> MakeAsync( |
| 103 | AsyncGenerator<std::shared_ptr<Buffer>> buffer_iterator) { |
| 104 | Transformer<std::shared_ptr<Buffer>, std::shared_ptr<Buffer>> fn = |
| 105 | CSVBufferIterator(); |
| 106 | return MakeTransformedGenerator(std::move(buffer_iterator), fn); |
| 107 | } |
| 108 | |
| 109 | Result<TransformFlow<std::shared_ptr<Buffer>>> operator()(std::shared_ptr<Buffer> buf) { |
| 110 | if (buf == nullptr) { |
| 111 | // EOF |
| 112 | return TransformFinish(); |
| 113 | } |
| 114 | |
| 115 | int64_t offset = 0; |
| 116 | if (first_buffer_) { |
| 117 | ARROW_ASSIGN_OR_RAISE(auto data, util::SkipUTF8BOM(buf->data(), buf->size())); |
| 118 | offset += data - buf->data(); |
| 119 | DCHECK_GE(offset, 0); |
| 120 | first_buffer_ = false; |
| 121 | } |
| 122 | |
| 123 | if (trailing_cr_ && buf->data()[offset] == '\n') { |
| 124 | // Skip '\r\n' line separator that started at the end of previous buffer |
| 125 | ++offset; |
| 126 | } |
| 127 | |
| 128 | trailing_cr_ = (buf->data()[buf->size() - 1] == '\r'); |
| 129 | buf = SliceBuffer(std::move(buf), offset); |
| 130 | if (buf->size() == 0) { |
| 131 | // EOF |
| 132 | return TransformFinish(); |
| 133 | } else { |
| 134 | return TransformYield(std::move(buf)); |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | protected: |
| 139 | bool first_buffer_ = true; |
| 140 | // Whether there was a trailing CR at the end of last received buffer |
| 141 | bool trailing_cr_ = false; |
| 142 | }; |
| 143 | |
| 144 | struct CSVBlock { |
| 145 | // (partial + completion + buffer) is an entire delimited CSV buffer. |