/* * * Copyright (C) 2000-2021, 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: DSRCompositeReferenceValue * */ #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ #include "dcmtk/dcmsr/dsrtypes.h" #include "dcmtk/dcmsr/dsrcomvl.h" #include "dcmtk/dcmsr/dsrxmld.h" #include "dcmtk/dcmdata/dcdeftag.h" #include "dcmtk/dcmdata/dcuid.h" #include "dcmtk/dcmdata/dcvrui.h" DSRCompositeReferenceValue::DSRCompositeReferenceValue() : SOPClassUID(), SOPInstanceUID() { } DSRCompositeReferenceValue::DSRCompositeReferenceValue(const OFString &sopClassUID, const OFString &sopInstanceUID, const OFBool check) : SOPClassUID(), SOPInstanceUID() { /* use the set method for checking purposes */ setReference(sopClassUID, sopInstanceUID, check); } DSRCompositeReferenceValue::DSRCompositeReferenceValue(const DSRCompositeReferenceValue &referenceValue) : SOPClassUID(referenceValue.SOPClassUID), SOPInstanceUID(referenceValue.SOPInstanceUID) { /* do not check since this would be unexpected to the user */ } DSRCompositeReferenceValue::~DSRCompositeReferenceValue() { } DSRCompositeReferenceValue &DSRCompositeReferenceValue::operator=(const DSRCompositeReferenceValue &referenceValue) { /* do not check since this would be unexpected to the user */ SOPClassUID = referenceValue.SOPClassUID; SOPInstanceUID = referenceValue.SOPInstanceUID; return *this; } OFBool DSRCompositeReferenceValue::operator==(const DSRCompositeReferenceValue &referenceValue) const { return (SOPClassUID == referenceValue.SOPClassUID) && (SOPInstanceUID == referenceValue.SOPInstanceUID); } OFBool DSRCompositeReferenceValue::operator!=(const DSRCompositeReferenceValue &referenceValue) const { return (SOPClassUID != referenceValue.SOPClassUID) || (SOPInstanceUID != referenceValue.SOPInstanceUID); } void DSRCompositeReferenceValue::clear() { SOPClassUID.clear(); SOPInstanceUID.clear(); } OFBool DSRCompositeReferenceValue::isValid() const { return checkSOPClassUID(SOPClassUID).good() && checkSOPInstanceUID(SOPInstanceUID).good(); } OFBool DSRCompositeReferenceValue::isEmpty() const { return SOPClassUID.empty() && SOPInstanceUID.empty(); } OFBool DSRCompositeReferenceValue::isComplete() const { return !SOPClassUID.empty() && !SOPInstanceUID.empty(); } OFCondition DSRCompositeReferenceValue::print(STD_NAMESPACE ostream &stream, const size_t flags) const { /* first, determine SOP class component */ OFString sopClassString = "\"" + SOPClassUID + "\""; if (!(flags & DSRTypes::PF_printSOPClassUID)) { /* look up name of known SOP classes */ const char *className = dcmFindNameOfUID(SOPClassUID.c_str()); if (className != NULL) sopClassString = className; } /* and then, print it */ stream << "(" << sopClassString << ","; /* print SOP instance component (if desired) */ if (flags & DSRTypes::PF_printSOPInstanceUID) stream << "\"" << SOPInstanceUID << "\""; stream << ")"; return EC_Normal; } OFCondition DSRCompositeReferenceValue::readXML(const DSRXMLDocument &doc, DSRXMLCursor cursor, const size_t /*flags*/) { OFCondition result = SR_EC_CorruptedXMLStructure; /* go one node level down */ if (cursor.gotoChild().valid()) { /* retrieve SOP Class UID and SOP Instance UID from XML tag (required) */ doc.getStringFromAttribute(doc.getNamedNode(cursor, "sopclass"), SOPClassUID, "uid"); doc.getStringFromAttribute(doc.getNamedNode(cursor, "instance"), SOPInstanceUID, "uid"); /* check whether value is valid */ result = isValid() ? EC_Normal : SR_EC_InvalidValue; } return result; } OFCondition DSRCompositeReferenceValue::writeXML(STD_NAMESPACE ostream &stream, const size_t flags) const { if ((flags & DSRTypes::XF_writeEmptyTags) || !isEmpty()) { stream << ""; /* retrieve name of SOP class (if known) */ stream << dcmFindNameOfUID(SOPClassUID.c_str(), "" /* empty value as default */); stream << "" << OFendl; stream << "" << OFendl; } return EC_Normal; } OFCondition DSRCompositeReferenceValue::readItem(DcmItem &dataset, const size_t flags) { const OFBool acceptViolation = (flags & DSRTypes::RF_acceptInvalidContentItemValue) > 0; /* read ReferencedSOPClassUID */ OFCondition result = DSRTypes::getAndCheckStringValueFromDataset(dataset, DCM_ReferencedSOPClassUID, SOPClassUID, "1", "1", "ReferencedSOPSequence", acceptViolation); /* read ReferencedSOPInstanceUID */ if (result.good()) result = DSRTypes::getAndCheckStringValueFromDataset(dataset, DCM_ReferencedSOPInstanceUID, SOPInstanceUID, "1", "1", "ReferencedSOPSequence", acceptViolation); return result; } OFCondition DSRCompositeReferenceValue::writeItem(DcmItem &dataset) const { /* write ReferencedSOPClassUID */ OFCondition result = DSRTypes::putStringValueToDataset(dataset, DCM_ReferencedSOPClassUID, SOPClassUID); /* write ReferencedSOPInstanceUID */ if (result.good()) result = DSRTypes::putStringValueToDataset(dataset, DCM_ReferencedSOPInstanceUID, SOPInstanceUID); return result; } OFCondition DSRCompositeReferenceValue::readSequence(DcmItem &dataset, const DcmTagKey &tagKey, const OFString &type, const size_t flags) { /* read specified sequence with its item */ DcmSequenceOfItems *dseq = NULL; OFCondition result = dataset.findAndGetSequence(tagKey, dseq); DSRTypes::checkElementValue(dseq, tagKey, "1", type, result, "content item"); if (result.good()) { /* read first item */ DcmItem *ditem = dseq->getItem(0); if (ditem != NULL) result = readItem(*ditem, flags); else result = SR_EC_InvalidDocumentTree; } return result; } OFCondition DSRCompositeReferenceValue::writeSequence(DcmItem &dataset, const DcmTagKey &tagKey) const { OFCondition result = EC_MemoryExhausted; /* write specified sequence with its item */ DcmSequenceOfItems *dseq = new DcmSequenceOfItems(tagKey); if (dseq != NULL) { DcmItem *ditem = new DcmItem(); if (ditem != NULL) { /* write item */ result = writeItem(*ditem); if (result.good()) dseq->insert(ditem); else delete ditem; } else result = EC_MemoryExhausted; /* write sequence */ if (result.good()) result = dataset.insert(dseq, OFTrue /*replaceOld*/); if (result.bad()) delete dseq; } return result; } OFCondition DSRCompositeReferenceValue::renderHTML(STD_NAMESPACE ostream &docStream, STD_NAMESPACE ostream & /*annexStream*/, size_t & /*annexNumber*/, const size_t /*flags*/) const { /* render reference */ docStream << ""; /* retrieve name of SOP class (if known) */ docStream << dcmFindNameOfUID(SOPClassUID.c_str(), "unknown composite object"); docStream << ""; return EC_Normal; } const OFString DSRCompositeReferenceValue::getSOPClassName(const OFString &defaultName) const { /* lookup name associated with the SOP class UID */ return SOPClassUID.empty() ? "" : dcmFindNameOfUID(SOPClassUID.c_str(), defaultName.c_str()); } OFCondition DSRCompositeReferenceValue::getValue(DSRCompositeReferenceValue &referenceValue) const { referenceValue = *this; return EC_Normal; } OFCondition DSRCompositeReferenceValue::setValue(const DSRCompositeReferenceValue &referenceValue, const OFBool check) { return setReference(referenceValue.SOPClassUID, referenceValue.SOPInstanceUID, check); } OFCondition DSRCompositeReferenceValue::setReference(const OFString &sopClassUID, const OFString &sopInstanceUID, const OFBool check) { OFCondition result = EC_Normal; /* first, make sure that the mandatory values are non-empty */ if (sopClassUID.empty() || sopInstanceUID.empty()) result = EC_IllegalParameter; else if (check) { /* then, check whether the passed values are valid */ result = checkSOPClassUID(sopClassUID); if (result.good()) result = checkSOPInstanceUID(sopInstanceUID); } if (result.good()) { SOPClassUID = sopClassUID; SOPInstanceUID = sopInstanceUID; } return result; } OFCondition DSRCompositeReferenceValue::setReference(DcmItem &dataset, const OFBool check) { OFCondition result = setSOPClassUID(dataset, DCM_SOPClassUID, 0 /*pos*/, check); if (result.good()) result = setSOPInstanceUID(dataset, DCM_SOPInstanceUID, 0 /*pos*/, check); return result; } OFCondition DSRCompositeReferenceValue::setSOPClassUID(const OFString &sopClassUID, const OFBool check) { OFCondition result = EC_Normal; /* first, make sure that the mandatory value is non-empty */ if (sopClassUID.empty()) result = EC_IllegalParameter; else if (check) { /* then, check whether the passed value is valid */ result = checkSOPClassUID(sopClassUID); } if (result.good()) SOPClassUID = sopClassUID; return result; } OFCondition DSRCompositeReferenceValue::setSOPClassUID(const DcmElement &delem, const unsigned long pos, const OFBool check) { OFString sopClassUID; /* first, get the value from the element (need to cast away "const") */ OFCondition result = OFconst_cast(DcmElement &, delem).getOFString(sopClassUID, pos); if (result.good()) { /* then, check and set the value */ result = setSOPClassUID(sopClassUID, check); } return result; } OFCondition DSRCompositeReferenceValue::setSOPClassUID(DcmItem &dataset, const DcmTagKey &tagKey, const unsigned long pos, const OFBool check) { OFString sopClassUID; /* first, get the element value from the dataset */ OFCondition result = DSRTypes::getStringValueFromDataset(dataset, tagKey, sopClassUID, pos); if (result.good()) { /* then, check and set the value */ result = setSOPClassUID(sopClassUID, check); } return result; } OFCondition DSRCompositeReferenceValue::setSOPInstanceUID(const OFString &sopInstanceUID, const OFBool check) { OFCondition result = EC_Normal; /* first, make sure that the mandatory value is non-empty */ if (sopInstanceUID.empty()) result = EC_IllegalParameter; else if (check) { /* then, check whether the passed value is valid */ result = checkSOPInstanceUID(sopInstanceUID); } if (result.good()) SOPInstanceUID = sopInstanceUID; return result; } OFCondition DSRCompositeReferenceValue::setSOPInstanceUID(const DcmElement &delem, const unsigned long pos, const OFBool check) { OFString sopInstanceUID; /* first, get the value from the element (need to cast away "const") */ OFCondition result = OFconst_cast(DcmElement &, delem).getOFString(sopInstanceUID, pos); if (result.good()) { /* then, check and set the value */ result = setSOPInstanceUID(sopInstanceUID, check); } return result; } OFCondition DSRCompositeReferenceValue::setSOPInstanceUID(DcmItem &dataset, const DcmTagKey &tagKey, const unsigned long pos, const OFBool check) { OFString sopInstanceUID; /* first, get the element value from the dataset */ OFCondition result = DSRTypes::getStringValueFromDataset(dataset, tagKey, sopInstanceUID, pos); if (result.good()) { /* then, check and set the value */ result = setSOPInstanceUID(sopInstanceUID, check); } return result; } OFCondition DSRCompositeReferenceValue::checkSOPClassUID(const OFString &sopClassUID, const OFBool /*reportWarnings*/) const { OFCondition result = sopClassUID.empty() ? SR_EC_InvalidValue : EC_Normal; if (result.good()) result = DcmUniqueIdentifier::checkStringValue(sopClassUID, "1"); return result; } OFCondition DSRCompositeReferenceValue::checkSOPInstanceUID(const OFString &sopInstanceUID, const OFBool /*reportWarnings*/) const { OFCondition result = sopInstanceUID.empty() ? SR_EC_InvalidValue : EC_Normal; if (result.good()) result = DcmUniqueIdentifier::checkStringValue(sopInstanceUID, "1"); return result; } OFCondition DSRCompositeReferenceValue::checkCurrentValue(const OFBool reportWarnings) const { OFCondition result = checkSOPClassUID(SOPClassUID, reportWarnings); if (result.good()) result = checkSOPInstanceUID(SOPInstanceUID, reportWarnings); return result; }