| 587 | } |
| 588 | |
| 589 | proto::StripeFooter getStripeFooter(const proto::StripeInformation& info, |
| 590 | FileContents& contents) { |
| 591 | uint64_t stripeFooterStart = info.offset() + info.index_length() + info.data_length(); |
| 592 | uint64_t stripeFooterLength = info.footer_length(); |
| 593 | |
| 594 | std::unique_ptr<SeekableInputStream> pbStream; |
| 595 | BufferSlice slice; |
| 596 | |
| 597 | { |
| 598 | std::lock_guard<std::mutex> lock(contents.readCacheMutex); |
| 599 | if (contents.readCache) { |
| 600 | slice = contents.readCache->read(ReadRange(stripeFooterStart, stripeFooterLength)); |
| 601 | } |
| 602 | } |
| 603 | if (slice.buffer) { |
| 604 | pbStream = std::make_unique<SeekableArrayInputStream>(slice.buffer->data() + slice.offset, |
| 605 | slice.length); |
| 606 | } else { |
| 607 | pbStream = std::make_unique<SeekableFileInputStream>(contents.stream.get(), stripeFooterStart, |
| 608 | stripeFooterLength, *contents.pool); |
| 609 | } |
| 610 | pbStream = createDecompressor(contents.compression, std::move(pbStream), contents.blockSize, |
| 611 | *contents.pool, contents.readerMetrics); |
| 612 | |
| 613 | proto::StripeFooter result; |
| 614 | if (!result.ParseFromZeroCopyStream(pbStream.get())) { |
| 615 | throw ParseError(std::string("bad StripeFooter from ") + pbStream->getName()); |
| 616 | } |
| 617 | // Verify StripeFooter in case it's corrupt |
| 618 | if (result.columns_size() != contents.footer->types_size()) { |
| 619 | std::stringstream msg; |
| 620 | msg << "bad number of ColumnEncodings in StripeFooter: expected=" |
| 621 | << contents.footer->types_size() << ", actual=" << result.columns_size(); |
| 622 | throw ParseError(msg.str()); |
| 623 | } |
| 624 | return result; |
| 625 | } |
| 626 | |
| 627 | ReaderImpl::ReaderImpl(std::shared_ptr<FileContents> contents, const ReaderOptions& opts, |
| 628 | uint64_t fileLength, uint64_t postscriptLength) |
no test coverage detected