| 321 | } // namespace |
| 322 | |
| 323 | Result<std::unique_ptr<Message>> ReadMessage(std::shared_ptr<Buffer> metadata, |
| 324 | std::shared_ptr<Buffer> body) { |
| 325 | std::unique_ptr<Message> result; |
| 326 | auto listener = std::make_shared<AssignMessageDecoderListener>(&result); |
| 327 | // If the user does not pass in a body buffer then we assume they are skipping it |
| 328 | MessageDecoder decoder(listener, default_memory_pool(), body == nullptr); |
| 329 | |
| 330 | if (metadata->size() < decoder.next_required_size()) { |
| 331 | return Status::Invalid("metadata_length should be at least ", |
| 332 | decoder.next_required_size()); |
| 333 | } |
| 334 | |
| 335 | ARROW_RETURN_NOT_OK(decoder.Consume(metadata)); |
| 336 | |
| 337 | switch (decoder.state()) { |
| 338 | case MessageDecoder::State::INITIAL: |
| 339 | // Metadata did not request a body so we better not have provided one |
| 340 | DCHECK_EQ(body, nullptr); |
| 341 | return result; |
| 342 | case MessageDecoder::State::METADATA_LENGTH: |
| 343 | return Status::Invalid("metadata length is missing from the metadata buffer"); |
| 344 | case MessageDecoder::State::METADATA: |
| 345 | return Status::Invalid("flatbuffer size ", decoder.next_required_size(), |
| 346 | " invalid. Buffer size: ", metadata->size()); |
| 347 | case MessageDecoder::State::BODY: { |
| 348 | if (body == nullptr) { |
| 349 | // Caller didn't give a body so just give them a message without body |
| 350 | return result; |
| 351 | } |
| 352 | if (body->size() != decoder.next_required_size()) { |
| 353 | return Status::IOError("Expected body buffer to be ", |
| 354 | decoder.next_required_size(), |
| 355 | " bytes for message body, got ", body->size()); |
| 356 | } |
| 357 | RETURN_NOT_OK(decoder.Consume(body)); |
| 358 | return result; |
| 359 | } |
| 360 | case MessageDecoder::State::EOS: |
| 361 | return Status::Invalid("Unexpected empty message in IPC file format"); |
| 362 | default: |
| 363 | return Status::Invalid("Unexpected state: ", decoder.state()); |
| 364 | } |
| 365 | } |
| 366 | |
| 367 | // Common helper for the two ReadMessage overloads that take a file + offset. |
| 368 | // When body_length is provided, metadata and body are read in a single IO. |