/* * * Copyright (C) 2015-2017, J. Riesmeier, Oldenburg, Germany * All rights reserved. See COPYRIGHT file for details. * * Source file for class TID1001_ObservationContext * * Author: Joerg Riesmeier * */ #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ #include "dcmtk/dcmsr/cmr/tid1001.h" #include "dcmtk/dcmsr/codes/dcm.h" #include "dcmtk/dcmdata/dcuid.h" // helper macros for checking the return value of API calls #define CHECK_RESULT(call) if (result.good()) result = call #define STORE_RESULT(call) result = call #define GOOD_RESULT(call) if (result.good()) call #define BAD_RESULT(call) if (result.bad()) call // index positions in node list (makes source code more readable) #define LAST_PERSON_OBSERVER 0 #define LAST_DEVICE_OBSERVER 1 #define NUMBER_OF_LIST_ENTRIES 2 // general information on TID 1001 (Observation Context) #define TEMPLATE_NUMBER "1001" #define MAPPING_RESOURCE "DCMR" #define MAPPING_RESOURCE_UID UID_DICOMContentMappingResource #define TEMPLATE_TYPE OFFalse /* non-extensible, but included templates are */ #define TEMPLATE_ORDER OFTrue /* significant */ TID1001_ObservationContext::TID1001_ObservationContext() : DSRSubTemplate(TEMPLATE_NUMBER, MAPPING_RESOURCE, MAPPING_RESOURCE_UID) { setExtensible(TEMPLATE_TYPE); setOrderSignificant(TEMPLATE_ORDER); /* need to store position of various content items */ reserveEntriesInNodeList(NUMBER_OF_LIST_ENTRIES); } OFCondition TID1001_ObservationContext::addPersonObserver(const OFString &personName, const OFString &organizationName, const CID7452_OrganizationalRoles &organizationRole, const CID7453_PerformingRoles &procedureRole, const OFBool check) { OFCondition result = EC_MemoryExhausted; /* create a new subtree in order to "rollback" in case of error */ DSRDocumentSubTree *subTree = new DSRDocumentSubTree; if (subTree != NULL) { /* TID 1002 (Observer Context) Row 1 */ STORE_RESULT(subTree->addContentItem(RT_hasObsContext, VT_Code, CODE_DCM_ObserverType, check)); CHECK_RESULT(subTree->getCurrentContentItem().setCodeValue(CODE_DCM_Person, check)); CHECK_RESULT(subTree->getCurrentContentItem().setAnnotationText("TID 1002 - Row 1")); /* TID 1003 (Person Observer Identifying Attributes) Row 1 */ CHECK_RESULT(subTree->addContentItem(RT_hasObsContext, VT_PName, CODE_DCM_PersonObserverName)); CHECK_RESULT(subTree->getCurrentContentItem().setStringValue(personName, check)); CHECK_RESULT(subTree->getCurrentContentItem().setAnnotationText("TID 1003 - Row 1")); /* TID 1003 (Person Observer Identifying Attributes) Row 2 */ if (!organizationName.empty()) { CHECK_RESULT(subTree->addContentItem(RT_hasObsContext, VT_Text, CODE_DCM_PersonObserverOrganizationName, check)); CHECK_RESULT(subTree->getCurrentContentItem().setStringValue(organizationName, check)); CHECK_RESULT(subTree->getCurrentContentItem().setAnnotationText("TID 1003 - Row 2")); } /* TID 1003 (Person Observer Identifying Attributes) Row 3 */ if (organizationRole.hasSelectedValue()) { CHECK_RESULT(subTree->addContentItem(RT_hasObsContext, VT_Code, CODE_DCM_PersonObserverRoleInTheOrganization, check)); CHECK_RESULT(subTree->getCurrentContentItem().setCodeValue(organizationRole, check)); CHECK_RESULT(subTree->getCurrentContentItem().setAnnotationText("TID 1003 - Row 3")); } /* TID 1003 (Person Observer Identifying Attributes) Row 4 */ if (procedureRole.hasSelectedValue()) { CHECK_RESULT(subTree->addContentItem(RT_hasObsContext, VT_Code, CODE_DCM_PersonObserverRoleInThisProcedure, check)); CHECK_RESULT(subTree->getCurrentContentItem().setCodeValue(procedureRole, check)); CHECK_RESULT(subTree->getCurrentContentItem().setAnnotationText("TID 1003 - Row 4")); } /* if everything was OK, insert new subtree into the template */ if (result.good()) { const size_t lastNode = subTree->getNodeID(); /* order is significant, so go to last person observer */ if (gotoLastEntryFromNodeList(this, LAST_PERSON_OBSERVER) > 0) { /* insert subtree at current position */ STORE_RESULT(insertSubTree(subTree, AM_afterCurrent)); } else { /* this is the first person observer (but there might be device observers) */ gotoRoot(); /* insert subtree before current position (at the beginning of the tree) */ STORE_RESULT(insertSubTree(subTree, AM_beforeCurrent)); } /* store ID of recently added node for later use */ GOOD_RESULT(storeEntryInNodeList(LAST_PERSON_OBSERVER, lastNode)); } /* in case of error, make sure that memory is freed */ BAD_RESULT(delete subTree); } return result; } OFCondition TID1001_ObservationContext::addDeviceObserver(const OFString &deviceUID, const OFString &deviceName, const OFString &manufacturer, const OFString &modelName, const OFString &serialNumber, const OFString &physicalLocation, const DeviceParticipatingRolesList &procedureRoles, const OFString &stationAEtitle, const OFBool check) { OFCondition result = EC_MemoryExhausted; /* create a new subtree in order to "rollback" in case of error */ DSRDocumentSubTree *subTree = new DSRDocumentSubTree; if (subTree != NULL) { /* TID 1002 (Observer Context) Row 1 */ STORE_RESULT(subTree->addContentItem(RT_hasObsContext, VT_Code, CODE_DCM_ObserverType, check)); CHECK_RESULT(subTree->getCurrentContentItem().setCodeValue(CODE_DCM_Device, check)); CHECK_RESULT(subTree->getCurrentContentItem().setAnnotationText("TID 1002 - Row 1")); /* TID 1004 (Device Observer Identifying Attributes) Row 1 */ CHECK_RESULT(subTree->addContentItem(RT_hasObsContext, VT_UIDRef, CODE_DCM_DeviceObserverUID)); CHECK_RESULT(subTree->getCurrentContentItem().setStringValue(deviceUID, check)); CHECK_RESULT(subTree->getCurrentContentItem().setAnnotationText("TID 1004 - Row 1")); /* TID 1004 (Device Observer Identifying Attributes) Row 2 */ if (!deviceName.empty()) { CHECK_RESULT(subTree->addContentItem(RT_hasObsContext, VT_Text, CODE_DCM_DeviceObserverName, check)); CHECK_RESULT(subTree->getCurrentContentItem().setStringValue(deviceName, check)); CHECK_RESULT(subTree->getCurrentContentItem().setAnnotationText("TID 1004 - Row 2")); } /* TID 1004 (Device Observer Identifying Attributes) Row 3 */ if (!manufacturer.empty()) { CHECK_RESULT(subTree->addContentItem(RT_hasObsContext, VT_Text, CODE_DCM_DeviceObserverManufacturer, check)); CHECK_RESULT(subTree->getCurrentContentItem().setStringValue(manufacturer, check)); CHECK_RESULT(subTree->getCurrentContentItem().setAnnotationText("TID 1004 - Row 3")); } /* TID 1004 (Device Observer Identifying Attributes) Row 4 */ if (!modelName.empty()) { CHECK_RESULT(subTree->addContentItem(RT_hasObsContext, VT_Text, CODE_DCM_DeviceObserverModelName, check)); CHECK_RESULT(subTree->getCurrentContentItem().setStringValue(modelName, check)); CHECK_RESULT(subTree->getCurrentContentItem().setAnnotationText("TID 1004 - Row 4")); } /* TID 1004 (Device Observer Identifying Attributes) Row 5 */ if (!serialNumber.empty()) { CHECK_RESULT(subTree->addContentItem(RT_hasObsContext, VT_Text, CODE_DCM_DeviceObserverSerialNumber, check)); CHECK_RESULT(subTree->getCurrentContentItem().setStringValue(serialNumber, check)); CHECK_RESULT(subTree->getCurrentContentItem().setAnnotationText("TID 1004 - Row 5")); } /* TID 1004 (Device Observer Identifying Attributes) Row 6 */ if (!physicalLocation.empty()) { CHECK_RESULT(subTree->addContentItem(RT_hasObsContext, VT_Text, CODE_DCM_DeviceObserverPhysicalLocationDuringObservation, check)); CHECK_RESULT(subTree->getCurrentContentItem().setStringValue(physicalLocation, check)); CHECK_RESULT(subTree->getCurrentContentItem().setAnnotationText("TID 1004 - Row 6")); } /* TID 1004 (Device Observer Identifying Attributes) Row 7 */ if (!procedureRoles.empty()) { OFListConstIterator(CID7445_DeviceParticipatingRoles) iter = procedureRoles.begin(); const OFListConstIterator(CID7445_DeviceParticipatingRoles) last = procedureRoles.end(); /* iterate over all list entries */ while ((iter != last) && result.good()) { STORE_RESULT(subTree->addContentItem(RT_hasObsContext, VT_Code, CODE_DCM_DeviceRoleInProcedure, check)); CHECK_RESULT(subTree->getCurrentContentItem().setCodeValue(iter->getSelectedValue(), check)); CHECK_RESULT(subTree->getCurrentContentItem().setAnnotationText("TID 1004 - Row 7")); ++iter; } } /* TID 1004 (Device Observer Identifying Attributes) Row 8 */ if (!stationAEtitle.empty()) { CHECK_RESULT(subTree->addContentItem(RT_hasObsContext, VT_Text, CODE_DCM_StationAETitle, check)); CHECK_RESULT(subTree->getCurrentContentItem().setStringValue(stationAEtitle, check)); CHECK_RESULT(subTree->getCurrentContentItem().setAnnotationText("TID 1004 - Row 8")); } /* if everything was OK, insert new subtree into the template */ if (result.good()) { const size_t lastNode = subTree->getNodeID(); /* order is significant, so go to last device (or person) observer */ gotoLastEntryFromNodeList(this, LAST_DEVICE_OBSERVER); /* insert subtree at current position */ STORE_RESULT(insertSubTree(subTree, AM_afterCurrent)); /* store ID of recently added node for later use */ GOOD_RESULT(storeEntryInNodeList(LAST_DEVICE_OBSERVER, lastNode)); } /* in case of error, make sure that memory is freed */ BAD_RESULT(delete subTree); } return result; } OFCondition TID1001_ObservationContext::addProcedureContext() { /* tbd: not yet implemented */ return EC_NotYetImplemented; } OFCondition TID1001_ObservationContext::addSubjectContext() { /* tbd: not yet implemented */ return EC_NotYetImplemented; }