| 221 | } |
| 222 | |
| 223 | Result<TransformFlow<CSVBlock>> operator()(std::shared_ptr<Buffer> next_buffer) { |
| 224 | if (buffer_ == nullptr) { |
| 225 | return TransformFinish(); |
| 226 | } |
| 227 | |
| 228 | bool is_final = (next_buffer == nullptr); |
| 229 | int64_t bytes_skipped = 0; |
| 230 | |
| 231 | if (skip_rows_) { |
| 232 | bytes_skipped += partial_->size(); |
| 233 | auto orig_size = buffer_->size(); |
| 234 | RETURN_NOT_OK( |
| 235 | chunker_->ProcessSkip(partial_, buffer_, is_final, &skip_rows_, &buffer_)); |
| 236 | bytes_skipped += orig_size - buffer_->size(); |
| 237 | auto empty = std::make_shared<Buffer>(nullptr, 0); |
| 238 | if (skip_rows_) { |
| 239 | // Still have rows beyond this buffer to skip return empty block |
| 240 | partial_ = std::move(buffer_); |
| 241 | buffer_ = next_buffer; |
| 242 | return TransformYield<CSVBlock>(CSVBlock{empty, empty, empty, block_index_++, |
| 243 | is_final, bytes_skipped, |
| 244 | [](int64_t) { return Status::OK(); }}); |
| 245 | } |
| 246 | partial_ = std::move(empty); |
| 247 | } |
| 248 | |
| 249 | std::shared_ptr<Buffer> completion; |
| 250 | |
| 251 | if (is_final) { |
| 252 | // End of file reached => compute completion from penultimate block |
| 253 | RETURN_NOT_OK(chunker_->ProcessFinal(partial_, buffer_, &completion, &buffer_)); |
| 254 | } else { |
| 255 | // Get completion of partial from previous block. |
| 256 | RETURN_NOT_OK( |
| 257 | chunker_->ProcessWithPartial(partial_, buffer_, &completion, &buffer_)); |
| 258 | } |
| 259 | int64_t bytes_before_buffer = partial_->size() + completion->size(); |
| 260 | |
| 261 | auto consume_bytes = [this, bytes_before_buffer, |
| 262 | next_buffer](int64_t nbytes) -> Status { |
| 263 | DCHECK_GE(nbytes, 0); |
| 264 | int64_t offset = nbytes - bytes_before_buffer; |
| 265 | // All data before the buffer should have been consumed. |
| 266 | // This is checked in Parse() and BlockParsingOperator::operator(). |
| 267 | DCHECK_GE(offset, 0); |
| 268 | partial_ = SliceBuffer(buffer_, offset); |
| 269 | buffer_ = next_buffer; |
| 270 | return Status::OK(); |
| 271 | }; |
| 272 | |
| 273 | return TransformYield<CSVBlock>(CSVBlock{partial_, completion, buffer_, |
| 274 | block_index_++, is_final, bytes_skipped, |
| 275 | std::move(consume_bytes)}); |
| 276 | } |
| 277 | }; |
| 278 | |
| 279 | // An object that reads delimited CSV blocks for threaded use. |
nothing calls this directly
no test coverage detected