9 const auto& source_layout = source.layout();
12 if (source_layout.stride_bytes() != target_layout.stride_bytes()
13 || source_layout.fields().size() != target_layout.fields().size()) {
15 "CompositeInsertion: incompatible layout");
19 for (
size_t i = 0; i < target_layout.fields().
size(); ++i) {
20 const auto&
src = source_layout.fields()[i];
21 const auto&
dst = target_layout.fields()[i];
23 ||
src.offset_bytes !=
dst.offset_bytes ||
src.size_bytes !=
dst.size_bytes) {
25 "CompositeInsertion: incompatible field '{}'",
dst.name);
30 const auto& source_elements = std::get<std::vector<uint8_t>>(*source.m_rows);
31 const size_t stride = target_layout.stride_bytes();
32 const auto element_begin = source_elements.begin() +
static_cast<ptrdiff_t
>(source.m_index * stride);
34 std::vector<uint8_t> element(element_begin, element_begin +
static_cast<ptrdiff_t
>(stride));
35 std::vector<std::pair<size_t, std::string>> texts;
36 std::vector<std::pair<size_t, std::vector<uint8_t>>> blobs;
37 size_t additional_text = 0;
38 size_t additional_blob = 0;
40 for (
size_t i = 0; i < source_layout.fields().
size(); ++i) {
41 const auto& field = source_layout.fields()[i];
42 if (!source.has(field.name))
46 if (field.type ==
typeid(std::string)
48 const auto value = source.text(field.name);
49 if (!
value ||
value->size() > std::numeric_limits<size_t>::max() - additional_text)
51 additional_text +=
value->size();
52 texts.emplace_back(i, std::string(*
value));
53 }
else if (field.type ==
typeid(std::vector<uint8_t>)
55 const auto value = source.blob(field.name);
56 if (!
value ||
value->size() > std::numeric_limits<size_t>::max() - additional_blob)
58 additional_blob +=
value->size();
59 blobs.emplace_back(i, std::vector<uint8_t>(
value->begin(),
value->end()));
63 auto& target_elements = std::get<std::vector<uint8_t>>(
m_array->
m_rows);
64 auto& target_text = std::get<std::vector<uint8_t>>(
m_array->
m_text);
65 auto& target_blob = std::get<std::vector<uint8_t>>(
m_array->
m_blob);
67 if (stride > target_elements.max_size() - target_elements.size()
68 || additional_text > target_text.max_size() - target_text.size()
69 || additional_blob > target_blob.max_size() - target_blob.size())
72 target_elements.reserve(target_elements.size() + stride);
73 target_text.reserve(target_text.size() + additional_text);
74 target_blob.reserve(target_blob.size() + additional_blob);
77 std::memcpy(target_elements.data() +
index * stride, element.data(), stride);
79 for (
const auto& [field_index,
value] : texts)
81 for (
const auto& [field_index,
value] : blobs)