MCPcopy Create free account
hub / github.com/apache/arrow / ReadFooterAsync

Method ReadFooterAsync

cpp/src/arrow/ipc/reader.cc:1870–1927  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1868 }
1869
1870 Future<> ReadFooterAsync(arrow::internal::Executor* executor) {
1871 constexpr int32_t kMagicSize = static_cast<int>(kArrowMagicBytes.size());
1872
1873 if (footer_offset_ <= kMagicSize * 2 + 4) {
1874 return Status::Invalid("File is too small: ", footer_offset_);
1875 }
1876
1877 int file_end_size = static_cast<int>(kMagicSize + sizeof(int32_t));
1878 auto self = std::dynamic_pointer_cast<RecordBatchFileReaderImpl>(shared_from_this());
1879 auto read_magic = file_->ReadAsync(footer_offset_ - file_end_size, file_end_size);
1880 if (executor) read_magic = executor->Transfer(std::move(read_magic));
1881 return read_magic
1882 .Then([=](const std::shared_ptr<Buffer>& buffer)
1883 -> Future<std::shared_ptr<Buffer>> {
1884 const int64_t expected_footer_size = kMagicSize + sizeof(int32_t);
1885 if (buffer->size() < expected_footer_size) {
1886 return Status::Invalid("Unable to read ", expected_footer_size,
1887 "from end of file");
1888 }
1889
1890 const auto magic_start = buffer->data() + sizeof(int32_t);
1891 if (std::string_view(reinterpret_cast<const char*>(magic_start), kMagicSize) !=
1892 kArrowMagicBytes) {
1893 return Status::Invalid("Not an Arrow file");
1894 }
1895
1896 int32_t footer_length = bit_util::FromLittleEndian(
1897 *reinterpret_cast<const int32_t*>(buffer->data()));
1898
1899 if (footer_length <= 0 ||
1900 footer_length > self->footer_offset_ - kMagicSize * 2 - 4) {
1901 return Status::Invalid("File is smaller than indicated metadata size");
1902 }
1903
1904 // Now read the footer
1905 auto read_footer = self->file_->ReadAsync(
1906 self->footer_offset_ - footer_length - file_end_size, footer_length);
1907 if (executor) read_footer = executor->Transfer(std::move(read_footer));
1908 return read_footer;
1909 })
1910 .Then([=](const std::shared_ptr<Buffer>& buffer) -> Status {
1911 self->footer_buffer_ = buffer;
1912 const auto data = self->footer_buffer_->data();
1913 const auto size = self->footer_buffer_->size();
1914 if (!internal::VerifyFlatbuffers<flatbuf::Footer>(data, size)) {
1915 return Status::IOError("Verification of flatbuffer-encoded Footer failed.");
1916 }
1917 self->footer_ = flatbuf::GetFooter(data);
1918
1919 auto fb_metadata = self->footer_->custom_metadata();
1920 if (fb_metadata != nullptr) {
1921 std::shared_ptr<KeyValueMetadata> md;
1922 RETURN_NOT_OK(internal::GetKeyValueMetadata(fb_metadata, &md));
1923 self->metadata_ = std::move(md); // const-ify
1924 }
1925 return Status::OK();
1926 });
1927 }

Callers

nothing calls this directly

Calls 11

IOErrorFunction · 0.85
GetFooterFunction · 0.85
GetKeyValueMetadataFunction · 0.85
ThenMethod · 0.80
InvalidFunction · 0.50
FromLittleEndianFunction · 0.50
OKFunction · 0.50
sizeMethod · 0.45
ReadAsyncMethod · 0.45
dataMethod · 0.45
custom_metadataMethod · 0.45

Tested by

no test coverage detected