------------------------------------------------------------------------------------------------
| 559 | |
| 560 | // ------------------------------------------------------------------------------------------------ |
| 561 | void ProcessMetadata(const Schema_2x3::ListOf<Schema_2x3::Lazy<Schema_2x3::IfcProperty>, 1, 0> &set, ConversionData &conv, Metadata &properties, |
| 562 | const std::string &prefix = std::string(), |
| 563 | unsigned int nest = 0) { |
| 564 | for (const Schema_2x3::IfcProperty &property : set) { |
| 565 | const std::string &key = prefix.length() > 0 ? (prefix + "." + property.Name) : property.Name; |
| 566 | if (const Schema_2x3::IfcPropertySingleValue *const singleValue = property.ToPtr<Schema_2x3::IfcPropertySingleValue>()) { |
| 567 | if (singleValue->NominalValue) { |
| 568 | if (const ::Assimp::STEP::EXPRESS::STRING *str = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::STRING>()) { |
| 569 | std::string value = static_cast<std::string>(*str); |
| 570 | properties[key] = value; |
| 571 | } else if (const ::Assimp::STEP::EXPRESS::REAL *val1 = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::REAL>()) { |
| 572 | float value = static_cast<float>(*val1); |
| 573 | std::stringstream s; |
| 574 | s << value; |
| 575 | properties[key] = s.str(); |
| 576 | } else if (const ::Assimp::STEP::EXPRESS::INTEGER *val2 = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::INTEGER>()) { |
| 577 | int64_t curValue = static_cast<int64_t>(*val2); |
| 578 | std::stringstream s; |
| 579 | s << curValue; |
| 580 | properties[key] = s.str(); |
| 581 | } |
| 582 | } |
| 583 | } else if (const Schema_2x3::IfcPropertyListValue *const listValue = property.ToPtr<Schema_2x3::IfcPropertyListValue>()) { |
| 584 | std::stringstream ss; |
| 585 | ss << "["; |
| 586 | unsigned index = 0; |
| 587 | for (const Schema_2x3::IfcValue::Out &v : listValue->ListValues) { |
| 588 | if (!v) continue; |
| 589 | if (const ::Assimp::STEP::EXPRESS::STRING *str = v->ToPtr<::Assimp::STEP::EXPRESS::STRING>()) { |
| 590 | std::string value = static_cast<std::string>(*str); |
| 591 | ss << "'" << value << "'"; |
| 592 | } else if (const ::Assimp::STEP::EXPRESS::REAL *val1 = v->ToPtr<::Assimp::STEP::EXPRESS::REAL>()) { |
| 593 | float value = static_cast<float>(*val1); |
| 594 | ss << value; |
| 595 | } else if (const ::Assimp::STEP::EXPRESS::INTEGER *val2 = v->ToPtr<::Assimp::STEP::EXPRESS::INTEGER>()) { |
| 596 | int64_t value = static_cast<int64_t>(*val2); |
| 597 | ss << value; |
| 598 | } |
| 599 | if (index + 1 < listValue->ListValues.size()) { |
| 600 | ss << ","; |
| 601 | } |
| 602 | index++; |
| 603 | } |
| 604 | ss << "]"; |
| 605 | properties[key] = ss.str(); |
| 606 | } else if (const Schema_2x3::IfcComplexProperty *const complexProp = property.ToPtr<Schema_2x3::IfcComplexProperty>()) { |
| 607 | if (nest > 2) { // mostly arbitrary limit to prevent stack overflow vulnerabilities |
| 608 | IFCImporter::LogError("maximum nesting level for IfcComplexProperty reached, skipping this property."); |
| 609 | } else { |
| 610 | ProcessMetadata(complexProp->HasProperties, conv, properties, key, nest + 1); |
| 611 | } |
| 612 | } else { |
| 613 | properties[key] = std::string(); |
| 614 | } |
| 615 | } |
| 616 | } |
| 617 | |
| 618 | // ------------------------------------------------------------------------------------------------ |