/* * * Copyright (C) 2000-2019, 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: DSRPNameTreeNode * */ #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ #include "dcmtk/dcmsr/dsrtypes.h" #include "dcmtk/dcmsr/dsrpnmtn.h" #include "dcmtk/dcmsr/dsrxmld.h" #include "dcmtk/dcmdata/dcdeftag.h" #include "dcmtk/dcmdata/dcvrpn.h" DSRPNameTreeNode::DSRPNameTreeNode(const E_RelationshipType relationshipType) : DSRDocumentTreeNode(relationshipType, VT_PName), DSRStringValue() { } DSRPNameTreeNode::DSRPNameTreeNode(const E_RelationshipType relationshipType, const OFString &personNameValue, const OFBool check) : DSRDocumentTreeNode(relationshipType, VT_PName), DSRStringValue(personNameValue, check) { } DSRPNameTreeNode::DSRPNameTreeNode(const DSRPNameTreeNode &node) : DSRDocumentTreeNode(node), DSRStringValue(node) { } DSRPNameTreeNode::~DSRPNameTreeNode() { } OFBool DSRPNameTreeNode::operator==(const DSRDocumentTreeNode &node) const { /* call comparison operator of base class (includes check of value type) */ OFBool result = DSRDocumentTreeNode::operator==(node); if (result) { /* it's safe to cast the type since the value type has already been checked */ result = DSRStringValue::operator==(OFstatic_cast(const DSRPNameTreeNode &, node).getValue()); } return result; } OFBool DSRPNameTreeNode::operator!=(const DSRDocumentTreeNode &node) const { /* call comparison operator of base class (includes check of value type) */ OFBool result = DSRDocumentTreeNode::operator!=(node); if (!result) { /* it's safe to cast the type since the value type has already been checked */ result = DSRStringValue::operator!=(OFstatic_cast(const DSRPNameTreeNode &, node).getValue()); } return result; } DSRPNameTreeNode *DSRPNameTreeNode::clone() const { return new DSRPNameTreeNode(*this); } void DSRPNameTreeNode::clear() { DSRDocumentTreeNode::clear(); DSRStringValue::clear(); } OFBool DSRPNameTreeNode::isValid() const { /* ConceptNameCodeSequence required */ return DSRDocumentTreeNode::isValid() && getConceptName().isValid() && hasValidValue(); } OFBool DSRPNameTreeNode::hasValidValue() const { return checkCurrentValue().good(); } OFCondition DSRPNameTreeNode::print(STD_NAMESPACE ostream &stream, const size_t flags) const { OFCondition result = DSRDocumentTreeNode::print(stream, flags); if (result.good()) { DCMSR_PRINT_ANSI_ESCAPE_CODE(DCMSR_ANSI_ESCAPE_CODE_DELIMITER) stream << "="; DCMSR_PRINT_ANSI_ESCAPE_CODE(DCMSR_ANSI_ESCAPE_CODE_ITEM_VALUE) DSRStringValue::print(stream); } return result; } OFCondition DSRPNameTreeNode::writeXML(STD_NAMESPACE ostream &stream, const size_t flags) const { OFCondition result = EC_Normal; writeXMLItemStart(stream, flags); result = DSRDocumentTreeNode::writeXML(stream, flags); if (!getValue().empty() || (flags & XF_writeEmptyTags)) { OFString tmpString; stream << "" << OFendl << dicomToXMLPersonName(getValue(), tmpString) << OFendl << "" << OFendl; } writeXMLItemEnd(stream, flags); return result; } OFCondition DSRPNameTreeNode::readContentItem(DcmItem &dataset, const size_t flags) { /* read PName */ return DSRStringValue::read(dataset, DCM_PersonName, flags); } OFCondition DSRPNameTreeNode::writeContentItem(DcmItem &dataset) const { /* write PName */ return DSRStringValue::write(dataset, DCM_PersonName); } OFCondition DSRPNameTreeNode::readXMLContentItem(const DSRXMLDocument &doc, DSRXMLCursor cursor, const size_t /*flags*/) { OFCondition result = SR_EC_CorruptedXMLStructure; if (cursor.valid()) { /* goto sub-node "value" */ cursor = doc.getNamedChildNode(cursor, "value").getChild(); if (cursor.valid()) { /* retrieve person name from XML tag */ OFString nameString; getValueFromXMLNodeContent(doc, cursor, nameString); /* set retrieved value */ result = DSRStringValue::setValue(nameString); } } return result; } OFString &DSRPNameTreeNode::getValueFromXMLNodeContent(const DSRXMLDocument &doc, DSRXMLCursor cursor, OFString &nameValue) { nameValue.clear(); /* check whether node is valid */ if (cursor.valid()) { OFString first, middle, last, suffix, prefix; /* iterate over all nodes */ while (cursor.valid()) { /* check for known element tags */ doc.getStringFromNodeContent(cursor, prefix, "prefix", OFTrue /*encoding*/, OFFalse /*clearString*/); doc.getStringFromNodeContent(cursor, first, "first", OFTrue /*encoding*/, OFFalse /*clearString*/); doc.getStringFromNodeContent(cursor, middle, "middle", OFTrue /*encoding*/, OFFalse /*clearString*/); doc.getStringFromNodeContent(cursor, last, "last", OFTrue /*encoding*/, OFFalse /*clearString*/); doc.getStringFromNodeContent(cursor, suffix, "suffix", OFTrue /*encoding*/, OFFalse /*clearString*/); /* proceed with next node */ cursor.gotoNext(); } /* create DICOM Person Name (PN) from name components */ DcmPersonName::getStringFromNameComponents(last, first, middle, prefix, suffix, nameValue); } return nameValue; } OFCondition DSRPNameTreeNode::renderHTMLContentItem(STD_NAMESPACE ostream &docStream, STD_NAMESPACE ostream & /*annexStream*/, const size_t /*nestingLevel*/, size_t & /*annexNumber*/, const size_t flags) const { /* render ConceptName */ OFCondition result = renderHTMLConceptName(docStream, flags); /* render PName */ if (result.good()) { OFString tmpString, htmlString; if (!(flags & DSRTypes::HF_renderItemsSeparately)) { if (flags & DSRTypes::HF_XHTML11Compatibility) docStream << ""; else if (flags & DSRTypes::HF_HTML32Compatibility) docStream << ""; else /* HTML 4.01 */ docStream << ""; } docStream << convertToHTMLString(dicomToReadablePersonName(getValue(), tmpString), htmlString, flags); if (!(flags & DSRTypes::HF_renderItemsSeparately)) { if (flags & DSRTypes::HF_HTML32Compatibility) docStream << ""; else docStream << ""; } docStream << OFendl; } return result; } OFCondition DSRPNameTreeNode::checkValue(const OFString &personNameValue) const { /* first, make sure that the mandatory value is non-empty */ OFCondition result = DSRStringValue::checkValue(personNameValue); /* then, check whether the passed value is valid with regards to VR and VM. * tbd: unfortunately, we do not know the character set, so "UNKNOWN" is used. */ if (result.good()) result = DcmPersonName::checkStringValue(personNameValue, "1", "UNKNOWN"); return result; }