| 422 | // pruned when they are no longer needed. |
| 423 | |
| 424 | XMPIterator::XMPIterator ( const XMPMeta & xmpObj, |
| 425 | XMP_StringPtr schemaNS, |
| 426 | XMP_StringPtr propName, |
| 427 | XMP_OptionBits options ) : clientRefs(0), info(IterInfo(options,&xmpObj)) |
| 428 | { |
| 429 | if ( (options & kXMP_IterClassMask) != kXMP_IterProperties ) { |
| 430 | XMP_Throw ( "Unsupported iteration kind", kXMPErr_BadOptions ); |
| 431 | } |
| 432 | |
| 433 | // *** Lock the XMPMeta object if we ever stop using a full DLL lock. |
| 434 | |
| 435 | if ( *propName != 0 ) { |
| 436 | |
| 437 | // An iterator rooted at a specific node. |
| 438 | |
| 439 | #if TraceIterators |
| 440 | printf ( "\nNew XMP property iterator for \"%s\", options = %X\n Schema = %s, root = %s\n", |
| 441 | xmpObj.tree.name.c_str(), options, schemaNS, propName ); |
| 442 | #endif |
| 443 | |
| 444 | XMP_ExpandedXPath propPath; |
| 445 | ExpandXPath ( schemaNS, propName, &propPath ); |
| 446 | XMP_Node * propNode = FindConstNode ( &xmpObj.tree, propPath ); // If not found get empty iteration. |
| 447 | |
| 448 | if ( propNode != 0 ) { |
| 449 | |
| 450 | XMP_VarString rootName ( propPath[1].step ); // The schema is [0]. |
| 451 | for ( size_t i = 2; i < propPath.size(); ++i ) { |
| 452 | XMP_OptionBits stepKind = GetStepKind ( propPath[i].options ); |
| 453 | if ( stepKind <= kXMP_QualifierStep ) rootName += '/'; |
| 454 | rootName += propPath[i].step; |
| 455 | } |
| 456 | |
| 457 | propName = rootName.c_str(); |
| 458 | size_t leafOffset = rootName.size(); |
| 459 | while ( (leafOffset > 0) && (propName[leafOffset] != '/') && (propName[leafOffset] != '[') ) --leafOffset; |
| 460 | if ( propName[leafOffset] == '/' ) ++leafOffset; |
| 461 | |
| 462 | info.tree.children.push_back ( IterNode ( propNode->options, propName, leafOffset ) ); |
| 463 | SetCurrSchema ( info, propPath[kSchemaStep].step.c_str() ); |
| 464 | if ( info.options & kXMP_IterJustChildren ) { |
| 465 | AddNodeOffspring ( info, info.tree.children.back(), propNode ); |
| 466 | } |
| 467 | |
| 468 | } |
| 469 | |
| 470 | } else if ( *schemaNS != 0 ) { |
| 471 | |
| 472 | // An iterator for all properties in one schema. |
| 473 | |
| 474 | #if TraceIterators |
| 475 | printf ( "\nNew XMP schema iterator for \"%s\", options = %X\n Schema = %s\n", |
| 476 | xmpObj.tree.name.c_str(), options, schemaNS ); |
| 477 | #endif |
| 478 | |
| 479 | info.tree.children.push_back ( IterNode ( kXMP_SchemaNode, schemaNS, 0 ) ); |
| 480 | IterNode & iterSchema = info.tree.children.back(); |
| 481 |
nothing calls this directly
no test coverage detected