/usr/include/dcmtk/dcmsr/dsrdocst.h is in libdcmtk-dev 3.6.2-3build3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 | /*
*
* Copyright (C) 2000-2017, OFFIS e.V.
* All rights reserved. See COPYRIGHT file for details.
*
* This software and supporting documentation were developed by
*
* OFFIS e.V.
* R&D Division Health
* Escherweg 2
* D-26121 Oldenburg, Germany
*
*
* Module: dcmsr
*
* Author: Joerg Riesmeier
*
* Purpose:
* classes: DSRDocumentSubTree
*
*/
#ifndef DSRDOCST_H
#define DSRDOCST_H
#include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
#include "dcmtk/dcmsr/dsrtree.h"
#include "dcmtk/dcmsr/dsrdoctn.h"
#include "dcmtk/dcmsr/dsrdncsr.h"
#include "dcmtk/dcmsr/dsrcitem.h"
#include "dcmtk/ofstd/ofmem.h"
/*------------------------*
* forward declarations *
*------------------------*/
class DSRIODConstraintChecker;
class DSRSubTemplate;
/*-------------------*
* type definition *
*-------------------*/
typedef OFshared_ptr<DSRSubTemplate> DSRSharedSubTemplate;
/*--------------------------*
* template instantiation *
*--------------------------*/
// the following is required in order to help older Clang compilers,
// e.g. Clang 3.0 and 3.1 on Mac OS X when building with shared libs
#if defined(__clang__)
template class DSRTree<DSRDocumentTreeNode>;
#endif
/*---------------------*
* class declaration *
*---------------------*/
/** Class managing a SR document subtree.
* A subtree represents an extract of an SR document tree. Compared to the "SR Document
* Content Tree" that is defined in the DICOM standard, there are almost no restrictions
* regarding the value and relationship types. It is also possible to have multiple nodes
* on the top-level, i.e. no dedicated root, or to use "unknown" relationship types.
*/
class DCMTK_DCMSR_EXPORT DSRDocumentSubTree
: public DSRTree<DSRDocumentTreeNode>
{
public:
/** default constructor
*/
DSRDocumentSubTree();
/** copy constructor.
* Please note that the internal cursor is not copied but reset, i.e. set to the root
* node. Also the IOD constraint checker is not copied by this class but recreated
* by the derived class DSRDocumentTree (based on the corresponding document type).
* This constructor also updates any by-reference relationships, i.e. translates the
* references from the source 'tree' (based on the position string) to the IDs of the
* newly created nodes.
** @param tree subtree to be copied
*/
DSRDocumentSubTree(const DSRDocumentSubTree &tree);
/** destructor
*/
virtual ~DSRDocumentSubTree();
/** assignment operator.
* Please note that internally the copy constructor is used, so the same comments apply.
** @param tree subtree to be copied
** @return reference to this subtree after copying
*/
DSRDocumentSubTree &operator=(DSRDocumentSubTree tree);
/** clone this subtree.
* Internally, the copy constructor is used, so the corresponding comments apply.
** @return copy of this subtree
*/
virtual DSRDocumentSubTree *clone() const;
/** clear internal member variables
*/
virtual void clear();
/** check whether the current internal state is valid.
* A subtree is valid if it is not empty.
** @return OFTrue if valid, OFFalse otherwise
*/
virtual OFBool isValid() const;
/** check whether the internal cursor, which points to the current content item, is valid
** @return OFTrue if cursor is valid, OFFalse otherwise
*/
virtual OFBool isCursorValid() const;
/** check whether this subtree is a valid document tree.
* In order to be a valid document tree, there should be a single root node only, with
* the value type "CONTAINER", and the internal relationship type of this node should be
* DSRTypes::RT_isRoot.
** @param defaultRelType default relationship type that is used if the one of the
* top-level node (root node) is "unknown"
** @return OFTrue if subtree is a valid document tree, OFFalse otherwise
*/
virtual OFBool isValidDocumentTree(const E_RelationshipType defaultRelType = RT_unknown) const;
/** check whether this subtree is an expanded document tree.
* Expanded means that no instances of DSRIncludedTemplateTreeNode exist in the document
* tree, i.e. no templates were included or all of them were replaced by their content
* (subtree).
** @return OFTrue if subtree is an expanded document tree, OFFalse otherwise
*/
virtual OFBool isExpandedDocumentTree() const;
/** check whether template identification is set
** @return OFTrue if template identification is set, OFFalse otherwise
*/
virtual OFBool hasTemplateIdentification() const;
/** check whether template identification is possible at all.
* According to the DICOM standard, it can be used if "the template consists of a single
* CONTAINER with nested content, and it is the outermost invocation of a set of nested
* templates that start with the same CONTAINER."
* With other words, the tree should have a single root node with value type "CONTAINER".
** @return OFTrue if template identification is possible, OFFalse otherwise
*/
virtual OFBool canUseTemplateIdentification() const;
/** print current SR document tree to specified output stream
** @param stream output stream
* @param flags optional flag used to customize the output (see DSRTypes::PF_xxx)
* @param posCounter optional pointer to position counter that should be used to
* initialize the counter for line indentation or numbering of
* nested content items
** @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition print(STD_NAMESPACE ostream &stream,
const size_t flags = 0,
const DSRPositionCounter *posCounter = NULL);
/** write current SR document tree in XML format
** @param stream output stream to which the XML document is written
* @param flags optional flag used to customize the output (see DSRTypes::XF_xxx)
** @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition writeXML(STD_NAMESPACE ostream &stream,
const size_t flags = 0);
/** get reference to current content item.
* This mechanism allows to access all content items without using pointers.
** @return reference to current content item (might be invalid)
*/
virtual DSRContentItem &getCurrentContentItem();
/** get read-only access to current node (content item)
** @return pointer to current node (might be NULL)
*/
virtual const DSRDocumentTreeNode *getCurrentNode() const;
/** get a cursor to the root node of this document tree.
* This cursor can be used to iterate over the nodes of the document tree without
* changing the internal cursor. Please note that the cursor might become invalid,
* e.g. by pointing to a non-existing node if the content of the document tree is
* modified after the cursor has been retrieved.
* Included sub-templates are not supported by this type of cursor, i.e. the subtree
* that is managed by an instance of DSRIncludedTemplateTreeNode is not iterated.
** @param cursor reference to variable where the cursor is stored
** @return OFTrue is the returned 'cursor' is valid, OFFalse otherwise
*/
virtual OFBool getCursorToRootNode(DSRDocumentTreeNodeCursor &cursor) const;
/** get a cursor to the root node of this document tree.
* This cursor can be used to iterate over the nodes of the document tree without
* changing the internal cursor. Please note that the cursor might become invalid,
* e.g. by pointing to a non-existing node if the content of the document tree is
* modified after the cursor has been retrieved.
* This type of cursor also supports included sub-templates, i.e. the subtree that
* is managed by an instance of DSRIncludedTemplateTreeNode is also iterated.
** @param cursor reference to variable where the cursor is stored
** @return OFTrue is the returned 'cursor' is valid, OFFalse otherwise
*/
virtual OFBool getCursorToRootNode(DSRIncludedTemplateNodeCursor &cursor) const;
/** count number of content items (nodes) in the document tree.
* This method iterates over all nodes that are stored in the document tree.
* By default, included sub-templates are counted as a single node (see options).
** @param searchIntoSubTemplates optional flag indicating whether to also
* count the content of included sub-templates
* (i.e.\ the nodes of the managed subtrees)
* @param countIncludedTemplateNodes optional flag indicating whether to count
* the DSRIncludedTemplateTreeNode instances
* as nodes. See includeTemplate() for details.
** @return number of nodes, 0 if document tree is empty
*/
size_t countNodes(const OFBool searchIntoSubTemplates = OFFalse,
const OFBool countIncludedTemplateNodes = OFTrue) const;
/** set internal cursor to a named node.
* If more than one node exists with the given concept name, the first one will
* be selected. Use gotoNextNamedNode() in order to go to the next matching node.
** @param conceptName concept name of the node to be searched for
* @param startFromRoot flag indicating whether to start from the root node
* or the current one
* @param searchIntoSub flag indicating whether to search into sub-trees
* ("deep search") or on the current level only
** @return ID of the new current node if successful, 0 otherwise
*/
virtual size_t gotoNamedNode(const DSRCodedEntryValue &conceptName,
const OFBool startFromRoot = OFTrue,
const OFBool searchIntoSub = OFTrue);
/** set internal cursor to a named node (starting from the first child of the
* current node and searching on this level only).
* This is just a shortcut for calling gotoChild() followed by gotoNamedNode()
* with 'searchIntoSub' being OFFalse, i.e. only the first sub-level is checked.
* If more than one node exists with the given concept name, the first one will
* be selected.
** @param conceptName concept name of the node to be searched for
** @return ID of the new current node if successful, 0 otherwise
*/
virtual size_t gotoNamedChildNode(const DSRCodedEntryValue &conceptName);
/** set internal cursor to a named node in the subtree below the current node.
* If more than one node exists with the given concept name, the first one will
* be selected. If the current node has no children, the cursor is not moved.
** @param conceptName concept name of the node to be searched for
* @param searchIntoSub flag indicating whether to search into sub-trees
* ("deep search") or on the first sub-level only
** @return ID of the new current node if successful, 0 otherwise
*/
virtual size_t gotoNamedNodeInSubTree(const DSRCodedEntryValue &conceptName,
const OFBool searchIntoSub = OFTrue);
/** set internal cursor to the next named node.
* Starts from "next" node, i.e. either the first child of the current node
* or the first sibling following the current node.
** @param conceptName concept name of the node to be searched for
* @param searchIntoSub flag indicating whether to search into sub-trees
* ("deep search") or on the current level only
** @return ID of the new current node if successful, 0 otherwise
*/
virtual size_t gotoNextNamedNode(const DSRCodedEntryValue &conceptName,
const OFBool searchIntoSub = OFTrue);
/** set internal cursor to an annotated node.
* If more than one node exists with the given annotation text, the first one will
* be selected. Use gotoNextAnnotatedNode() in order to go to the next matching
* node. In contrast to gotoNamedNode(), a "deep search" is always performed.
** @param annotationText annotation text of the node to be searched for
* @param startFromRoot flag indicating whether to start from the root node
* or the current one
** @return ID of the new current node if successful, 0 otherwise
*/
virtual size_t gotoAnnotatedNode(const OFString &annotationText,
const OFBool startFromRoot = OFTrue);
/** set internal cursor to the next annotated node.
* Starts from "next" node, i.e. either the first child of the current node
* or the first sibling following the current node.
** @param annotationText annotation text of the node to be searched for
** @return ID of the new current node if successful, 0 otherwise
*/
virtual size_t gotoNextAnnotatedNode(const OFString &annotationText);
/** check whether specified content item can be added to the current one.
* This method can be used to decide which type of content items can be added prior
* to really doing so. Please note that only by-value relationships are supported.
* Always returns true if no constraint checker is available but 'relationshipType'
* and 'valueType' have valid values.
** @param relationshipType relationship type of node to be checked with regard to
* the current one
* @param valueType value type of node to be checked
* @param addMode flag specifying at which position the new node would
* be added (e.g. after or below the current node)
** @return OFTrue if specified node can be added, OFFalse otherwise
*/
virtual OFBool canAddContentItem(const E_RelationshipType relationshipType,
const E_ValueType valueType,
const E_AddMode addMode = AM_afterCurrent) const;
/** check whether specified by-reference relationship can be added to the current
* content item.
* Always returns true if no constraint checker is available but 'relationshipType' and
* 'targetValueType' have valid values. The value type DSRTypes::VT_includedTemplate is
* never allowed for the target content item.
** @param relationshipType type of relationship between current and target node
* @param targetValueType value type of the referenced node (target content item)
** @return OFTrue if specified by-reference relationship can be added, OFFalse otherwise
*/
virtual OFBool canAddByReferenceRelationship(const E_RelationshipType relationshipType,
const E_ValueType targetValueType) const;
/** add specified content item to the current one.
* If possible, this method creates a new node as specified and adds it to the current
* one. The method canAddContentItem() is called internally to check parameters first.
* If the node could be added successfully, the cursor is set to it automatically.
** @param relationshipType relationship type of node to be added with regard to
* the current one
* @param valueType value type of node to be added
* @param addMode flag specifying at which position to add the new node
* (e.g. after or below the current node)
** @return ID of new node if successful, 0 otherwise
*/
virtual size_t addContentItem(const E_RelationshipType relationshipType,
const E_ValueType valueType,
const E_AddMode addMode = AM_afterCurrent);
/** add specified content item to the current one.
* If possible, this method adds a given new node to the current one. The method
* canAddContentItem() is called internally to check parameters first. If the
* node could be added successfully, the cursor is set to it automatically.
* Please note that no copy of the given node is created. Therefore, the node
* has to be created with new() or with DSRTypes::createDocumentTreeNode() - do
* not use a reference to a local variable and do not delete it a second time.
** @param node pointer to the new node to be added (should not be empty).
* Reference remains valid after successful insertion.
* @param addMode flag specifying at which position to add the new node
* (e.g. after or below the current node)
* @param deleteIfFail flag specifying whether to delete the given 'node' if
* adding fails. By default, the item is not deleted, i.e.
* in case of error it has to be deleted by the caller.
** @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition addContentItem(DSRDocumentTreeNode *node,
const E_AddMode addMode = AM_afterCurrent,
const OFBool deleteIfFail = OFFalse);
/** add specified content item after the current one.
* If possible, this method creates a new node as specified and adds it after the current
* one, i.e. on the same level. Internally, the first variant of the addContentItem()
* method is called with the third parameter being DSRTypes::AM_afterCurrent. If
* successful, the given concept name is set for the new node, and the cursor is updated.
* @note This is a convenience function that avoids calling several other functions.
** @param relationshipType relationship type of node to be added with regard
* to the current one
* @param valueType value type of node to be added
* @param conceptName concept name of the node to be added
* @param check if enabled, check 'conceptName for validity before setting it
** @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition addContentItem(const E_RelationshipType relationshipType,
const E_ValueType valueType,
const DSRCodedEntryValue &conceptName,
const OFBool check = OFTrue);
/** add specified content item below the current one.
* If possible, this method creates a new node as specified and adds it below the current
* one, i.e. as a child. Internally, the first variant of the addContentItem() method
* is called with the third parameter being DSRTypes::AM_belowCurrent. If successful,
* the given concept name is set for the new node, and the cursor is updated.
* @note This is a convenience function that avoids calling several other functions.
** @param relationshipType relationship type of node to be added with regard
* to the current one
* @param valueType value type of node to be added
* @param conceptName concept name of the node to be added
* @param check if enabled, check 'conceptName for validity before setting it
** @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition addChildContentItem(const E_RelationshipType relationshipType,
const E_ValueType valueType,
const DSRCodedEntryValue &conceptName,
const OFBool check = OFTrue);
/** add specified by-reference relationship to the current content item.
* If possible, this method creates a new pseudo-node (relationship) and adds it to the
* current one. The method canAddByReferenceRelationship() is called internally to check
* parameters first. The internal cursor is automatically re-set to the current node.
** @param relationshipType relationship type between current and referenced node
* @param referencedNodeID ID of the referenced node (target content item)
** @return ID of new pseudo-node if successful, 0 otherwise
*/
virtual size_t addByReferenceRelationship(const E_RelationshipType relationshipType,
const size_t referencedNodeID);
/** update the position strings used to encode by-reference relationships (if any).
* Internally, this method calls checkByReferenceRelationships() with the 'mode'
* parameter being DSRTypes::CM_updatePositionString. It should be called before
* this subtree is cloned in order to make sure that the by-reference relationships
* (if any) still work on the cloned subtree. This method should also be called
* before accessing the position string of a referenced content item, see
* DSRByReferenceTreeNode::getReferencedContentItem().
** @param updateIncludedTemplates optional flag indicating whether to also update
* the subtrees managed by included sub-templates
** @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition updateByReferenceRelationships(const OFBool updateIncludedTemplates = OFFalse);
/** check whether specified subtree can be inserted at the current position, i.e.\ added
* to the current content item. Internally, the method canAddContentItem() is used for
* all top-level nodes of the document subtree. In addition, if a constraint checker
* is available, the remaining nodes of the given subtree are also checked for their
* compliance with the relationship content constraints of the underlying SR IOD.
** @param tree pointer to new subtree to be inserted (should not be empty)
* @param addMode flag specifying at which position the new subtree would
* be added (e.g. after or below the current node)
* @param defaultRelType default relationship type between the top-level nodes of
* the given subtree and the current node. This relationship
* type is used if the one of a top-level node is "unknown".
** @return OFTrue if specified subtree can be inserted, OFFalse otherwise
*/
virtual OFBool canInsertSubTree(const DSRDocumentSubTree *tree,
const E_AddMode addMode = AM_belowCurrent,
const E_RelationshipType defaultRelType = RT_unknown) const;
/** insert specified subtree to this tree, i.e.\ add it to the current content item.
* If possible, this method adds a given new subtree to the current content item.
* The method canInsertSubTree() is called internally to check the parameters first.
* Please note that no copy of the given subtree is created. Therefore, the subtree
* has to be created with new() or with cloneSubTree() - do not use a reference to a
* local variable and do not delete it a second time.
** @param tree pointer to new subtree to be inserted (should not be empty).
* Reference becomes invalid after successful insertion!
* @param addMode flag specifying at which position to add the new subtree
* (e.g. after or below the current node)
* @param defaultRelType default relationship type between the top-level nodes of
* the given subtree and the current node. This relationship
* type is used if the one of a top-level node is "unknown".
* @param deleteIfFail flag specifying whether to delete the given 'tree' if
* adding fails. By default, the tree is not deleted, i.e.
* in case of error it has to be deleted by the caller.
** @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition insertSubTree(DSRDocumentSubTree *tree,
const E_AddMode addMode = AM_belowCurrent,
const E_RelationshipType defaultRelType = RT_unknown,
const OFBool deleteIfFail = OFFalse);
/** extract a subtree i.e.\ a fragment from this tree.
* The subtree is specified by the current node, which becomes the root of the subtree.
* In contrast to cloneSubTree(), this method also makes sure that the by-reference
* relationships are preserved (as long as both source and target node are contained
* in the same tree). Please note that the returned subtree has to be deleted by the
* caller if it is not inserted into the document tree using insertSubTree().
** @return pointer to the extracted subtree, NULL in case of error
*/
virtual DSRDocumentSubTree *extractSubTree();
/** remove current content item from tree.
* Please note that not only the specified node but also all of its child nodes are
* removed from the tree and then deleted. The internal cursor is set automatically
* to a new valid position.
** @return ID of the node which became the current one after deletion, 0 if an error
* occurred or the tree is now empty.
*/
virtual size_t removeCurrentContentItem();
/** remove a subtree from this tree.
* The subtree to be removed (and deleted) is either specified by the current node or by
* the node with the given ID. Afterwards, the internal cursor is set automatically to
* a new valid position. It would be an error to remove a subtree from an empty tree.
** @param searchID ID of the root node specifying the subtree to be removed.
* By default (0), the current node is used.
** @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition removeSubTree(const size_t searchID = 0);
/** clone the current tree node.
* Internally, the copy constructor of the respective tree node class is used, so the
* corresponding comments apply. Please note that the returned tree node has to be
* deleted by the caller if it is not added to the document tree using addContentItem().
** @return pointer to a copy of the current tree node, NULL in case of error
*/
virtual DSRDocumentTreeNode *cloneCurrentTreeNode() const;
/** clone a subtree i.e.\ a fragment of this tree.
* The cloning starts with the current node and ends with the given node.
* Please note that the returned subtree has to be deleted by the caller if it is not
* inserted into the document tree using insertSubTree().
** @param stopAfterNodeID ID of the node after which the cloning should stop.
* By default (0), the process ends after cloning the
* current node with all of its child nodes (if any).
** @return pointer to a copy of the specified subtree, NULL in case of error
*/
virtual DSRDocumentSubTree *cloneSubTree(const size_t stopAfterNodeID = 0) const;
/** created an expanded version of this (sub)tree.
* Expanded means that no instance of DSRIncludedTemplateTreeNode will exist in the new
* document tree, i.e. all of them are replaced by their content (subtree). Please note
* that the returned subtree has to be deleted by the caller if it is not inserted into
* the document tree using insertSubTree().
** @param tree variable that will store the pointer to the new subtree
** @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition createExpandedSubTree(DSRDocumentSubTree *&tree) const;
/** compare template identification of the root node with given values.
* Please note that the comparison only takes place if there is a single node at the
* root of the tree and its value type is CONTAINER.
** @param templateIdentifier template identifier to compare with
* @param mappingResource mapping resource that defines the template
* @param mappingResourceUID uniquely identifies the mapping resource (optional).
* Not used for comparison if the value is empty.
** @result OFTrue if template identification can be compared and the values are
* identical, OFFalse otherwise
*/
virtual OFBool compareTemplateIdentification(const OFString &templateIdentifier,
const OFString &mappingResource,
const OFString &mappingResourceUID = "") const;
/** get template identifier and mapping resource from the root node of this tree. See
* DSRDocumentTreeNode::getTemplateIdentification() for details on template identification.
* Please note that the template identification is only retrieved if there is a single node
* at the root of the tree and its value type is CONTAINER.
** @param templateIdentifier identifier of the template (might be empty)
* @param mappingResource mapping resource that defines the template (might be empty)
** @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition getTemplateIdentification(OFString &templateIdentifier,
OFString &mappingResource) const;
/** get template identifier, mapping resource and optional mapping resource UID from the
* root node of this tree. See DSRDocumentTreeNode::getTemplateIdentification() for
* details on template identification.
* Please note that the template identification is only retrieved if there is a single node
* at the root of the tree and its value type is CONTAINER.
** @param templateIdentifier identifier of the template (might be empty)
* @param mappingResource mapping resource that defines the template (might be empty)
* @param mappingResourceUID uniquely identifies the mapping resource (might be empty)
** @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition getTemplateIdentification(OFString &templateIdentifier,
OFString &mappingResource,
OFString &mappingResourceUID) const;
/** set template identifier and mapping resource to the root node of this tree.
* The identification is valid if the first two values are either present (non-empty) or
* all three values are absent (empty). See DSRDocumentTreeNode::getTemplateIdentification()
* for details.
* Please note that the template identification is only set if there is a single node at
* the root of the tree and its value type is CONTAINER.
** @param templateIdentifier identifier of the template to be set
* @param mappingResource mapping resource that defines the template
* @param mappingResourceUID uniquely identifies the mapping resource (optional)
* @param check check 'templateIdentifier', 'mappingResource' and
* 'mappingResourceUID' for conformance with VR (CS,UI) and
* VM (1) if enabled
** @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition setTemplateIdentification(const OFString &templateIdentifier,
const OFString &mappingResource,
const OFString &mappingResourceUID = "",
const OFBool check = OFTrue);
protected:
/** special constructor that receives a pointer to the root node.
* Please note that the 'rootNode' and the associated tree is not copied!
** @param rootNode pointer to the root node of the "new" tree
*/
DSRDocumentSubTree(DSRDocumentTreeNode *rootNode);
/** special copy constructor that clones a particular subtree only
** @param startCursor first node of the subtree to be copied
* @param stopAfterNodeID ID of the node after which the cloning should stop
*/
DSRDocumentSubTree(const DSRDocumentTreeNodeCursor &startCursor,
size_t stopAfterNodeID);
/** fast, non-throwing swap function.
* The time complexity of this function is constant.
** @param tree subtree to swap with
*/
void swap(DSRDocumentSubTree &tree);
/** get pointer to current node.
* Hide this inherited method from the public interface.
** @return pointer to current node (might be NULL)
*/
virtual DSRDocumentTreeNode *getNode() const;
/** add new node to the current one.
* Please note that no copy of the given node is created. Therefore, the node
* has to be created with new() - do not use a reference to a local variable.
* If the node could be added successfully, the cursor is set to it automatically.
** @param node pointer to the new node to be added
* @param addMode flag specifying at which position to add the new node
* (e.g. after or below the current node)
** @return ID of the new node if successful, 0 otherwise
*/
virtual size_t addNode(DSRDocumentTreeNode *node,
const E_AddMode addMode = AM_afterCurrent);
/** replace current node by the given one.
* Please note that no copy of the given node is created. Therefore, the node
* should be created with new() - do not use a reference to a local variable. If
* the node could be replaced successfully, the "old" node (and all of its child
* nodes) are deleted, and the cursor is set to the new one.
** @param node pointer to the new node to replace the current one
** @return ID of the new node if successful, 0 otherwise
*/
virtual size_t replaceNode(DSRDocumentTreeNode *node);
/** extract current node from tree.
* Please note that not only the specified node but also all of its child nodes are
* extracted from the tree. The cursor is set automatically to a new valid position.
** @return pointer to extracted node, NULL in case of error (or the tree was empty)
*/
virtual DSRDocumentTreeNode *extractNode();
/** get pointer to root node and "forget" the internal reference to this node.
* In other words: after calling this method, the stored tree will be empty.
* This also means that the caller is responsible for deleting the allocated memory.
** @return pointer to root node, might be NULL (empty tree)
*/
virtual DSRDocumentTreeNode *getAndRemoveRootNode();
/** remove current node from tree.
* Please note that not only the specified node but also all of his child nodes are
* removed from the tree and deleted afterwards. The cursor is set automatically to
* a new valid position.
** @return ID of the node which became the current one after deletion, 0 if an error
* occurred or the tree is now empty.
*/
virtual size_t removeNode();
/** include specified sub-template, i.e.\ add a new DSRIncludedTemplateTreeNode, which
* references this template, to the current content item.
* Please note that no checks are performed that would make sure that the template
* with its top-level nodes can actually be added, e.g. by using an IOD constraint
* checker. This is also the reason why this method is "protected" and not "public",
* i.e. it can only be used by derived classes, e.g. DSRSubTemplate and its children.
** @param subTemplate shared pointer to a sub-template that should be included
* into this tree (at the current position)
* @param addMode flag specifying at which position to add the 'subTemplate'
* (e.g. after or below the current node)
* @param defaultRelType default relationship type that will be used when the
* subtree that is managed by the 'subTemplate' is inserted
* into this tree and the relationship type of one of the
* top-level nodes is "unknown". Also see documentation of
* createExpandedSubTree().
** @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition includeTemplate(const DSRSharedSubTemplate &subTemplate,
const E_AddMode addMode = AM_belowCurrent,
const E_RelationshipType defaultRelType = RT_unknown);
/** expand all "included template" content items in a given (sub)tree.
* Expanding means that all instances of DSRIncludedTemplateTreeNode are replaced by
* their content (subtree).
* Please note that the internal cursor of the given 'tree' is set to the root node
* if no error occurred. Otherwise, the cursor points to the content item that
* caused the problem.
** @param tree pointer to the subtree that should be expanded
** @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition expandIncludedTemplates(DSRDocumentSubTree *tree) const;
/** check the by-reference relationships (if any) for validity.
* This function checks whether all by-reference relationships possibly contained
* in the document tree are valid according to the following restrictions: source
* and target node are not identical and the target node is not an ancestor of the
* source node (requirement from the DICOM standard to prevent loops -> directed
* acyclic graph, though this is not 100% true - see "reportlp.dcm" example).
* In addition, the position strings (used to encode by-reference relationships
* according to the DICOM standard) OR the node IDs (used internally to uniquely
* identify nodes) can be updated.
* Please note that the checking modes DSRTypes::CM_updatePositionString and
* DSRTypes::CM_updateNodeID are mutually exclusive.
** @tparam T_Cursor template type used for the cursor iterating the document (sub)tree
** @param mode mode used to customize the checking process (see DSRTypes::CM_xxx)
* @param flags flag used to customize the reading (see DSRTypes::RF_xxx) and/or
* printing process (see DSRTypes::PF_xxx). Conflicting definitions
* are avoided using the appropriate bit mask (see DSRTypes::CB_xxx).
** @return status, EC_Normal if successful, an error code otherwise
*/
template <typename T_Cursor>
OFCondition checkByReferenceRelationships(const size_t mode = 0,
const size_t flags = 0);
/** reset flag for all content items whether they are target of a by-reference relationship.
* This function calls 'setReferenceTarget(OFFalse)' for all content items in the tree.
*/
virtual void resetReferenceTargetFlag();
/** update the tree for subsequent output, e.g.\ for being printed or added to an SR
* document. By default, this virtual function does nothing but is called automatically
* by the affected output methods and should be overwritten in derived classes.
*/
virtual void updateTreeForOutput();
/** check whether the given subtree complies with the constraints of the given checker
** @param tree pointer to subtree that should be checked
* @param checker pointer to relationship content constraints checker to be used.
* If NULL, no checks are performed by this method.
** @return status, EC_Normal if successful, an error code otherwise
*/
virtual OFCondition checkSubTreeConstraints(const DSRDocumentSubTree *tree,
const DSRIODConstraintChecker *checker) const;
/// check relationship content constraints of the associated IOD
DSRIODConstraintChecker *ConstraintChecker;
private:
/// current content item. Introduced to avoid the external use of pointers.
DSRContentItem CurrentContentItem;
};
#endif
|