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

Function ReadMessageContinued

cpp/src/arrow/ipc/message.cc:336–399  ·  view source on GitHub ↗

A common continuation callback for ReadMessage and ReadMessageAsync overloads

Source from the content-addressed store, hash-verified

334
335// A common continuation callback for ReadMessage and ReadMessageAsync overloads
336static Result<std::unique_ptr<Message>> ReadMessageContinued(
337 int64_t offset, int32_t metadata_length, std::optional<int64_t> body_length,
338 std::shared_ptr<Buffer> metadata, io::RandomAccessFile* file,
339 const FieldsLoaderFunction& fields_loader, ReadMessageState* state) {
340 MessageDecoder* decoder = state->decoder.get();
341 if (body_length.has_value()) {
342 // If body length was known, the given buffer should contain exactly the metadata
343 // followed by the body.
344 DCHECK_EQ(metadata->size(), metadata_length + *body_length);
345 }
346 ARROW_RETURN_NOT_OK(decoder->Consume(SliceBuffer(metadata, 0, metadata_length)));
347 if (decoder->buffered_size() > 0) {
348 return Status::Invalid("Message metadata too long by ", decoder->buffered_size(),
349 " bytes");
350 }
351 switch (decoder->state()) {
352 case MessageDecoder::State::INITIAL:
353 return std::move(state->result);
354 case MessageDecoder::State::METADATA_LENGTH:
355 return Status::Invalid("metadata length is missing. File offset: ", offset,
356 ", metadata length: ", metadata_length);
357 case MessageDecoder::State::METADATA:
358 return Status::Invalid("flatbuffer size ", decoder->next_required_size(),
359 " invalid. File offset: ", offset,
360 ", metadata length: ", metadata_length);
361 case MessageDecoder::State::BODY: {
362 std::shared_ptr<Buffer> body;
363 if (fields_loader) {
364 // Selective field loading: allocate a body buffer and read only the
365 // requested field ranges into it.
366 DCHECK_NE(file, nullptr);
367 ARROW_ASSIGN_OR_RAISE(
368 body, AllocateBuffer(decoder->next_required_size(), default_memory_pool()));
369 RETURN_NOT_OK(ReadFieldsSubset(offset, file, fields_loader,
370 SliceBuffer(metadata, 0, metadata_length),
371 decoder->next_required_size(), body));
372 } else if (body_length.has_value()) {
373 // Body was already read as part of the combined IO; just slice it out.
374 if (*body_length != decoder->next_required_size()) {
375 // The streaming decoder got out of sync with the actual advertised
376 // metadata and body size, which signals an invalid IPC file.
377 return Status::IOError("Invalid IPC file: advertised body size is ",
378 *body_length, ", but message decoder expects to read ",
379 decoder->next_required_size(), " bytes instead");
380 }
381 body = SliceBuffer(metadata, metadata_length,
382 std::min(*body_length, metadata->size() - metadata_length));
383 } else {
384 // Body length was unknown; do a separate IO to read the body.
385 DCHECK_NE(file, nullptr);
386 ARROW_ASSIGN_OR_RAISE(
387 body, file->ReadAt(offset + metadata_length, decoder->next_required_size(),
388 /*allow_short_read=*/false));
389 }
390
391 RETURN_NOT_OK(decoder->Consume(body));
392 return std::move(state->result);
393 }

Callers 2

ReadMessageInternalFunction · 0.85
ReadMessageAsyncFunction · 0.85

Calls 14

SliceBufferFunction · 0.85
default_memory_poolFunction · 0.85
ReadFieldsSubsetFunction · 0.85
IOErrorFunction · 0.85
ARROW_ASSIGN_OR_RAISEFunction · 0.70
InvalidFunction · 0.50
AllocateBufferFunction · 0.50
getMethod · 0.45
sizeMethod · 0.45
ConsumeMethod · 0.45
buffered_sizeMethod · 0.45
stateMethod · 0.45

Tested by

no test coverage detected