| 436 | // exceptions for error handling (with the async path converting to Future/Status). |
| 437 | |
| 438 | void ParseMetaData() { |
| 439 | int64_t footer_read_size = GetFooterReadSize(); |
| 440 | PARQUET_ASSIGN_OR_THROW( |
| 441 | auto footer_buffer, |
| 442 | source_->ReadAt(source_size_ - footer_read_size, footer_read_size)); |
| 443 | uint32_t metadata_len = ParseFooterLength(footer_buffer, footer_read_size); |
| 444 | int64_t metadata_start = source_size_ - kFooterSize - metadata_len; |
| 445 | |
| 446 | std::shared_ptr<::arrow::Buffer> metadata_buffer; |
| 447 | if (footer_read_size >= (metadata_len + kFooterSize)) { |
| 448 | metadata_buffer = SliceBuffer( |
| 449 | footer_buffer, footer_read_size - metadata_len - kFooterSize, metadata_len); |
| 450 | } else { |
| 451 | PARQUET_ASSIGN_OR_THROW(metadata_buffer, |
| 452 | source_->ReadAt(metadata_start, metadata_len)); |
| 453 | } |
| 454 | |
| 455 | // Parse the footer depending on encryption type |
| 456 | const bool is_encrypted_footer = |
| 457 | memcmp(footer_buffer->data() + footer_read_size - 4, kParquetEMagic, 4) == 0; |
| 458 | std::shared_ptr<InternalFileDecryptor> file_decryptor; |
| 459 | if (is_encrypted_footer) { |
| 460 | // Encrypted file with Encrypted footer. |
| 461 | const std::pair<int64_t, uint32_t> read_size = |
| 462 | ParseMetaDataOfEncryptedFileWithEncryptedFooter(metadata_buffer, metadata_len, |
| 463 | &file_decryptor); |
| 464 | // Read the actual footer |
| 465 | metadata_start = read_size.first; |
| 466 | metadata_len = read_size.second; |
| 467 | PARQUET_ASSIGN_OR_THROW(metadata_buffer, |
| 468 | source_->ReadAt(metadata_start, metadata_len)); |
| 469 | // Fall through |
| 470 | } |
| 471 | |
| 472 | ParseMetaDataFinal(std::move(metadata_buffer), metadata_len, is_encrypted_footer, |
| 473 | std::move(file_decryptor)); |
| 474 | } |
| 475 | |
| 476 | // Validate the source size and get the initial read size. |
| 477 | int64_t GetFooterReadSize() { |
no test coverage detected