| 148 | // *** Should someday check the full syntax. |
| 149 | |
| 150 | static void |
| 151 | VerifyXPathRoot ( XMP_StringPtr schemaURI, |
| 152 | XMP_StringPtr propName, |
| 153 | XMP_ExpandedXPath * expandedXPath ) |
| 154 | { |
| 155 | // Do some basic checks on the URI and name. Try to lookup the URI. See if the name is qualified. |
| 156 | |
| 157 | XMP_Assert ( (schemaURI != 0) && (propName != 0) && (*propName != 0) ); |
| 158 | XMP_Assert ( (expandedXPath != 0) && (expandedXPath->empty()) ); |
| 159 | |
| 160 | if ( *schemaURI == 0 ) XMP_Throw ( "Schema namespace URI is required", kXMPErr_BadSchema ); |
| 161 | |
| 162 | if ( (*propName == '?') || (*propName == '@') ) { |
| 163 | XMP_Throw ( "Top level name must not be a qualifier", kXMPErr_BadXPath ); |
| 164 | } |
| 165 | for ( XMP_StringPtr ch = propName; *ch != 0; ++ch ) { |
| 166 | if ( (*ch == '/') || (*ch == '[') ) { |
| 167 | XMP_Throw ( "Top level name must be simple", kXMPErr_BadXPath ); |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | XMP_StringMapPos uriPos = sNamespaceURIToPrefixMap->find ( XMP_VarString ( schemaURI ) ); |
| 172 | if ( uriPos == sNamespaceURIToPrefixMap->end() ) { |
| 173 | XMP_Throw ( "Unregistered schema namespace URI", kXMPErr_BadSchema ); |
| 174 | } |
| 175 | |
| 176 | XMP_StringPtr colonPos = propName; |
| 177 | while ( (*colonPos != 0) && (*colonPos != ':') ) ++colonPos; |
| 178 | VerifySimpleXMLName ( propName, colonPos ); // Verify the part before any colon. |
| 179 | |
| 180 | // Verify the various URI and prefix combinations. Initialize the expanded XPath. |
| 181 | |
| 182 | if ( *colonPos == 0 ) { |
| 183 | |
| 184 | // The propName is unqualified, use the schemaURI and associated prefix. |
| 185 | |
| 186 | expandedXPath->push_back ( XPathStepInfo ( schemaURI, kXMP_SchemaNode ) ); |
| 187 | expandedXPath->push_back ( XPathStepInfo ( uriPos->second, 0 ) ); |
| 188 | (*expandedXPath)[kRootPropStep].step += propName; |
| 189 | |
| 190 | } else { |
| 191 | |
| 192 | // The propName is qualified. Make sure the prefix is legit. Use the associated URI and qualified name. |
| 193 | |
| 194 | size_t prefixLen = colonPos - propName + 1; // ! Include the colon. |
| 195 | VerifySimpleXMLName ( colonPos+1, colonPos+strlen(colonPos) ); |
| 196 | |
| 197 | XMP_VarString prefix ( propName, prefixLen ); |
| 198 | XMP_StringMapPos prefixPos = sNamespacePrefixToURIMap->find ( prefix ); |
| 199 | if ( prefixPos == sNamespacePrefixToURIMap->end() ) { |
| 200 | XMP_Throw ( "Unknown schema namespace prefix", kXMPErr_BadSchema ); |
| 201 | } |
| 202 | if ( prefix != uriPos->second ) { |
| 203 | XMP_Throw ( "Schema namespace URI and prefix mismatch", kXMPErr_BadSchema ); |
| 204 | } |
| 205 | |
| 206 | expandedXPath->push_back ( XPathStepInfo ( schemaURI, kXMP_SchemaNode ) ); |
| 207 | expandedXPath->push_back ( XPathStepInfo ( propName, 0 ) ); |
no test coverage detected