bool HandleConstAlias( const spIMetadata & meta, spINode & destNode, const XMP_ExpandedXPath & expandedXPath, sizet & nodeIndex ) { if ( expandedXPath.empty() ) NOTIFY_ERROR( IError::kEDGeneral, kGECLogicalError, "Empty XPath", IError::kESOperationFatal, false, false ); if ( !( expandedXPath[ kSchemaStep ].options & kXMP_SchemaNode ) ) { return false; } else { XMP_VarString namespaceName = expandedXPath[ kSchemaStep ].step.c_str(); size_t colonPos = expandedXPath[ kRootPropStep ].step.find( ":" ); assert( colonPos != std::string::npos ); XMP_VarString propertyName = expandedXPath[ kRootPropStep ].step.substr( colonPos + 1 ); // here find the node with this name destNode = meta->GetNode( namespaceName.c_str(), namespaceName.size(), propertyName.c_str(), propertyName.size() ); if ( !destNode ) return false; if ( expandedXPath.size() == 2 ) return true; assert( destNode->GetNodeType() == INode::kNTArray ); if ( expandedXPath[ 2 ].options == kXMP_ArrayIndexStep ) { assert( expandedXPath[ 2 ].step == "[1]" ); destNode = destNode->ConvertToArrayNode()->GetNodeAtIndex( 1 ); auto actualNodeType = destNode->GetNodeType(); if ( destNode ) { if ( nodeIndex ) nodeIndex = 1; return true; } return false; } else if ( expandedXPath[ 2 ].options == kXMP_QualSelectorStep ) { assert( expandedXPath[ 2 ].step == "[?xml:lang=\"x-default\"]" ); if ( !destNode || destNode->GetNodeType() != INode::kNTArray ) return false; spINodeIterator iter = destNode->ConvertToArrayNode()->Iterator(); sizet index = 1; while ( iter ) { spINode node = iter->GetNode(); try { spISimpleNode qualNode = node->GetSimpleQualifier( "http://www.w3.org/XML/1998/namespace", AdobeXMPCommon::npos, "lang", AdobeXMPCommon::npos ); if ( qualNode->GetValue()->compare( "x-default" ) == 0 ) { destNode = node; if ( nodeIndex ) nodeIndex = index; return true; } } catch ( spcIError err ) { } catch ( ... ) {} index++; iter = iter->Next(); } return false; } return false; } }
bool HandleNonConstAlias( const spIMetadata & meta, XMP_ExpandedXPath & expandedXPath, bool createNodes, XMP_OptionBits leafOptions, spINode & destNode, sizet & nodeIndex, bool ignoreLastStep, const spINode & inputNode ) { destNode = meta; spcIUTF8String inputNodeValue; if ( inputNode && inputNode->GetNodeType() == INode::kNTSimple ) { inputNodeValue = inputNode->ConvertToSimpleNode()->GetValue(); } bool isAliasBeingCreated = expandedXPath.size() == 2; if ( expandedXPath.empty() ) NOTIFY_ERROR( IError::kEDDataModel, kDMECBadXPath, "Empty XPath", IError::kESOperationFatal, false, false ); if ( !( expandedXPath[ kSchemaStep ].options & kXMP_SchemaNode ) ) { return false; } else { XMP_VarString namespaceName = expandedXPath[ kSchemaStep ].step.c_str(); size_t colonPos = expandedXPath[ kRootPropStep ].step.find( ":" ); assert( colonPos != std::string::npos ); XMP_VarString propertyName = expandedXPath[ kRootPropStep ].step.substr( colonPos + 1 ); spcINode childNode = meta->GetNode( namespaceName.c_str(), namespaceName.size(), propertyName.c_str(), propertyName.size() ); if ( !childNode && !createNodes ) return false; if ( expandedXPath.size() == 2 ) { if ( childNode ) return true; XMP_OptionBits createOptions = 0; spINode tempNode; if ( isAliasBeingCreated ) tempNode = CreateTerminalNode( namespaceName.c_str(), propertyName.c_str(), leafOptions ); else tempNode = CreateTerminalNode( namespaceName.c_str(), propertyName.c_str(), createOptions ); if ( !tempNode ) return false; if ( inputNodeValue ) tempNode->ConvertToSimpleNode()->SetValue( inputNodeValue->c_str(), inputNodeValue->size() ); if ( destNode == meta ) { meta->InsertNode( tempNode ); } else { destNode->ConvertToStructureNode()->AppendNode( tempNode ); } destNode = tempNode; if ( destNode ) return true; return false; } XMP_Assert( expandedXPath.size() == 3 ); if ( expandedXPath[ 2 ].options == kXMP_ArrayIndexStep ) { XMP_Assert( expandedXPath[ 2 ].step == "[1]" ); destNode = meta->GetNode( namespaceName.c_str(), namespaceName.size(), propertyName.c_str(), propertyName.size() ); if ( !destNode && !createNodes ) return false; if ( !destNode ) { spINode arrayNode = CreateTerminalNode( namespaceName.c_str(), propertyName.c_str(), kXMP_PropArrayIsOrdered | kXMP_PropValueIsArray ); meta->AppendNode( arrayNode ); destNode = arrayNode; } if ( destNode->ConvertToArrayNode()->GetNodeAtIndex( 1 ) ) { destNode = destNode->ConvertToArrayNode()->GetNodeAtIndex( 1 ); if ( nodeIndex ) nodeIndex = 1; return true; } else { spISimpleNode indexNode = ISimpleNode::CreateSimpleNode( namespaceName.c_str(), namespaceName.size(), propertyName.c_str(), propertyName.size() ); if ( inputNodeValue ) { indexNode->SetValue( inputNodeValue->c_str(), inputNodeValue->size() ); } destNode->ConvertToArrayNode()->InsertNodeAtIndex( indexNode, 1 ); destNode = indexNode; return true; } return false; } else if ( expandedXPath[ 2 ].options == kXMP_QualSelectorStep ) { assert( expandedXPath[ 2 ].step == "[?xml:lang=\"x-default\"]" ); destNode = meta->GetNode( namespaceName.c_str(), namespaceName.size(), propertyName.c_str(), propertyName.size() ); if ( !destNode && !createNodes ) return false; spINode arrayNode = CreateTerminalNode( namespaceName.c_str(), propertyName.c_str(), kXMP_PropValueIsArray | kXMP_PropArrayIsAltText); meta->AppendNode( arrayNode ); destNode = arrayNode; auto iter = destNode->ConvertToArrayNode()->Iterator(); XMP_Index index = 1; while ( iter ) { spINode node = iter->GetNode(); spINode qualNode = node->GetQualifier( "http://www.w3.org/XML/1998/namespace", AdobeXMPCommon::npos, "lang", AdobeXMPCommon::npos ); if ( qualNode->GetNodeType() == INode::kNTSimple ) { if ( !qualNode->ConvertToSimpleNode()->GetValue()->compare( "x-default" ) ) { destNode = node; if ( nodeIndex ) nodeIndex = index; return true; } } index++; iter = iter->Next(); } spISimpleNode qualifierNode = ISimpleNode::CreateSimpleNode( "http://www.w3.org/XML/1998/namespace", AdobeXMPCommon::npos, "lang", AdobeXMPCommon::npos, "x-default", AdobeXMPCommon::npos ); if ( destNode->ConvertToArrayNode()->GetNodeAtIndex( 1 ) ) { destNode = destNode->ConvertToArrayNode()->GetNodeAtIndex( 1 ); if ( nodeIndex ) nodeIndex = 1; destNode->InsertQualifier( qualifierNode ); return true; } else { spISimpleNode indexNode = ISimpleNode::CreateSimpleNode( namespaceName.c_str(), AdobeXMPCommon::npos, propertyName.c_str(), AdobeXMPCommon::npos ); if ( inputNodeValue ) { indexNode->SetValue( inputNodeValue->c_str(), inputNodeValue->size() ); } destNode->ConvertToArrayNode()->InsertNodeAtIndex( indexNode, 1 ); destNode->InsertQualifier( qualifierNode ); destNode = indexNode; return true; } } } return false; }