1 /* 2 * 3 * Copyright (C) 2000-2017, OFFIS e.V. 4 * All rights reserved. See COPYRIGHT file for details. 5 * 6 * This software and supporting documentation were developed by 7 * 8 * OFFIS e.V. 9 * R&D Division Health 10 * Escherweg 2 11 * D-26121 Oldenburg, Germany 12 * 13 * 14 * Module: dcmsr 15 * 16 * Author: Joerg Riesmeier 17 * 18 * Purpose: 19 * classes: DSRDocumentTreeNode 20 * 21 */ 22 23 24 #ifndef DSRDOCTN_H 25 #define DSRDOCTN_H 26 27 #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ 28 29 #include "dcmtk/dcmsr/dsrtree.h" 30 #include "dcmtk/dcmsr/dsrcodvl.h" 31 32 33 /*-----------------------* 34 * forward declaration * 35 *-----------------------*/ 36 37 class DSRIODConstraintChecker; 38 39 40 /*---------------------* 41 * class declaration * 42 *---------------------*/ 43 44 /** Base class for content items 45 */ 46 class DCMTK_DCMSR_EXPORT DSRDocumentTreeNode 47 : public DSRTreeNode 48 { 49 // allow direct access to protected methods 50 friend class DSRTree<DSRDocumentTreeNode>; 51 friend class DSRTreeNodeCursor<DSRDocumentTreeNode>; 52 // also for the derived cursor classes 53 friend class DSRDocumentTreeNodeCursor; 54 friend class DSRIncludedTemplateNodeCursor; 55 56 // allow access to getConceptNamePtr() 57 friend class DSRContentItem; 58 59 public: 60 61 /** constructor. 62 * The 'valueType' can never be changed after the tree node has been created 63 * (therefore, the corresponding member variable is declared "const"). 64 ** @param relationshipType type of relationship to the parent tree node. Should 65 * not be DSRTypes::RT_invalid, and DSRTypes::RT_isRoot 66 * only for the root node. 67 * @param valueType value type of the associated content item. Should not 68 * be DSRTypes::VT_invalid. 69 */ 70 DSRDocumentTreeNode(const E_RelationshipType relationshipType, 71 const E_ValueType valueType); 72 73 /** copy constructor. 74 * Please note that the member variables of the base class DSRTreeNode are not copied 75 * because the new tree node is not (yet) part of a document tree. Furthermore, the 76 * following member variables of this class are also not copied but initialized with 77 * their respective default values: 78 * - ReferenceTarget 79 * - MACParameters 80 * - DigitalSignatures 81 * 82 ** @param node tree node to be copied 83 */ 84 DSRDocumentTreeNode(const DSRDocumentTreeNode &node); 85 86 /** destructor 87 */ 88 virtual ~DSRDocumentTreeNode(); 89 90 /** comparison operator "equal". 91 * Two tree nodes are regarded as equal if the relationship type, the value type and the 92 * concept name are equal. Other information is not used unless implemented in a derived 93 * class. 94 ** @param node tree node that should be compared to the current one 95 ** @return OFTrue if both tree nodes are equal, OFFalse otherwise 96 */ 97 virtual OFBool operator==(const DSRDocumentTreeNode &node) const; 98 99 /** comparison operator "not equal". 100 * Two tree nodes are regarded as not equal if either the relationship type or the value 101 * type or the concept name are not equal. Other information is not used unless implemented 102 * in a derived class. 103 ** @param node tree node that should be compared to the current one 104 ** @return OFTrue if both tree nodes are not equal, OFFalse otherwise 105 */ 106 virtual OFBool operator!=(const DSRDocumentTreeNode &node) const; 107 108 /** clone this tree node (abstract). 109 * Internally, the copy constructor is used, so the corresponding comments apply. 110 ** @return copy of this tree node 111 */ 112 virtual DSRDocumentTreeNode *clone() const = 0; 113 114 /** clear all member variables. 115 * This does not apply to the relationship and value type since they are never changed. 116 */ 117 virtual void clear(); 118 119 /** check whether the content item is valid. 120 * The content item is valid if the relationship type and the value type are both not invalid. 121 ** @return OFTrue if tree node is valid, OFFalse otherwise 122 */ 123 virtual OFBool isValid() const; 124 125 /** check whether the value of the content item is valid. See derived classes for details. 126 ** @return OFTrue if the value is valid, OFFalse otherwise 127 */ 128 virtual OFBool hasValidValue() const; 129 130 /** check whether the content is short. 131 * This method is used to check whether the rendered output of this content item can be 132 * expanded inline or not (used for renderHTML()). This base class always returns OFTrue. 133 ** @param flags flag used to customize the output (see DSRTypes::HF_xxx) 134 ** @return OFTrue if the content is short, OFFalse otherwise 135 */ 136 virtual OFBool isShort(const size_t flags) const; 137 138 /** check whether template identification is set 139 ** @return OFTrue if template identification is set, OFFalse otherwise 140 */ 141 virtual OFBool hasTemplateIdentification() const; 142 143 /** print content item. 144 * The output of a content item depends on its value type. This general method prints 145 * only those parts which all derived classes (= value types) do have in common, i.e. the 146 * type of relationship, the value type and the (optional) concept name. 147 * A typical output looks like this: has concept mod CODE: (,,"Concept") 148 ** @param stream output stream to which the content item should be printed 149 * @param flags flag used to customize the output (see DSRTypes::PF_xxx) 150 ** @return status, EC_Normal if successful, an error code otherwise 151 */ 152 virtual OFCondition print(STD_NAMESPACE ostream &stream, 153 const size_t flags) const; 154 155 /** print extended information on the content item. 156 * The following details are printed (if present and output is enabled): observation 157 * date/time (in curly brackets), annotation text (in quotation marks) and template 158 * identification (after a hash mark). This method is intended to be called after 159 * the general print() method, e.g. like it is done by DSRDocumentSubTree::print(). 160 ** @param stream output stream to which the extended information should be printed 161 * @param flags flag used to customize the output (see DSRTypes::PF_xxx) 162 ** @return status, EC_Normal if successful, an error code otherwise 163 */ 164 virtual OFCondition printExtended(STD_NAMESPACE ostream &stream, 165 const size_t flags) const; 166 167 /** read content item from dataset. 168 * A number of readXXX() methods are called (see "protected" part) in order to retrieve all 169 * possibly nested content items from the dataset. 170 ** @param dataset DICOM dataset from which the content item should be read 171 * @param constraintChecker checks relationship content constraints of the associated IOD 172 * @param flags flag used to customize the reading process (see DSRTypes::RF_xxx) 173 ** @return status, EC_Normal if successful, an error code otherwise 174 */ 175 virtual OFCondition read(DcmItem &dataset, 176 const DSRIODConstraintChecker *constraintChecker, 177 const size_t flags); 178 179 /** write content item to dataset. 180 * A number of writeXXX() methods are called (see "protected" part) in order to write all 181 * possibly nested content items to the dataset. 182 ** @param dataset DICOM dataset to which the content item should be written 183 * @param markedItems optional stack where pointers to all 'marked' content items 184 * (DICOM datasets/items) are added to during the write process. 185 * Can be used to digitally sign parts of the document tree. 186 ** @return status, EC_Normal if successful, an error code otherwise 187 */ 188 virtual OFCondition write(DcmItem &dataset, 189 DcmStack *markedItems = NULL); 190 191 /** read general XML document tree node data 192 ** @param doc document containing the XML file content 193 * @param cursor cursor pointing to the starting node 194 * @param documentType type of the document to be read (used for debug output only) 195 * @param flags flag used to customize the reading process (see DSRTypes::XF_xxx) 196 ** @return status, EC_Normal if successful, an error code otherwise 197 */ 198 virtual OFCondition readXML(const DSRXMLDocument &doc, 199 DSRXMLCursor cursor, 200 const E_DocumentType documentType, 201 const size_t flags); 202 203 /** write content item in XML format 204 ** @param stream output stream to which the XML document is written 205 * @param flags flag used to customize the output (see DSRTypes::XF_xxx) 206 ** @return status, EC_Normal if successful, an error code otherwise 207 */ 208 virtual OFCondition writeXML(STD_NAMESPACE ostream &stream, 209 const size_t flags) const; 210 211 /** render content item in HTML/XHTML format. 212 * After rendering the current content item all child nodes (if any) are also rendered (see 213 * renderHTMLChildNodes() for details). 214 ** @param docStream output stream to which the main HTML/XHTML document is written 215 * @param annexStream output stream to which the HTML/XHTML document annex is written 216 * @param nestingLevel current nesting level. Used to render section headings. 217 * @param annexNumber reference to the variable where the current annex number is stored. 218 * Value is increased automatically by 1 after a new entry has been added. 219 * @param flags flag used to customize the output (see DSRTypes::HF_xxx) 220 ** @return status, EC_Normal if successful, an error code otherwise 221 */ 222 virtual OFCondition renderHTML(STD_NAMESPACE ostream &docStream, 223 STD_NAMESPACE ostream &annexStream, 224 const size_t nestingLevel, 225 size_t &annexNumber, 226 const size_t flags) const; 227 228 /** check whether content item is digitally signed. 229 * A content item is signed if the DigitalSignaturesSequence exists. This sequence is read 230 * from the dataset if present and the 'signature' flag for the 'read' method is turned on. 231 ** @return OFTrue if content item is signed, OFFalse otherwise 232 */ isSigned()233 inline OFBool isSigned() 234 { 235 return !DigitalSignatures.isEmpty(); 236 } 237 238 /** check whether content item is marked. 239 * Use method setMark() to mark and unmark the current content item. 240 * Pointers to the DICOM dataset/item of marked content items are added to the optional 241 * stack when calling the DSRDocument::write() method. This mechanism can e.g. be used 242 * to digitally sign particular content items. 243 ** @return OFTrue if content item is marked, OFFalse otherwise 244 */ isMarked()245 inline OFBool isMarked() const 246 { 247 return MarkFlag; 248 } 249 250 /** mark/unmark the current content item. 251 * See explanation for method isMarked() for details. 252 * @param flag mark item if OFTrue, unmark otherwise 253 */ setMark(const OFBool flag)254 inline void setMark(const OFBool flag) 255 { 256 MarkFlag = flag; 257 } 258 259 /** check whether the current content item is target of a by-reference relationship 260 ** @return OFTrue if the content item is target, OFFalse otherwise 261 */ isReferenceTarget()262 inline OFBool isReferenceTarget() const 263 { 264 return ReferenceTarget; 265 } 266 267 /** specify whether the current content item is target of a by-reference relationship 268 ** @param isTarget OFTrue if the content item is target (default), OFFalse otherwise 269 */ 270 inline void setReferenceTarget(const OFBool isTarget = OFTrue) 271 { 272 ReferenceTarget = isTarget; 273 } 274 275 /** check whether the current content item has any children 276 ** @return OFTrue if there are any child nodes, OFFalse otherwise 277 */ hasChildNodes()278 inline OFBool hasChildNodes() const 279 { 280 return (getDown() != NULL); 281 } 282 283 /** check whether the current content item has any siblings 284 ** @return OFTrue if there are any sibling nodes, OFFalse otherwise 285 */ hasSiblingNodes()286 inline OFBool hasSiblingNodes() const 287 { 288 return (getPrev() != NULL) || (getNext() != NULL); 289 } 290 291 /** get ID of the current tree node 292 ** @return ID of the current tree node (should never be 0) 293 */ getNodeID()294 inline size_t getNodeID() const 295 { 296 return getIdent(); 297 } 298 299 /** get relationship type of the current content item 300 ** @return relationship type of the current content item (might be DSRTypes::RT_invalid) 301 */ getRelationshipType()302 inline E_RelationshipType getRelationshipType() const 303 { 304 return RelationshipType; 305 } 306 307 /** set relationship type of the current content item (if previously unknown). 308 * Please note that changing the relationship type (which was originally passed to the 309 * constructor of this class) only works if the current value is DSRTypes::RT_unknown. 310 * This is needed for inserting document subtrees where the top-level nodes might have an 311 * "unknown" relationship to the parent node (see DSRDocumentSubTree::insertSubTree()). 312 ** @param relationshipType type of relationship to the parent tree node. Should not be 313 * DSRTypes::RT_invalid or DSRTypes::RT_unknown. Be careful 314 * with DSRTypes::RT_isRoot, use it for root nodes only. 315 ** @return status, EC_Normal if successful, an error code otherwise 316 */ 317 virtual OFCondition setRelationshipType(const E_RelationshipType relationshipType); 318 319 /** get value type of the current content item 320 ** @return value type of the current content item (might be DSRTypes::VT_invalid) 321 */ getValueType()322 inline E_ValueType getValueType() const 323 { 324 return ValueType; 325 } 326 327 /** get reference to the concept name 328 ** @return reference to the concept name (code, might be empty/invalid) 329 */ getConceptName()330 inline const DSRCodedEntryValue &getConceptName() const 331 { 332 return ConceptName; 333 } 334 335 /** get copy of the concept name. 336 * Code describing the concept represented by this content item. Also conveys the value 337 * of document title and section headings in documents. 338 ** @param conceptName reference to a variable where the code should be stored 339 ** @return status, EC_Normal if successful, an error code otherwise 340 */ 341 virtual OFCondition getConceptName(DSRCodedEntryValue &conceptName) const; 342 343 /** set the concept name. 344 * Code describing the concept represented by this content item. Also conveys the value 345 * of document title and section headings in documents. 346 * If the new code is invalid the current one is not replaced. An empty code can 347 * be used to clear the current concept name. 348 ** @param conceptName code to be set as the new concept name (checked before set) 349 * @param check check 'conceptName' for validity if enabled. See 350 * DSRCodedEntryValue::checkCode() for details. 351 ** @return status, EC_Normal if successful, an error code otherwise 352 */ 353 virtual OFCondition setConceptName(const DSRCodedEntryValue &conceptName, 354 const OFBool check = OFTrue); 355 356 /** get observation date/time. 357 * This is the date and time on which this content item was completed. Might be empty 358 * if the date and time do not differ from the content date and time, see DSRDocument. 359 ** @return observation date/time of current content item (might be empty/invalid) 360 */ getObservationDateTime()361 inline const OFString &getObservationDateTime() const 362 { 363 return ObservationDateTime; 364 } 365 366 /** set observation date/time. 367 * This is the date and time on which this content item was completed. Might be empty 368 * if the date and time do not differ from the content date and time, see DSRDocument. 369 ** @param observationDateTime value to be set (might be an empty string) 370 * @param check check 'observationDateTime' for conformance with VR (DT) 371 * and VM (1) if enabled 372 ** @return status, EC_Normal if successful, an error code otherwise 373 */ 374 virtual OFCondition setObservationDateTime(const OFString &observationDateTime, 375 const OFBool check = OFTrue); 376 377 /** set observation date/time from element. 378 * This is the date and time on which this content item was completed. Might be empty 379 * if the date and time do not differ from the content date and time, see DSRDocument. 380 ** @param delem DICOM element from which the date/time value should be retrieved 381 * @param pos index of the value in case of multi-valued elements (0..vm-1) 382 * @param check check date/time value for conformance with VR (DT) and VM (1) if 383 * enabled 384 ** @return status, EC_Normal if successful, an error code otherwise 385 */ 386 virtual OFCondition setObservationDateTime(const DcmElement &delem, 387 const unsigned long pos = 0, 388 const OFBool check = OFTrue); 389 390 /** set observation date/time from dataset. 391 * This is the date and time on which this content item was completed. Might be empty 392 * if the date and time do not differ from the content date and time, see DSRDocument. 393 ** @param dataset DICOM dataset from which the date/time value should be retrieved 394 * @param tagKey DICOM tag specifying the attribute from which the value should be 395 * retrieved. The search is limited to the top-level of the dataset. 396 * @param pos index of the value in case of multi-valued elements (0..vm-1) 397 * @param check check date/time value for conformance with VR (DT) and VM (1) if 398 * enabled 399 ** @return status, EC_Normal if successful, an error code otherwise 400 */ 401 virtual OFCondition setObservationDateTime(DcmItem &dataset, 402 const DcmTagKey &tagKey, 403 const unsigned long pos = 0, 404 const OFBool check = OFTrue); 405 406 /** get observation unique identifier. 407 * The UID represents the semantic content of the observation; an encoding of the same 408 * observation with the same context into another representation may use the same UID. 409 ** @return observation unique identifier of current content item (might be empty/invalid) 410 */ getObservationUID()411 inline const OFString &getObservationUID() const 412 { 413 return ObservationUID; 414 } 415 416 /** set observation unique identifier. 417 * The UID represents the semantic content of the observation; an encoding of the same 418 * observation with the same context into another representation may use the same UID. 419 ** @param observationUID value to be set (might be an empty string) 420 * @param check check 'observationUID' for conformance with VR (UI) and VM (1) 421 * if enabled 422 ** @return status, EC_Normal if successful, an error code otherwise 423 */ 424 virtual OFCondition setObservationUID(const OFString &observationUID, 425 const OFBool check = OFTrue); 426 427 /** compare template identification with given values 428 ** @param templateIdentifier template identifier to compare with 429 * @param mappingResource mapping resource that defines the template 430 * @param mappingResourceUID uniquely identifies the mapping resource (optional). 431 * Not used for comparison if the value is empty. 432 ** @result OFTrue if template identification is identical, OFFalse otherwise 433 */ 434 virtual OFBool compareTemplateIdentification(const OFString &templateIdentifier, 435 const OFString &mappingResource, 436 const OFString &mappingResourceUID = "") const; 437 438 /** get template identifier and mapping resource. 439 * This value pair identifies the template that was used to create this content item 440 * (and its children). According to the DICOM standard, it is "required if a template 441 * was used to define the content of this Item, and the template consists of a single 442 * CONTAINER with nested content, and it is the outermost invocation of a set of 443 * nested templates that start with the same CONTAINER." The identification is valid 444 * if both values are either present (non-empty) or absent (empty). 445 ** @param templateIdentifier identifier of the template (might be empty) 446 * @param mappingResource mapping resource that defines the template (might be empty) 447 ** @return status, EC_Normal if successful, an error code otherwise 448 */ 449 virtual OFCondition getTemplateIdentification(OFString &templateIdentifier, 450 OFString &mappingResource) const; 451 452 /** get template identifier, mapping resource and optional mapping resource UID. 453 * This value triple identifies the template that was used to create this content item 454 * (and its children). According to the DICOM standard, it is "required if a template 455 * was used to define the content of this Item, and the template consists of a single 456 * CONTAINER with nested content, and it is the outermost invocation of a set of 457 * nested templates that start with the same CONTAINER." The identification is valid 458 * if the first two values are either present (non-empty) or all three are absent (empty). 459 ** @param templateIdentifier identifier of the template (might be empty) 460 * @param mappingResource mapping resource that defines the template (might be empty) 461 * @param mappingResourceUID uniquely identifies the mapping resource (might be empty) 462 ** @return status, EC_Normal if successful, an error code otherwise 463 */ 464 virtual OFCondition getTemplateIdentification(OFString &templateIdentifier, 465 OFString &mappingResource, 466 OFString &mappingResourceUID) const; 467 468 /** set template identifier and mapping resource. 469 * The identification is valid if the first two values are either present (non-empty) or 470 * all three values are absent (empty). See getTemplateIdentification() for details. 471 * A warning message is reported to the logger if a template identification is specified 472 * for a content item that is not a CONTAINER. 473 ** @param templateIdentifier identifier of the template to be set 474 * @param mappingResource mapping resource that defines the template 475 * @param mappingResourceUID uniquely identifies the mapping resource (optional) 476 * @param check check 'templateIdentifier', 'mappingResource' and 477 * 'mappingResourceUID' for conformance with VR (CS,UI) and 478 * VM (1) if enabled 479 ** @return status, EC_Normal if successful, an error code otherwise 480 */ 481 virtual OFCondition setTemplateIdentification(const OFString &templateIdentifier, 482 const OFString &mappingResource, 483 const OFString &mappingResourceUID = "", 484 const OFBool check = OFTrue); 485 486 /** remove digital signatures from content item. 487 * This method clears the MACParametersSequence and the DigitalSignaturesSequence for 488 * the current content item which have been filled during reading. 489 */ 490 void removeSignatures(); 491 492 493 protected: 494 495 /** get pointer to the concept name 496 ** @return pointer to the concept name (never NULL) 497 */ getConceptNamePtr()498 inline DSRCodedEntryValue *getConceptNamePtr() 499 { 500 return &ConceptName; 501 } 502 503 /** get pointer to previous tree node 504 ** @return pointer to previous tree node (might be NULL) 505 */ getPrev()506 inline DSRDocumentTreeNode *getPrev() const 507 { 508 return OFstatic_cast(DSRDocumentTreeNode *, DSRTreeNode::getPrev()); 509 } 510 511 /** get pointer to next tree node 512 ** @return pointer to next tree node (might be NULL) 513 */ getNext()514 inline DSRDocumentTreeNode *getNext() const 515 { 516 return OFstatic_cast(DSRDocumentTreeNode *, DSRTreeNode::getNext()); 517 } 518 519 /** get pointer to first child node 520 ** @return pointer to first child node (might be NULL) 521 */ getDown()522 inline DSRDocumentTreeNode *getDown() const 523 { 524 return OFstatic_cast(DSRDocumentTreeNode *, DSRTreeNode::getDown()); 525 } 526 527 /** get unique identifier of this node 528 ** @return unique identifier of this node 529 */ getIdent()530 inline size_t getIdent() const 531 { 532 return DSRTreeNode::getIdent(); 533 } 534 535 /** create a new node and append it to the current one 536 ** @param previousNode reference to the pointer to the previous node (sibling). 537 * Used to decide whether the new node is a child (value=NULL) 538 * or a sibling (!=NULL). NB: The value might be modified 539 * inside this method (to store a reference to the previous node). 540 * @param relationshipType relationship type of the new node with regard to the 541 * current one 542 * @param valueType value type of node to be added 543 * @param constraintChecker checks relationship content constraints of the associated IOD 544 ** @return status, EC_Normal if successful, an error code otherwise 545 */ 546 OFCondition createAndAppendNewNode(DSRDocumentTreeNode *&previousNode, 547 const E_RelationshipType relationshipType, 548 const E_ValueType valueType, 549 const DSRIODConstraintChecker *constraintChecker = NULL); 550 551 /** read content item (value) from dataset. 552 * This method does nothing for this base class, but derived classes overwrite it to read 553 * the contents according to their value type. 554 ** @param dataset DICOM dataset from which the content item should be read 555 * @param flags flag used to customize the reading process (see DSRTypes::RF_xxx) 556 ** @return status, EC_Normal if successful, an error code otherwise 557 */ 558 virtual OFCondition readContentItem(DcmItem &dataset, 559 const size_t flags); 560 561 /** write content item (value) to dataset. 562 * This method does nothing for this base class, but derived classes overwrite it to write 563 * the contents according to their value type. 564 ** @param dataset DICOM dataset to which the content item should be written 565 ** @return status, EC_Normal if successful, an error code otherwise 566 */ 567 virtual OFCondition writeContentItem(DcmItem &dataset) const; 568 569 /** read content item specific XML data. 570 * This method does nothing for this base class, but derived classes overwrite it to read 571 * the contents according to their value type. 572 ** @param doc document containing the XML file content 573 * @param cursor cursor pointing to the starting node 574 * @param flags flag used to customize the output (see DSRTypes::XF_xxx) 575 ** @return status, EC_Normal if successful, an error code otherwise 576 */ 577 virtual OFCondition readXMLContentItem(const DSRXMLDocument &doc, 578 DSRXMLCursor cursor, 579 const size_t flags); 580 581 /** render content item (value) in HTML/XHTML format. 582 * This method does nothing for this base class, but derived classes overwrite it to render 583 * the contents according to their value type. 584 ** @param docStream output stream to which the main HTML/XHTML document is written 585 * @param annexStream output stream to which the HTML/XHTML document annex is written 586 * @param nestingLevel current nesting level. Used to render section headings. 587 * @param annexNumber reference to the variable where the current annex number is stored. 588 * Value is increased automatically by 1 after a new entry has been added. 589 * @param flags flag used to customize the output (see DSRTypes::HF_xxx) 590 ** @return status, EC_Normal if successful, an error code otherwise 591 */ 592 virtual OFCondition renderHTMLContentItem(STD_NAMESPACE ostream &docStream, 593 STD_NAMESPACE ostream &annexStream, 594 const size_t nestingLevel, 595 size_t &annexNumber, 596 const size_t flags) const; 597 598 /** write common item start (XML tag) 599 ** @param stream output stream to which the XML document is written 600 * @param flags flag used to customize the output (see DSRTypes::XF_xxx) 601 * @param closingBracket write closing bracket of XML start tag if OFTrue, otherwise the 602 * bracket has to be closed in the calling method 603 */ 604 void writeXMLItemStart(STD_NAMESPACE ostream &stream, 605 const size_t flags, 606 const OFBool closingBracket = OFTrue) const; 607 608 /** write common item start (XML tag) 609 ** @param stream output stream to which the XML document is written 610 * @param flags flag used to customize the output (see DSRTypes::XF_xxx) 611 */ 612 void writeXMLItemEnd(STD_NAMESPACE ostream &stream, 613 const size_t flags) const; 614 615 /** read SR document content module 616 ** @param dataset DICOM dataset from which the data should be read 617 * @param constraintChecker checks relationship content constraints of the associated IOD 618 * @param flags flag used to customize the reading process (see DSRTypes::RF_xxx) 619 ** @return status, EC_Normal if successful, an error code otherwise 620 */ 621 OFCondition readSRDocumentContentModule(DcmItem &dataset, 622 const DSRIODConstraintChecker *constraintChecker, 623 const size_t flags); 624 625 /** write SR document content module 626 ** @param dataset DICOM dataset to which the data should be written 627 * @param markedItems optional stack where pointers to all 'marked' content items 628 * (DICOM datasets/items) are added to during the write process. 629 ** @return status, EC_Normal if successful, an error code otherwise 630 */ 631 OFCondition writeSRDocumentContentModule(DcmItem &dataset, 632 DcmStack *markedItems); 633 634 /** read document relationship macro 635 ** @param dataset DICOM dataset from which the data should be read 636 * @param constraintChecker checks relationship content constraints of the associated IOD 637 * @param posString location of the current content item (e.g.\ "1.2.3") 638 * @param flags flag used to customize the reading process (see DSRTypes::RF_xxx) 639 ** @return status, EC_Normal if successful, an error code otherwise 640 */ 641 OFCondition readDocumentRelationshipMacro(DcmItem &dataset, 642 const DSRIODConstraintChecker *constraintChecker, 643 const OFString &posString, 644 const size_t flags); 645 646 /** write document relationship macro 647 ** @param dataset DICOM dataset to which the data should be written 648 * @param markedItems optional stack where pointers to all 'marked' content items 649 * (DICOM datasets/items) are added to during the write process. 650 ** @return status, EC_Normal if successful, an error code otherwise 651 */ 652 OFCondition writeDocumentRelationshipMacro(DcmItem &dataset, 653 DcmStack *markedItems); 654 655 /** read document content macro 656 ** @param dataset DICOM dataset from which the data should be read 657 * @param posString location of the current content item (e.g.\ "1.2.3") 658 * @param flags flag used to customize the reading process (see DSRTypes::RF_xxx) 659 ** @return status, EC_Normal if successful, an error code otherwise 660 */ 661 OFCondition readDocumentContentMacro(DcmItem &dataset, 662 const OFString &posString, 663 const size_t flags); 664 665 /** write document content macro 666 ** @param dataset DICOM dataset to which the data should be written 667 ** @return status, EC_Normal if successful, an error code otherwise 668 */ 669 OFCondition writeDocumentContentMacro(DcmItem &dataset) const; 670 671 /** read content sequence 672 ** @param dataset DICOM dataset from which the data should be read 673 * @param constraintChecker checks relationship content constraints of the associated IOD 674 * @param posString location of the current content item (e.g.\ "1.2.3") 675 * @param flags flag used to customize the reading process (see DSRTypes::RF_xxx) 676 ** @return status, EC_Normal if successful, an error code otherwise 677 */ 678 OFCondition readContentSequence(DcmItem &dataset, 679 const DSRIODConstraintChecker *constraintChecker, 680 const OFString &posString, 681 const size_t flags); 682 683 /** write content sequence 684 ** @param dataset DICOM dataset to which the data should be written 685 * @param markedItems optional stack where pointers to all 'marked' content items 686 * (DICOM datasets/items) are added to during the write process. 687 ** @return status, EC_Normal if successful, an error code otherwise 688 */ 689 OFCondition writeContentSequence(DcmItem &dataset, 690 DcmStack *markedItems) const; 691 692 /** render concept name in HTML/XHTML format. 693 * If the optional observation date/time field is non-empty, it is also rendered. 694 ** @param docStream output stream to which the main HTML/XHTML document is written 695 * @param flags flag used to customize the output (see DSRTypes::HF_xxx) 696 ** @return status, EC_Normal if successful, an error code otherwise 697 */ 698 OFCondition renderHTMLConceptName(STD_NAMESPACE ostream &docStream, 699 const size_t flags) const; 700 701 /** render child nodes in HTML/XHTML format 702 ** @param docStream output stream to which the main HTML/XHTML document is written 703 * @param annexStream output stream to which the HTML/XHTML document annex is written 704 * @param nestingLevel current nesting level. Used to render section headings. 705 * @param annexNumber reference to the variable where the current annex number is stored. 706 * Value is increased automatically by 1 after a new entry has been added. 707 * @param flags flag used to customize the output (see DSRTypes::HF_xxx) 708 ** @return status, EC_Normal if successful, an error code otherwise 709 */ 710 OFCondition renderHTMLChildNodes(STD_NAMESPACE ostream &docStream, 711 STD_NAMESPACE ostream &annexStream, 712 const size_t nestingLevel, 713 size_t &annexNumber, 714 const size_t flags) const; 715 716 // --- static function --- 717 718 /** convert relationship type into a text used for HTML rendering 719 ** @param relationshipType type of relationship to be converted 720 * @param relationshipText reference to string variable where the resulting text should be 721 * stored. Value is cleared if 'relationshipType' is invalid or not 722 * supported. 723 * @param flags flag used to customize the output (see DSRTypes::HF_xxx) 724 ** @return reference to the 'relationshipText' string (might be empty) 725 */ 726 static const OFString &getRelationshipText(const E_RelationshipType relationshipType, 727 OFString &relationshipText, 728 const size_t flags); 729 730 /** check the specified template identification values for validity. 731 * The identification is valid if the first two values are either present (non-empty) or 732 * absent (empty). In the latter case, the third (optional) parameter also has to be empty. 733 ** @param templateIdentifier identifier of the template 734 * @param mappingResource mapping resource that defines the template 735 * @param mappingResourceUID uniquely identifies the mapping resource (optional) 736 ** @return OFTrue if template identification is valid, OFFalse otherwise 737 */ 738 static OFBool checkTemplateIdentification(const OFString &templateIdentifier, 739 const OFString &mappingResource, 740 const OFString &mappingResourceUID); 741 742 743 private: 744 745 /// flag indicating whether the content item is marked (e.g.\ used for digital signatures). 746 /// The default value is OFFalse. 747 OFBool MarkFlag; 748 /// flag indicating whether the content item is referenced (by-reference relationship). 749 /// The default value is OFFalse. 750 OFBool ReferenceTarget; 751 752 /// relationship type to the parent node (associated DICOM VR=CS, mandatory) 753 E_RelationshipType RelationshipType; 754 /// value type (associated DICOM VR=CS, mandatory) 755 const E_ValueType ValueType; 756 757 /// concept name (VR=SQ, conditional) 758 DSRCodedEntryValue ConceptName; 759 /// observation date/time (VR=DT, conditional) 760 OFString ObservationDateTime; 761 /// observation unique identifier (VR=UI, optional) 762 OFString ObservationUID; 763 764 /// template identifier (VR=CS, mandatory in ContentTemplateSequence) 765 OFString TemplateIdentifier; 766 /// mapping resource (VR=CS, mandatory in ContentTemplateSequence) 767 OFString MappingResource; 768 /// mapping resource UID (VR=UI, optional in ContentTemplateSequence) 769 OFString MappingResourceUID; 770 771 /// MAC parameters sequence (VR=SQ, optional) 772 DcmSequenceOfItems MACParameters; 773 /// digital signatures sequence (VR=SQ, optional) 774 DcmSequenceOfItems DigitalSignatures; 775 776 // --- declaration of default constructor and assignment operator 777 778 DSRDocumentTreeNode(); 779 DSRDocumentTreeNode &operator=(const DSRDocumentTreeNode &); 780 }; 781 782 783 #endif 784