Finalize exporting by setting C struct fields and allocating autonomous private data for each schema node. This function can't fail, as properly reclaiming memory in case of error would be too fragile. After this function returns, memory is reclaimed by calling the release() pointer in the top level ArrowSchema struct.
| 219 | // would be too fragile. After this function returns, memory is reclaimed |
| 220 | // by calling the release() pointer in the top level ArrowSchema struct. |
| 221 | void Finish(struct ArrowSchema* c_struct) { |
| 222 | // First, create permanent ExportedSchemaPrivateData |
| 223 | auto pdata = new ExportedSchemaPrivateData(std::move(export_)); |
| 224 | |
| 225 | // Second, finish dictionary and children. |
| 226 | if (dict_exporter_) { |
| 227 | dict_exporter_->Finish(&pdata->dictionary_); |
| 228 | } |
| 229 | pdata->child_pointers_.resize(child_exporters_.size(), nullptr); |
| 230 | for (size_t i = 0; i < child_exporters_.size(); ++i) { |
| 231 | auto ptr = pdata->child_pointers_[i] = &pdata->children_[i]; |
| 232 | child_exporters_[i].Finish(ptr); |
| 233 | } |
| 234 | |
| 235 | // Third, fill C struct. |
| 236 | DCHECK_NE(c_struct, nullptr); |
| 237 | memset(c_struct, 0, sizeof(*c_struct)); |
| 238 | |
| 239 | c_struct->format = pdata->format_.c_str(); |
| 240 | c_struct->name = pdata->name_.c_str(); |
| 241 | c_struct->metadata = pdata->metadata_.empty() ? nullptr : pdata->metadata_.c_str(); |
| 242 | c_struct->flags = flags_; |
| 243 | |
| 244 | c_struct->n_children = static_cast<int64_t>(child_exporters_.size()); |
| 245 | c_struct->children = c_struct->n_children ? pdata->child_pointers_.data() : nullptr; |
| 246 | c_struct->dictionary = dict_exporter_ ? &pdata->dictionary_ : nullptr; |
| 247 | c_struct->private_data = pdata; |
| 248 | c_struct->release = ReleaseExportedSchema; |
| 249 | } |
| 250 | |
| 251 | const DataType* UnwrapExtension(const DataType* type) { |
| 252 | if (type->id() == Type::EXTENSION) { |