void XMPMetadataSource::saveProperty(const MetadataSet& property, const MetaString& pathToSchema, const MetaString& propertyName) { if (property.empty()) { // not loaded or empty. In any case nothing to do. return; } MetaString pathToPropertiesArray; SXMPUtils::ComposeStructFieldPath(VMF_NS, pathToSchema.c_str(), VMF_NS, SCHEMA_SET, &pathToPropertiesArray); MetaString thisPropertyPath = findProperty(pathToSchema, propertyName); if (thisPropertyPath.empty()) { xmp->AppendArrayItem(VMF_NS, pathToPropertiesArray.c_str(), kXMP_PropValueIsArray, nullptr, kXMP_PropValueIsStruct); SXMPUtils::ComposeArrayItemPath(VMF_NS, pathToPropertiesArray.c_str(), kXMP_ArrayLastItem, &thisPropertyPath); } savePropertyName(thisPropertyPath, propertyName); xmp->SetStructField(VMF_NS, thisPropertyPath.c_str(), VMF_NS, PROPERTY_SET, nullptr, kXMP_PropValueIsArray); MetaString thisPropertySetPath; SXMPUtils::ComposeStructFieldPath(VMF_NS, thisPropertyPath.c_str(), VMF_NS, PROPERTY_SET, &thisPropertySetPath); for(auto metadata = property.begin(); metadata != property.end(); ++metadata) { saveMetadata(*metadata, thisPropertySetPath); } }
void MetadataStream::remove( const MetadataSet& set ) { std::for_each( set.begin(), set.end(), [&]( const std::shared_ptr<Metadata>& spMetadata ) { this->remove( spMetadata->getId() ); }); }
bool MetadataStream::import( MetadataStream& srcStream, MetadataSet& srcSet, long long nTarFrameIndex, long long nSrcFrameIndex, long long nNumOfFrames, MetadataSet* pSetFailure ) { // Find all schemes used by the source metadata set std::vector< std::string > vSchemaNames; std::for_each( srcSet.begin(), srcSet.end(), [&vSchemaNames]( std::shared_ptr<Metadata>& spMetadata ) { vSchemaNames.push_back( spMetadata->getSchemaName() ); }); // Remove redundant schema names std::sort( vSchemaNames.begin(), vSchemaNames.end() ); vSchemaNames.erase( std::unique( vSchemaNames.begin(), vSchemaNames.end() ), vSchemaNames.end()); // Import all schemes used std::for_each( vSchemaNames.begin(), vSchemaNames.end(), [&]( std::string& sAppName ) { if( this->getSchema( sAppName ) == nullptr ) { auto it = srcStream.m_mapSchemas.find( sAppName ); if( it != srcStream.m_mapSchemas.end()) this->addSchema( it->second ); else { VMF_EXCEPTION(InternalErrorException, "Metadata schema missing in the source stream!" ); } } }); // This map stores Id pairs<old, new> from the srcSet and this set. std::map< IdType, IdType > mapIds; // Import metadata one by one. std::for_each( srcSet.begin(), srcSet.end(), [&]( std::shared_ptr<Metadata>& spMetadata ) { if( import( srcStream, spMetadata, mapIds, nTarFrameIndex, nSrcFrameIndex, nNumOfFrames ) == nullptr && pSetFailure != NULL ) { pSetFailure->push_back( spMetadata ); } }); return mapIds.size() > 0; }
// setName == "" means all sets in the specified schema // schemaName == "" means all schemas (i.e. all metadata) void dumpMetadata(const string& path, const string& schemaName = "", const string& setName = "") { cout << "\nDumping metadata: " << (schemaName.empty() ? string("*") : schemaName + '/' + (setName.empty() ? string("*") : setName) ) << endl; MetadataStream ms; if (!ms.open(path, MetadataStream::ReadOnly)) throw std::runtime_error("Can't open MetadataStream"); vector<string> schemas; if(schemaName.empty()) ms.getAllSchemaNames().swap(schemas); else schemas.push_back(schemaName); for (unsigned int sNum = 0; sNum < schemas.size(); sNum++) { auto sName = schemas[sNum]; cout << "* (" << sNum << ") [schema]: " << sName << endl; if(!ms.load(sName)) throw std::runtime_error(string("Error loading schema: " + sName).c_str()); vector<shared_ptr<MetadataDesc>>mDescs; if(setName.empty()) ms.getSchema(sName)->getAll().swap(mDescs); else mDescs.push_back(ms.getSchema(sName)->findMetadataDesc(setName)); for (unsigned int setNum = 0; setNum < mDescs.size(); setNum++) { auto mDesc = mDescs[setNum]; string setName = mDesc->getMetadataName(); MetadataSet set = ms.queryByName(setName); cout << "\t* (" << sNum << "." << setNum << ") [set]: " << setName << "(" << set.size() << " items)" << endl; if(set.empty()) continue; vector<string> fields(set[0]->getFieldNames()); int itemNum = 0; for (auto item = set.begin(); item != set.end(); item++) { cout << "\t\t* (" << sNum << "." << setNum << "." << ++itemNum << ") { "; const char * separator = ""; for (auto f = fields.begin(); f != fields.end(); f++) { cout << separator << *f << "="; try { cout << (*item)->getFieldValue(*f).toString(); } catch(vmf::Exception& e) { cout << '<' << e.what() << '>'; } separator = ", "; } cout << " }" << endl; } } } }