| 702 | // Allocate and initialize buffers |
| 703 | arrow::BufferVector buffers; |
| 704 | ARROW_ASSIGN_OR_RAISE(auto header_buf, arrow::AllocateBuffer(header_size)); |
| 705 | |
| 706 | // Force the header_stream to be destructed, which actually flushes |
| 707 | // the data into the slice. |
| 708 | { |
| 709 | ArrayOutputStream header_writer(const_cast<uint8_t*>(header_buf->mutable_data()), |
| 710 | static_cast<int>(header_size)); |
| 711 | CodedOutputStream header_stream(&header_writer); |
| 712 | |
| 713 | // Write descriptor |
| 714 | if (msg.descriptor != nullptr) { |
| 715 | WireFormatLite::WriteTag(pb::FlightData::kFlightDescriptorFieldNumber, |
| 716 | WireFormatLite::WIRETYPE_LENGTH_DELIMITED, &header_stream); |
| 717 | header_stream.WriteVarint32(descriptor_size); |
| 718 | header_stream.WriteRawMaybeAliased(msg.descriptor->data(), |
| 719 | static_cast<int>(msg.descriptor->size())); |
| 720 | } |
| 721 | |
| 722 | // Write header |
| 723 | if (has_ipc) { |
| 724 | WireFormatLite::WriteTag(pb::FlightData::kDataHeaderFieldNumber, |
| 725 | WireFormatLite::WIRETYPE_LENGTH_DELIMITED, &header_stream); |
| 726 | header_stream.WriteVarint32(metadata_size); |
| 727 | header_stream.WriteRawMaybeAliased(ipc_msg.metadata->data(), |
| 728 | static_cast<int>(ipc_msg.metadata->size())); |
| 729 | } |
| 730 | |
| 731 | // Write app metadata |
| 732 | if (app_metadata_size > 0) { |
| 733 | WireFormatLite::WriteTag(pb::FlightData::kAppMetadataFieldNumber, |
| 734 | WireFormatLite::WIRETYPE_LENGTH_DELIMITED, &header_stream); |
| 735 | header_stream.WriteVarint32(app_metadata_size); |
| 736 | header_stream.WriteRawMaybeAliased(msg.app_metadata->data(), |
| 737 | static_cast<int>(msg.app_metadata->size())); |
| 738 | } |
| 739 | |
| 740 | if (has_body) { |
| 741 | // Write body tag |
| 742 | WireFormatLite::WriteTag(pb::FlightData::kDataBodyFieldNumber, |
| 743 | WireFormatLite::WIRETYPE_LENGTH_DELIMITED, &header_stream); |
| 744 | header_stream.WriteVarint32(static_cast<uint32_t>(body_size)); |
| 745 | |
| 746 | // Enqueue body buffers for writing, without copying |
| 747 | for (const auto& buffer : ipc_msg.body_buffers) { |
| 748 | // Buffer may be null when the row length is zero, or when all |
| 749 | // entries are invalid. |
| 750 | if (!buffer || buffer->size() == 0) continue; |
| 751 | buffers.push_back(buffer); |
| 752 | |
| 753 | // Write padding if not multiple of 8 |
| 754 | const auto remainder = static_cast<int>( |
| 755 | bit_util::RoundUpToMultipleOf8(buffer->size()) - buffer->size()); |
| 756 | if (remainder) { |
| 757 | buffers.push_back(std::make_shared<arrow::Buffer>(kPaddingBytes, remainder)); |
| 758 | } |
| 759 | } |
| 760 | } |
| 761 | |