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

Method ReadFooterAsync

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

Source from the content-addressed store, hash-verified

1881 }
1882
1883 Future<> ReadFooterAsync(arrow::internal::Executor* executor) {
1884 constexpr int32_t kMagicSize = static_cast<int>(kArrowMagicBytes.size());
1885
1886 if (footer_offset_ <= kMagicSize * 2 + 4) {
1887 return Status::Invalid("File is too small: ", footer_offset_);
1888 }
1889
1890 constexpr int64_t kTotalMagicSize = kMagicSize + sizeof(int32_t);
1891 auto self = std::dynamic_pointer_cast<RecordBatchFileReaderImpl>(shared_from_this());
1892 auto read_magic = file_->ReadAsync(footer_offset_ - kTotalMagicSize, kTotalMagicSize,
1893 /*allow_short_read=*/false);
1894 if (executor) read_magic = executor->Transfer(std::move(read_magic));
1895 return read_magic
1896 .Then([=](const std::shared_ptr<Buffer>& buffer)
1897 -> Future<std::shared_ptr<Buffer>> {
1898 DCHECK_EQ(buffer->size(), kTotalMagicSize);
1899 const auto magic_start = buffer->data() + sizeof(int32_t);
1900 if (std::string_view(reinterpret_cast<const char*>(magic_start), kMagicSize) !=
1901 kArrowMagicBytes) {
1902 return Status::Invalid("Not an Arrow file");
1903 }
1904
1905 int32_t footer_length = bit_util::FromLittleEndian(
1906 *reinterpret_cast<const int32_t*>(buffer->data()));
1907
1908 if (footer_length <= 0 ||
1909 footer_length > self->footer_offset_ - kMagicSize * 2 - 4) {
1910 return Status::Invalid("File is smaller than indicated metadata size");
1911 }
1912
1913 // Now read the footer
1914 auto read_footer = self->file_->ReadAsync(
1915 self->footer_offset_ - footer_length - kTotalMagicSize, footer_length,
1916 /*allow_short_read=*/false);
1917 if (executor) read_footer = executor->Transfer(std::move(read_footer));
1918 return read_footer;
1919 })
1920 .Then([=](const std::shared_ptr<Buffer>& buffer) -> Status {
1921 self->footer_buffer_ = buffer;
1922 const auto data = self->footer_buffer_->data();
1923 const auto size = self->footer_buffer_->size();
1924 if (!internal::VerifyFlatbuffers<flatbuf::Footer>(data, size)) {
1925 return Status::IOError("Verification of flatbuffer-encoded Footer failed.");
1926 }
1927 self->footer_ = flatbuf::GetFooter(data);
1928
1929 auto fb_metadata = self->footer_->custom_metadata();
1930 if (fb_metadata != nullptr) {
1931 std::shared_ptr<KeyValueMetadata> md;
1932 ARROW_ASSIGN_OR_RAISE(self->metadata_,
1933 internal::GetKeyValueMetadata(fb_metadata));
1934 }
1935 return Status::OK();
1936 });
1937 }
1938
1939 int num_dictionaries() const {
1940 return static_cast<int>(internal::FlatBuffersVectorSize(footer_->dictionaries()));

Callers

nothing calls this directly

Calls 12

IOErrorFunction · 0.85
GetFooterFunction · 0.85
GetKeyValueMetadataFunction · 0.85
ThenMethod · 0.80
ARROW_ASSIGN_OR_RAISEFunction · 0.70
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