This is an automated email from the git hooks/post-receive script. lamy-guest pushed a commit to branch master in repository odil.
commit ef8f6c6d9f42e598242a279a312f6f0cecf17cf2 Author: Julien Lamy <l...@unistra.fr> Date: Thu Oct 20 14:20:25 2016 +0200 Imported Upstream version 0.7.3 --- applications/print_.py | 4 +- src/odil/AssociationParameters.cpp | 135 +++++++++- src/odil/AssociationParameters.h | 48 ++++ src/odil/pdu/AsynchronousOperationsWindow.cpp | 87 +++++++ src/odil/pdu/AsynchronousOperationsWindow.h | 55 ++++ src/odil/pdu/SOPClassCommonExtendedNegotiation.cpp | 190 ++++++++++++++ src/odil/pdu/SOPClassCommonExtendedNegotiation.h | 69 ++++++ src/odil/pdu/SOPClassExtendedNegotiation.cpp | 120 +++++++++ src/odil/pdu/SOPClassExtendedNegotiation.h | 63 +++++ src/odil/pdu/UserInformation.cpp | 35 ++- src/odil/registry.cpp | 276 +++++++++++++++++++-- src/odil/registry.h | 92 ++++++- tests/code/AssociationParameters.cpp | 24 +- tests/code/dul/Transport.cpp | 1 - tests/code/pdu/AsynchronousOperationsWindow.cpp | 59 +++++ .../code/pdu/SOPClassCommonExtendedNegotiation.cpp | 87 +++++++ tests/code/pdu/SOPClassExtendedNegotiation.cpp | 71 ++++++ wrappers/json_converter.cpp | 8 +- 18 files changed, 1389 insertions(+), 35 deletions(-) diff --git a/applications/print_.py b/applications/print_.py index 2a7be04..0179984 100644 --- a/applications/print_.py +++ b/applications/print_.py @@ -50,7 +50,9 @@ def print_data_set(data_set, decode_uids, padding, max_length): "s" if sum(lengths)>1 else "") else: getter = None - if element.is_int(): + if element.empty(): + getter = lambda: [] + elif element.is_int(): getter = element.as_int elif element.is_real(): getter = element.as_real diff --git a/src/odil/AssociationParameters.cpp b/src/odil/AssociationParameters.cpp index e152cee..6d9d605 100644 --- a/src/odil/AssociationParameters.cpp +++ b/src/odil/AssociationParameters.cpp @@ -18,11 +18,14 @@ #include "odil/pdu/AAssociateRQ.h" #include "odil/Exception.h" #include "odil/uid.h" +#include "odil/pdu/AsynchronousOperationsWindow.h" #include "odil/pdu/ImplementationClassUID.h" #include "odil/pdu/ImplementationVersionName.h" #include "odil/pdu/PresentationContextAC.h" #include "odil/pdu/PresentationContextRQ.h" #include "odil/pdu/RoleSelection.h" +#include "odil/pdu/SOPClassExtendedNegotiation.h" +#include "odil/pdu/SOPClassCommonExtendedNegotiation.h" namespace odil { @@ -102,7 +105,9 @@ AssociationParameters::UserIdentity AssociationParameters ::AssociationParameters() : _called_ae_title(""), _calling_ae_title(""), _presentation_contexts(), - _user_identity(), _maximum_length(16384) + _user_identity({UserIdentity::Type::None, "", ""}), _maximum_length(16384), + _maximum_number_operations_invoked(1), _maximum_number_operations_performed(1), + _sop_class_extended_negotiation(), _sop_class_common_extended_negotiation() { // Nothing else. } @@ -178,6 +183,20 @@ AssociationParameters { this->set_maximum_length(maximum_length[0].get_maximum_length()); } + + // Maximum number of operations performed/invoked + auto const asynchronous_operations_window = + user_information.get_sub_items<pdu::AsynchronousOperationsWindow>(); + if(!asynchronous_operations_window.empty()) + { + this->_maximum_number_operations_invoked = + asynchronous_operations_window[0].get_maximum_number_operations_invoked(); + this->_maximum_number_operations_performed = + asynchronous_operations_window[0].get_maximum_number_operations_performed(); + } + + this->_sop_class_common_extended_negotiation = + user_information.get_sub_items<pdu::SOPClassCommonExtendedNegotiation>(); } AssociationParameters @@ -252,6 +271,19 @@ AssociationParameters { this->set_maximum_length(maximum_length[0].get_maximum_length()); } + + // Maximum number of operations performed/invoked + auto const asynchronous_operations_window = + user_information.get_sub_items<pdu::AsynchronousOperationsWindow>(); + if(!asynchronous_operations_window.empty()) + { + this->_maximum_number_operations_invoked = + asynchronous_operations_window[0].get_maximum_number_operations_invoked(); + this->_maximum_number_operations_performed = + asynchronous_operations_window[0].get_maximum_number_operations_performed(); + } + + // No SOPClassCommonExtendedNegotiation in AC } std::string const & @@ -384,6 +416,66 @@ AssociationParameters return *this; } +uint16_t +AssociationParameters +::get_maximum_number_operations_invoked() const +{ + return this->_maximum_number_operations_invoked; +} + +AssociationParameters & +AssociationParameters +::set_maximum_number_operations_invoked(uint16_t value) +{ + this->_maximum_number_operations_invoked = value; + return *this; +} + +uint16_t +AssociationParameters +::get_maximum_number_operations_performed() const +{ + return this->_maximum_number_operations_performed; +} + +AssociationParameters & +AssociationParameters +::set_maximum_number_operations_performed(uint16_t value) +{ + this->_maximum_number_operations_performed = value; + return *this; +} + +std::vector<pdu::SOPClassExtendedNegotiation> +AssociationParameters +::get_sop_class_extended_negotiation() const +{ + return this->_sop_class_extended_negotiation; +} + +void +AssociationParameters +::set_sop_class_extended_negotiation( + std::vector<pdu::SOPClassExtendedNegotiation> const & value) +{ + this->_sop_class_extended_negotiation = value; +} + +std::vector<pdu::SOPClassCommonExtendedNegotiation> +AssociationParameters +::get_sop_class_common_extended_negotiation() const +{ + return this->_sop_class_common_extended_negotiation; +} + +void +AssociationParameters +::set_sop_class_common_extended_negotiation( + std::vector<pdu::SOPClassCommonExtendedNegotiation> const & value) +{ + this->_sop_class_common_extended_negotiation = value; +} + pdu::AAssociateRQ AssociationParameters ::as_a_associate_rq() const @@ -419,6 +511,22 @@ AssociationParameters user_information.set_sub_items<pdu::ImplementationClassUID>( {implementation_class_uid}); + + if(this->_maximum_number_operations_invoked != 1 || + this->_maximum_number_operations_performed != 1) + { + user_information.set_sub_items<pdu::AsynchronousOperationsWindow>({{ + this->_maximum_number_operations_invoked, + this->_maximum_number_operations_performed + }}); + } + + user_information.set_sub_items<pdu::SOPClassExtendedNegotiation>( + this->_sop_class_extended_negotiation); + + user_information.set_sub_items<pdu::SOPClassCommonExtendedNegotiation>( + this->_sop_class_common_extended_negotiation); + user_information.set_sub_items<pdu::ImplementationVersionName>( {implementation_version_name}); @@ -487,6 +595,21 @@ AssociationParameters user_information.set_sub_items<pdu::ImplementationClassUID>( {implementation_class_uid}); + + if(this->_maximum_number_operations_invoked != 1 || + this->_maximum_number_operations_performed != 1) + { + user_information.set_sub_items<pdu::AsynchronousOperationsWindow>({{ + this->_maximum_number_operations_invoked, + this->_maximum_number_operations_performed + }}); + } + + user_information.set_sub_items<pdu::SOPClassExtendedNegotiation>( + this->_sop_class_extended_negotiation); + + // No SOPClassCommonExtendedNegotiation in AC + user_information.set_sub_items<pdu::ImplementationVersionName>( {implementation_version_name}); @@ -515,7 +638,15 @@ AssociationParameters this->get_calling_ae_title() == other.get_calling_ae_title() && this->get_presentation_contexts() == other.get_presentation_contexts() && this->get_user_identity() == other.get_user_identity() && - this->get_maximum_length() == other.get_maximum_length() + this->get_maximum_length() == other.get_maximum_length() && + this->get_maximum_number_operations_invoked() == + other.get_maximum_number_operations_invoked() && + this->get_maximum_number_operations_performed() == + other.get_maximum_number_operations_performed() && + this->get_sop_class_extended_negotiation() == + other.get_sop_class_extended_negotiation() && + this->get_sop_class_common_extended_negotiation() == + other.get_sop_class_common_extended_negotiation() ); } diff --git a/src/odil/AssociationParameters.h b/src/odil/AssociationParameters.h index 19e88e7..d11d582 100644 --- a/src/odil/AssociationParameters.h +++ b/src/odil/AssociationParameters.h @@ -15,6 +15,8 @@ #include "odil/pdu/AAssociateAC.h" #include "odil/pdu/AAssociateRQ.h" +#include "odil/pdu/SOPClassCommonExtendedNegotiation.h" +#include "odil/pdu/SOPClassExtendedNegotiation.h" namespace odil { @@ -170,6 +172,46 @@ public: * no maximum length. */ AssociationParameters & set_maximum_length(uint32_t value); + + /// @brief Return the maximum number of outstanding operations invoked + uint16_t get_maximum_number_operations_invoked() const; + + /** + * @brief Set the maximum number of outstanding operations invoked, + * default to 1. + */ + AssociationParameters & set_maximum_number_operations_invoked(uint16_t value); + + /// @brief Return the maximum number of outstanding operations performed + uint16_t get_maximum_number_operations_performed() const; + + /** + * @brief Set the maximum number of outstanding operations performed, + * default to 1. + */ + AssociationParameters & set_maximum_number_operations_performed(uint16_t value); + + /// @brief Return the list of SOP Class Extended Negotiation items. + std::vector<pdu::SOPClassExtendedNegotiation> + get_sop_class_extended_negotiation() const; + + /** + * @brief Set the list of SOP Class Extended Negotiation items, default + * to an empty list. + */ + void set_sop_class_extended_negotiation( + std::vector<pdu::SOPClassExtendedNegotiation> const & value); + + /// @brief Return the list of SOP Class Extended Negotiation items. + std::vector<pdu::SOPClassCommonExtendedNegotiation> + get_sop_class_common_extended_negotiation() const; + + /** + * @brief Set the list of SOP Class Common Extend Negotiation items, default + * to an empty list. + */ + void set_sop_class_common_extended_negotiation( + std::vector<pdu::SOPClassCommonExtendedNegotiation> const & value); /// @brief Create an A-ASSOCIATE-RQ PDU. pdu::AAssociateRQ as_a_associate_rq() const; @@ -186,6 +228,12 @@ private: std::vector<PresentationContext> _presentation_contexts; UserIdentity _user_identity; uint32_t _maximum_length; + uint16_t _maximum_number_operations_invoked; + uint16_t _maximum_number_operations_performed; + std::vector<pdu::SOPClassExtendedNegotiation> + _sop_class_extended_negotiation; + std::vector<pdu::SOPClassCommonExtendedNegotiation> + _sop_class_common_extended_negotiation; /// @brief Set the user identity. AssociationParameters & _set_user_identity(UserIdentity const & value); diff --git a/src/odil/pdu/AsynchronousOperationsWindow.cpp b/src/odil/pdu/AsynchronousOperationsWindow.cpp new file mode 100644 index 0000000..67ff5e5 --- /dev/null +++ b/src/odil/pdu/AsynchronousOperationsWindow.cpp @@ -0,0 +1,87 @@ +/************************************************************************* + * odil - Copyright (C) Universite de Strasbourg + * Distributed under the terms of the CeCILL-B license, as published by + * the CEA-CNRS-INRIA. Refer to the LICENSE file or to + * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html + * for details. + ************************************************************************/ + +#include "odil/pdu/AsynchronousOperationsWindow.h" + +#include <cstdint> +#include <istream> + +#include "odil/Exception.h" +#include "odil/pdu/Object.h" + +namespace odil +{ + +namespace pdu +{ + +AsynchronousOperationsWindow +::AsynchronousOperationsWindow( + uint16_t maximum_number_operations_invoked, + uint16_t maximum_number_operations_performed) +{ + this->_item.add("Item-type", this->type); + this->_item.add("Reserved", uint8_t(0)); + this->_item.add("Item-length", uint16_t(4)); + this->_item.add("Maximum-number-operations-invoked", uint16_t(0)); + this->_item.add("Maximum-number-operations-performed", uint16_t(0)); + + this->set_maximum_number_operations_invoked(maximum_number_operations_invoked); + this->set_maximum_number_operations_performed(maximum_number_operations_performed); +} + +AsynchronousOperationsWindow +::AsynchronousOperationsWindow(std::istream & stream) +{ + this->_item.read(stream, "Item-type", Item::Field::Type::unsigned_int_8); + if(this->_item.as_unsigned_int_8("Item-type") != this->type) + { + throw Exception("Invalid item type"); + } + + this->_item.read(stream, "Reserved", Item::Field::Type::unsigned_int_8); + this->_item.read(stream, "Item-length", Item::Field::Type::unsigned_int_16); + this->_item.read( + stream, "Maximum-number-operations-invoked", + Item::Field::Type::unsigned_int_16); + this->_item.read( + stream, "Maximum-number-operations-performed", + Item::Field::Type::unsigned_int_16); +} + +uint16_t +AsynchronousOperationsWindow +::get_maximum_number_operations_invoked() const +{ + return this->_item.as_unsigned_int_16("Maximum-number-operations-invoked"); +} + +void +AsynchronousOperationsWindow +::set_maximum_number_operations_invoked(uint16_t value) +{ + this->_item.as_unsigned_int_16("Maximum-number-operations-invoked") = value; +} + +uint16_t +AsynchronousOperationsWindow +::get_maximum_number_operations_performed() const +{ + return this->_item.as_unsigned_int_16("Maximum-number-operations-performed"); +} + +void +AsynchronousOperationsWindow +::set_maximum_number_operations_performed(uint16_t value) +{ + this->_item.as_unsigned_int_16("Maximum-number-operations-performed") = value; +} + +} + +} diff --git a/src/odil/pdu/AsynchronousOperationsWindow.h b/src/odil/pdu/AsynchronousOperationsWindow.h new file mode 100644 index 0000000..608246b --- /dev/null +++ b/src/odil/pdu/AsynchronousOperationsWindow.h @@ -0,0 +1,55 @@ +/************************************************************************* + * odil - Copyright (C) Universite de Strasbourg + * Distributed under the terms of the CeCILL-B license, as published by + * the CEA-CNRS-INRIA. Refer to the LICENSE file or to + * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html + * for details. + ************************************************************************/ + +#ifndef _a24346ab_a585_4412_9237_5b2142f2d6eb +#define _a24346ab_a585_4412_9237_5b2142f2d6eb + +#include <cstdint> +#include <istream> + +#include "odil/pdu/Object.h" + +namespace odil +{ + +namespace pdu +{ + +/// @brief Asynchronous Operations Window Sub-Item (PS 3.7, D.3.3.3.1 and D.3.3.3.2). +class AsynchronousOperationsWindow: public Object +{ +public: + /// @brief Item type. + static uint8_t const type=0x53; + + /// @brief Create a Asynchronous Operations Window item. + AsynchronousOperationsWindow( + uint16_t maximum_number_operations_invoked, + uint16_t maximum_number_operations_performed); + + /// @brief Read a Asynchronous Operations Window item from a stream. + AsynchronousOperationsWindow(std::istream & stream); + + /// @brief Return the Maximum-number-operations-invoked. + uint16_t get_maximum_number_operations_invoked() const; + + /// @brief Set the Maximum-number-operations-invoked. + void set_maximum_number_operations_invoked(uint16_t value); + + /// @brief Return the Maximum-number-operations-performed. + uint16_t get_maximum_number_operations_performed() const; + + /// @brief Set the Maximum-number-operations-performed. + void set_maximum_number_operations_performed(uint16_t value); +}; + +} + +} + +#endif // _a24346ab_a585_4412_9237_5b2142f2d6eb diff --git a/src/odil/pdu/SOPClassCommonExtendedNegotiation.cpp b/src/odil/pdu/SOPClassCommonExtendedNegotiation.cpp new file mode 100644 index 0000000..fdafbb7 --- /dev/null +++ b/src/odil/pdu/SOPClassCommonExtendedNegotiation.cpp @@ -0,0 +1,190 @@ +/************************************************************************* + * odil - Copyright (C) Universite de Strasbourg + * Distributed under the terms of the CeCILL-B license, as published by + * the CEA-CNRS-INRIA. Refer to the LICENSE file or to + * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html + * for details. + ************************************************************************/ + +#include "odil/pdu/SOPClassCommonExtendedNegotiation.h" + +#include <algorithm> +#include <istream> +#include <string> +#include <vector> + +#include "odil/Exception.h" +#include "odil/pdu/Object.h" + +namespace odil +{ + +namespace pdu +{ + +SOPClassCommonExtendedNegotiation +::SOPClassCommonExtendedNegotiation( + std::string const & sop_class_uid, std::string const & service_class_uid, + std::vector<std::string> const & related_general_sop_class_uids) +{ + this->_item.add("Item-type", this->type); + this->_item.add("Sub-item-version", uint8_t(0)); + this->_item.add("Item-length", uint16_t(0)); + this->_item.add("SOP-class-uid-length", uint16_t(0)); + this->_item.add("SOP-class-uid", std::string()); + this->_item.add("Service-class-uid-length", uint16_t(0)); + this->_item.add("Service-class-uid", std::string()); + this->_item.add( + "Related-general-sop-class-identification-length", uint16_t(0)); + this->_item.add( + "Related-general-sop-class-identification", std::vector<Item>()); + + this->set_sop_class_uid(sop_class_uid); + this->set_service_class_uid(service_class_uid); + this->set_related_general_sop_class_uids(related_general_sop_class_uids); +} + +SOPClassCommonExtendedNegotiation +::SOPClassCommonExtendedNegotiation(std::istream & stream) +{ + this->_item.read(stream, "Item-type", Item::Field::Type::unsigned_int_8); + if(this->_item.as_unsigned_int_8("Item-type") != this->type) + { + throw Exception("Invalid item type"); + } + + this->_item.read( + stream, "Sub-item-version", Item::Field::Type::unsigned_int_8); + this->_item.read(stream, "Item-length", Item::Field::Type::unsigned_int_16); + + this->_item.read( + stream, "SOP-class-uid-length", Item::Field::Type::unsigned_int_16); + this->_item.read( + stream, "SOP-class-uid", Item::Field::Type::string, + this->_item.as_unsigned_int_16("SOP-class-uid-length")); + + this->_item.read( + stream, "Service-class-uid-length", Item::Field::Type::unsigned_int_16); + this->_item.read( + stream, "Service-class-uid", Item::Field::Type::string, + this->_item.as_unsigned_int_16("Service-class-uid-length")); + + this->_item.read( + stream, "Related-general-sop-class-identification-length", + Item::Field::Type::unsigned_int_16); + auto const related_classes_length = this->_item.as_unsigned_int_16( + "Related-general-sop-class-identification-length"); + + auto const begin = stream.tellg(); + std::vector<Item> sub_items; + while(stream.tellg()-begin < related_classes_length) + { + Item item; + item.read( + stream, "Related-general-sop-class-uid-length", + Item::Field::Type::unsigned_int_16); + item.read( + stream, "Related-general-sop-class-uid", Item::Field::Type::string, + item.as_unsigned_int_16("Related-general-sop-class-uid-length")); + sub_items.push_back(item); + } + this->_item.add("Related-general-sop-class-identification", sub_items); +} + +bool +SOPClassCommonExtendedNegotiation +::operator==(SOPClassCommonExtendedNegotiation const & other) const +{ + return ( + this->get_sop_class_uid() == other.get_sop_class_uid() + && this->get_service_class_uid() == other.get_service_class_uid() + && this->get_related_general_sop_class_uids() == + other.get_related_general_sop_class_uids() + ); +} + +std::string const & +SOPClassCommonExtendedNegotiation +::get_sop_class_uid() const +{ + return this->_item.as_string("SOP-class-uid"); +} + +void +SOPClassCommonExtendedNegotiation +::set_sop_class_uid(std::string const & value) +{ + this->_item.as_unsigned_int_16("SOP-class-uid-length") = value.size(); + this->_item.as_string("SOP-class-uid") = value; + this->_item.as_unsigned_int_16("Item-length") = this->_compute_length(); +} + +std::string const & +SOPClassCommonExtendedNegotiation +::get_service_class_uid() const +{ + return this->_item.as_string("Service-class-uid"); +} + +void +SOPClassCommonExtendedNegotiation +::set_service_class_uid(std::string const & value) +{ + this->_item.as_unsigned_int_16("Service-class-uid-length") = value.size(); + this->_item.as_string("Service-class-uid") = value; + this->_item.as_unsigned_int_16("Item-length") = this->_compute_length(); +} + +std::vector<std::string> +SOPClassCommonExtendedNegotiation +::get_related_general_sop_class_uids() const +{ + auto const & sub_items = this->_item.as_items( + "Related-general-sop-class-identification"); + + std::vector<std::string> result(sub_items.size()); + std::transform( + sub_items.begin(), sub_items.end(), + result.begin(), + [](Item const & item) + { + return item.as_string("Related-general-sop-class-uid"); + }); + + return result; +} + +void +SOPClassCommonExtendedNegotiation +::set_related_general_sop_class_uids(std::vector<std::string> const & value) +{ + auto & sub_items = this->_item.as_items( + "Related-general-sop-class-identification"); + sub_items.resize(value.size()); + uint16_t size=0; + std::transform( + value.begin(), value.end(), + sub_items.begin(), + [&size](std::string const & sop_class_uid) + { + Item item; + item.add( + "Related-general-sop-class-uid-length", + uint16_t(sop_class_uid.size())); + item.add("Related-general-sop-class-uid", sop_class_uid); + + size += (2+sop_class_uid.size()); + + return item; + }); + + this->_item.as_unsigned_int_16( + "Related-general-sop-class-identification-length") = size; + this->_item.as_items( + "Related-general-sop-class-identification") = sub_items; + this->_item.as_unsigned_int_16("Item-length") = this->_compute_length(); +} + +} + +} diff --git a/src/odil/pdu/SOPClassCommonExtendedNegotiation.h b/src/odil/pdu/SOPClassCommonExtendedNegotiation.h new file mode 100644 index 0000000..36ef78d --- /dev/null +++ b/src/odil/pdu/SOPClassCommonExtendedNegotiation.h @@ -0,0 +1,69 @@ +/************************************************************************* + * odil - Copyright (C) Universite de Strasbourg + * Distributed under the terms of the CeCILL-B license, as published by + * the CEA-CNRS-INRIA. Refer to the LICENSE file or to + * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html + * for details. + ************************************************************************/ + +#ifndef _4182d886_9654_4ec2_8cd6_7f334f290e56 +#define _4182d886_9654_4ec2_8cd6_7f334f290e56 + +#include <istream> +#include <string> +#include <vector> + +#include "odil/pdu/Object.h" + +namespace odil +{ + +namespace pdu +{ + +/// @brief SOP Class Common Extended Negotiation sub-item (PS 3.7, D.3.3.6). +class SOPClassCommonExtendedNegotiation: public Object +{ +public: + /// @brief Item type. + static uint8_t const type=0x57; + + /// @brief Constructor. + SOPClassCommonExtendedNegotiation( + std::string const & sop_class_uid, + std::string const & service_class_uid="", + std::vector<std::string> const & + related_general_sop_class_uids=std::vector<std::string>()); + + /// @brief Read a SOP Class Common Extended Negotiation from a stream. + SOPClassCommonExtendedNegotiation(std::istream & stream); + + /// @brief Comparison. + bool operator==(SOPClassCommonExtendedNegotiation const & other) const; + + /// @brief Return the SOP Class UID. + std::string const & get_sop_class_uid() const; + + /// @brief Set the SOP Class UID. + void set_sop_class_uid(std::string const & value); + + /// @brief Return the Service Class UID. + std::string const & get_service_class_uid() const; + + /// @brief Set the Service Class UID (default to ""). + void set_service_class_uid(std::string const & value); + + /// @brief Return the Related General SOP Class UIDs. + std::vector<std::string> get_related_general_sop_class_uids() const; + + /// @brief Set the Related General SOP Class UIDs (default to empty). + void set_related_general_sop_class_uids( + std::vector<std::string> const & value); + +}; + +} + +} + +#endif // _4182d886_9654_4ec2_8cd6_7f334f290e56 diff --git a/src/odil/pdu/SOPClassExtendedNegotiation.cpp b/src/odil/pdu/SOPClassExtendedNegotiation.cpp new file mode 100644 index 0000000..a8fcab2 --- /dev/null +++ b/src/odil/pdu/SOPClassExtendedNegotiation.cpp @@ -0,0 +1,120 @@ +/************************************************************************* + * odil - Copyright (C) Universite de Strasbourg + * Distributed under the terms of the CeCILL-B license, as published by + * the CEA-CNRS-INRIA. Refer to the LICENSE file or to + * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html + * for details. + ************************************************************************/ + +#include "odil/pdu/SOPClassExtendedNegotiation.h" + +#include <algorithm> +#include <cstdint> +#include <istream> +#include <string> +#include <vector> + +#include "odil/Exception.h" +#include "odil/pdu/Object.h" + +namespace odil +{ + +namespace pdu +{ + +SOPClassExtendedNegotiation +::SOPClassExtendedNegotiation( + std::string const & sop_class_uid, + std::vector<uint8_t> const & service_class_application_information) +{ + this->_item.add("Item-type", this->type); + this->_item.add("Reserved", uint8_t(0)); + this->_item.add("Item-length", uint16_t(0)); + this->_item.add("SOP-class-uid-length", uint16_t(0)); + this->_item.add("SOP-class-uid", std::string()); + this->_item.add("Service-class-application-information", std::string()); + + this->set_sop_class_uid(sop_class_uid); + this->set_service_class_application_information( + service_class_application_information); +} + +SOPClassExtendedNegotiation +::SOPClassExtendedNegotiation(std::istream & stream) +{ + this->_item.read(stream, "Item-type", Item::Field::Type::unsigned_int_8); + if(this->_item.as_unsigned_int_8("Item-type") != this->type) + { + throw Exception("Invalid item type"); + } + + this->_item.read(stream, "Reserved", Item::Field::Type::unsigned_int_8); + this->_item.read(stream, "Item-length", Item::Field::Type::unsigned_int_16); + + this->_item.read( + stream, "SOP-class-uid-length", Item::Field::Type::unsigned_int_16); + this->_item.read( + stream, "SOP-class-uid", Item::Field::Type::string, + this->_item.as_unsigned_int_16("SOP-class-uid-length")); + + this->_item.read( + stream, "Service-class-application-information", + Item::Field::Type::string, + this->_item.as_unsigned_int_16("Item-length") + -this->_item.as_unsigned_int_16("SOP-class-uid-length") + -2); +} + +bool +SOPClassExtendedNegotiation +::operator==(SOPClassExtendedNegotiation const & other) const +{ + return ( + this->get_sop_class_uid() == other.get_sop_class_uid() + && this->get_service_class_application_information() == + other.get_service_class_application_information() + ); +} + +std::string const & +SOPClassExtendedNegotiation +::get_sop_class_uid() const +{ + return this->_item.as_string("SOP-class-uid"); +} + +void +SOPClassExtendedNegotiation +::set_sop_class_uid(std::string const & value) +{ + this->_item.as_unsigned_int_16("SOP-class-uid-length") = value.size(); + this->_item.as_string("SOP-class-uid") = value; + this->_item.as_unsigned_int_16("Item-length") = this->_compute_length(); +} + +std::vector<uint8_t> +SOPClassExtendedNegotiation +::get_service_class_application_information() const +{ + auto const & string = this->_item.as_string( + "Service-class-application-information"); + std::vector<uint8_t> result(string.size()); + std::copy(string.begin(), string.end(), result.begin()); + return result; +} + +void +SOPClassExtendedNegotiation +::set_service_class_application_information(std::vector<uint8_t> const & value) +{ + std::string string(value.size(), '\0'); + std::copy(value.begin(), value.end(), string.begin()); + + this->_item.as_string("Service-class-application-information") = string; + this->_item.as_unsigned_int_16("Item-length") = this->_compute_length(); +} + +} + +} diff --git a/src/odil/pdu/SOPClassExtendedNegotiation.h b/src/odil/pdu/SOPClassExtendedNegotiation.h new file mode 100644 index 0000000..91acf0f --- /dev/null +++ b/src/odil/pdu/SOPClassExtendedNegotiation.h @@ -0,0 +1,63 @@ +/************************************************************************* + * odil - Copyright (C) Universite de Strasbourg + * Distributed under the terms of the CeCILL-B license, as published by + * the CEA-CNRS-INRIA. Refer to the LICENSE file or to + * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html + * for details. + ************************************************************************/ + +#ifndef _6e3d351d_e5dc_4ab6_9c2d_8582e4fe2aa5 +#define _6e3d351d_e5dc_4ab6_9c2d_8582e4fe2aa5 + +#include <cstdint> +#include <istream> +#include <string> +#include <vector> + +#include "odil/pdu/Object.h" + +namespace odil +{ + +namespace pdu +{ + +/// @brief SOP Class Extended Negotiation sub-item (PS 3.7, D.3.3.5). +class SOPClassExtendedNegotiation: public Object +{ +public: + /// @brief Item type. + static uint8_t const type=0x56; + + /// @brief Constructor. + SOPClassExtendedNegotiation( + std::string const & sop_class_uid, + std::vector<uint8_t> const & service_class_application_information); + + /// @brief Read a SOP Class Common Extended Negotiation from a stream. + SOPClassExtendedNegotiation(std::istream & stream); + + /// @brief Comparison. + bool operator==(SOPClassExtendedNegotiation const & other) const; + + /// @brief Return the SOP Class UID. + std::string const & get_sop_class_uid() const; + + /// @brief Set the SOP Class UID. + void set_sop_class_uid(std::string const & value); + + /// @brief Return the Service Class Application Information. + std::vector<uint8_t> get_service_class_application_information() const; + + /// @brief Set the Service Class Application Information. + void set_service_class_application_information( + std::vector<uint8_t> const & value); + + +}; + +} + +} + +#endif // _6e3d351d_e5dc_4ab6_9c2d_8582e4fe2aa5 diff --git a/src/odil/pdu/UserInformation.cpp b/src/odil/pdu/UserInformation.cpp index e788519..0576b49 100644 --- a/src/odil/pdu/UserInformation.cpp +++ b/src/odil/pdu/UserInformation.cpp @@ -15,11 +15,14 @@ #include "odil/endian.h" #include "odil/Exception.h" #include "odil/logging.h" +#include "odil/pdu/AsynchronousOperationsWindow.h" #include "odil/pdu/ImplementationClassUID.h" #include "odil/pdu/ImplementationVersionName.h" #include "odil/pdu/MaximumLength.h" #include "odil/pdu/Object.h" #include "odil/pdu/RoleSelection.h" +#include "odil/pdu/SOPClassCommonExtendedNegotiation.h" +#include "odil/pdu/SOPClassExtendedNegotiation.h" #include "odil/pdu/UserIdentityAC.h" #include "odil/pdu/UserIdentityRQ.h" @@ -60,8 +63,12 @@ UserInformation std::vector<MaximumLength> maximum_length; std::vector<ImplementationClassUID> implementation_class_uid; + std::vector<AsynchronousOperationsWindow> asynchronous_operation_window; std::vector<RoleSelection> role_selection; std::vector<ImplementationVersionName> implementation_version_name; + std::vector<SOPClassExtendedNegotiation> sop_class_extended_negotiation; + std::vector<SOPClassCommonExtendedNegotiation> + sop_class_common_extended_negotiation; std::vector<UserIdentityRQ> user_identity_rq; std::vector<UserIdentityAC> user_identity_ac; @@ -70,31 +77,39 @@ UserInformation uint8_t const type = stream.peek(); if(type == 0x51) { - maximum_length.push_back(MaximumLength(stream)); + maximum_length.emplace_back(stream); } else if(type == 0x52) { - implementation_class_uid.push_back(ImplementationClassUID(stream)); + implementation_class_uid.emplace_back(stream); + } + else if(type == 0x53) + { + asynchronous_operation_window.emplace_back(stream); } - // 0x53: Asynchronous Operations Window, PS 3.7, D.3.3.3.1 else if(type == 0x54) { - role_selection.push_back(RoleSelection(stream)); + role_selection.emplace_back(stream); } else if(type == 0x55) { - implementation_version_name.push_back( - ImplementationVersionName(stream)); + implementation_version_name.emplace_back(stream); + } + else if(type == 0x56) + { + sop_class_extended_negotiation.emplace_back(stream); + } + else if(type == 0x57) + { + sop_class_common_extended_negotiation.emplace_back(stream); } - // 0x56: SOP Class Extended Negotiation, PS 3.7, D.3.3.5.1 - // 0x57: SOP Class Common Extended Negotiation, PS 3.7, D.3.3.6.1 else if(type == 0x58) { - user_identity_rq.push_back(UserIdentityRQ(stream)); + user_identity_rq.emplace_back(stream); } else if(type == 0x59) { - user_identity_ac.push_back(UserIdentityAC(stream)); + user_identity_ac.emplace_back(stream); } else { diff --git a/src/odil/registry.cpp b/src/odil/registry.cpp index e8b39d7..d15a09d 100644 --- a/src/odil/registry.cpp +++ b/src/odil/registry.cpp @@ -304,6 +304,12 @@ ElementsDictionary create_public_dictionary() "Mapping Resource Identification Sequence", "MappingResourceIdentificationSequence", "SQ", "1" }, { Tag(0x0008, 0x0201), "Timezone Offset From UTC", "TimezoneOffsetFromUTC", "SH", "1" }, + { Tag(0x0008, 0x0220), + "Responsible Group Code Sequence", "ResponsibleGroupCodeSequence", "SQ", "1" }, + { Tag(0x0008, 0x0221), + "Equipment Modality", "EquipmentModality", "CS", "1" }, + { Tag(0x0008, 0x0222), + "Manufacturer's Related Model Group", "ManufacturerRelatedModelGroup", "LO", "1" }, { Tag(0x0008, 0x0300), "Private Data Element Characteristics Sequence", "PrivateDataElementCharacteristicsSequence", "SQ", "1" }, { Tag(0x0008, 0x0301), @@ -320,6 +326,24 @@ ElementsDictionary create_public_dictionary() "Deidentification Action Sequence", "DeidentificationActionSequence", "SQ", "1" }, { Tag(0x0008, 0x0307), "Deidentification Action", "DeidentificationAction", "CS", "1" }, + { Tag(0x0008, 0x0308), + "Private Data Element", "PrivateDataElement", "US", "1" }, + { Tag(0x0008, 0x0309), + "Private Data Element Value Multiplicity", "PrivateDataElementValueMultiplicity", "UL", "1-3" }, + { Tag(0x0008, 0x030a), + "Private Data Element Value Representation", "PrivateDataElementValueRepresentation", "CS", "1" }, + { Tag(0x0008, 0x030b), + "Private Data Element Number of Items", "PrivateDataElementNumberOfItems", "UL", "1-2" }, + { Tag(0x0008, 0x030c), + "Private Data Element Name", "PrivateDataElementName", "UC", "1" }, + { Tag(0x0008, 0x030d), + "Private Data Element Keyword", "PrivateDataElementKeyword", "UC", "1" }, + { Tag(0x0008, 0x030e), + "Private Data Element Description", "PrivateDataElementDescription", "UT", "1" }, + { Tag(0x0008, 0x030f), + "Private Data Element Encoding", "PrivateDataElementEncoding", "UT", "1" }, + { Tag(0x0008, 0x0310), + "Private Data Element Definition Sequence", "PrivateDataElementDefinitionSequence", "SQ", "1" }, { Tag(0x0008, 0x1000), "Network ID", "NetworkID", "AE", "1" }, { Tag(0x0008, 0x1010), @@ -608,6 +632,12 @@ ElementsDictionary create_public_dictionary() "Patient's Size", "PatientSize", "DS", "1" }, { Tag(0x0010, 0x1021), "Patient's Size Code Sequence", "PatientSizeCodeSequence", "SQ", "1" }, + { Tag(0x0010, 0x1022), + "Patient's Body Mass Index", "PatientBodyMassIndex", "DS", "1" }, + { Tag(0x0010, 0x1023), + "Measured AP Dimension", "MeasuredAPDimension", "DS", "1" }, + { Tag(0x0010, 0x1024), + "Measured Lateral Dimension", "MeasuredLateralDimension", "DS", "1" }, { Tag(0x0010, 0x1030), "Patient's Weight", "PatientWeight", "DS", "1" }, { Tag(0x0010, 0x1040), @@ -718,6 +748,10 @@ ElementsDictionary create_public_dictionary() "Distribution Type", "DistributionType", "CS", "1" }, { Tag(0x0012, 0x0085), "Consent for Distribution Flag", "ConsentForDistributionFlag", "CS", "1" }, + { Tag(0x0012, 0x0086), + "Ethics Committee Approval Effectiveness Start Date", "EthicsCommitteeApprovalEffectivenessStartDate", "DA", "1" }, + { Tag(0x0012, 0x0087), + "Ethics Committee Approval Effectiveness End Date", "EthicsCommitteeApprovalEffectivenessEndDate", "DA", "1" }, { Tag(0x0014, 0x0023), "CAD File Format", "CADFileFormat", "ST", "1" }, { Tag(0x0014, 0x0024), @@ -1222,6 +1256,10 @@ ElementsDictionary create_public_dictionary() "Cassette ID", "CassetteID", "LO", "1" }, { Tag(0x0018, 0x1008), "Gantry ID", "GantryID", "LO", "1" }, + { Tag(0x0018, 0x1009), + "Unique Device Identifier", "UniqueDeviceIdentifier", "UT", "1" }, + { Tag(0x0018, 0x100a), + "UDI Sequence", "UDISequence", "SQ", "1" }, { Tag(0x0018, 0x1010), "Secondary Capture Device ID", "SecondaryCaptureDeviceID", "LO", "1" }, { Tag(0x0018, 0x1011), @@ -2209,7 +2247,7 @@ ElementsDictionary create_public_dictionary() { Tag(0x0018, 0x9322), "Reconstruction Pixel Spacing", "ReconstructionPixelSpacing", "FD", "2" }, { Tag(0x0018, 0x9323), - "Exposure Modulation Type", "ExposureModulationType", "CS", "1" }, + "Exposure Modulation Type", "ExposureModulationType", "CS", "1-n" }, { Tag(0x0018, 0x9324), "Estimated Dose Saving", "EstimatedDoseSaving", "FD", "1" }, { Tag(0x0018, 0x9325), @@ -2580,6 +2618,124 @@ ElementsDictionary create_public_dictionary() "Transducer Application Code Sequence", "TransducerApplicationCodeSequence", "SQ", "1" }, { Tag(0x0018, 0x9810), "Zero Velocity Pixel Value", "ZeroVelocityPixelValue", "US or SS", "1" }, + { Tag(0x0018, 0x9900), + "Reference Location Label", "ReferenceLocationLabel", "LO", "1" }, + { Tag(0x0018, 0x9901), + "Reference Location Description", "ReferenceLocationDescription", "UT", "1" }, + { Tag(0x0018, 0x9902), + "Reference Basis Code Sequence", "ReferenceBasisCodeSequence", "SQ", "1" }, + { Tag(0x0018, 0x9903), + "Reference Geometry Code Sequence", "ReferenceGeometryCodeSequence", "SQ", "1" }, + { Tag(0x0018, 0x9904), + "Offset Distance", "OffsetDistance", "DS", "1" }, + { Tag(0x0018, 0x9905), + "Offset Direction", "OffsetDirection", "CS", "1" }, + { Tag(0x0018, 0x9906), + "Potential Scheduled Protocol Code Sequence", "PotentialScheduledProtocolCodeSequence", "SQ", "1" }, + { Tag(0x0018, 0x9907), + "Potential Requested Procedure Code Sequence", "PotentialRequestedProcedureCodeSequence", "SQ", "1" }, + { Tag(0x0018, 0x9908), + "Potential Reasons for Procedure", "PotentialReasonsForProcedure", "UC", "1-n" }, + { Tag(0x0018, 0x9909), + "Potential Reasons for Procedure Code Sequence", "PotentialReasonsForProcedureCodeSequence", "SQ", "1" }, + { Tag(0x0018, 0x990a), + "Potential Diagnostic Tasks", "PotentialDiagnosticTasks", "UC", "1-n" }, + { Tag(0x0018, 0x990b), + "Contraindications Code Sequence", "ContraindicationsCodeSequence", "SQ", "1" }, + { Tag(0x0018, 0x990c), + "Referenced Defined Protocol Sequence", "ReferencedDefinedProtocolSequence", "SQ", "1" }, + { Tag(0x0018, 0x990d), + "Referenced Performed Protocol Sequence", "ReferencedPerformedProtocolSequence", "SQ", "1" }, + { Tag(0x0018, 0x990e), + "Predecessor Protocol Sequence", "PredecessorProtocolSequence", "SQ", "1" }, + { Tag(0x0018, 0x990f), + "Protocol Planning Information", "ProtocolPlanningInformation", "UT", "1" }, + { Tag(0x0018, 0x9910), + "Protocol Design Rationale", "ProtocolDesignRationale", "UT", "1" }, + { Tag(0x0018, 0x9911), + "Patient Specification Sequence", "PatientSpecificationSequence", "SQ", "1" }, + { Tag(0x0018, 0x9912), + "Model Specification Sequence", "ModelSpecificationSequence", "SQ", "1" }, + { Tag(0x0018, 0x9913), + "Parameters Specification Sequence", "ParametersSpecificationSequence", "SQ", "1" }, + { Tag(0x0018, 0x9914), + "Instruction Sequence", "InstructionSequence", "SQ", "1" }, + { Tag(0x0018, 0x9915), + "Instruction Index", "InstructionIndex", "US", "1" }, + { Tag(0x0018, 0x9916), + "Instruction Text", "InstructionText", "LO", "1" }, + { Tag(0x0018, 0x9917), + "Instruction Description", "InstructionDescription", "UT", "1" }, + { Tag(0x0018, 0x9918), + "Instruction Performed Flag", "InstructionPerformedFlag", "CS", "1" }, + { Tag(0x0018, 0x9919), + "Instruction Performed DateTime", "InstructionPerformedDateTime", "DT", "1" }, + { Tag(0x0018, 0x991a), + "Instruction Performance Comment", "InstructionPerformanceComment", "UT", "1" }, + { Tag(0x0018, 0x991b), + "Patient Positioning Instruction Sequence", "PatientPositioningInstructionSequence", "SQ", "1" }, + { Tag(0x0018, 0x991c), + "Positioning Method Code Sequence", "PositioningMethodCodeSequence", "SQ", "1" }, + { Tag(0x0018, 0x991d), + "Positioning Landmark Sequence", "PositioningLandmarkSequence", "SQ", "1" }, + { Tag(0x0018, 0x991e), + "Target Frame of Reference UID", "TargetFrameOfReferenceUID", "UI", "1" }, + { Tag(0x0018, 0x991f), + "Acquisition Protocol Element Specification Sequence", "AcquisitionProtocolElementSpecificationSequence", "SQ", "1" }, + { Tag(0x0018, 0x9920), + "Acquisition Protocol Element Sequence", "AcquisitionProtocolElementSequence", "SQ", "1" }, + { Tag(0x0018, 0x9921), + "Protocol Element Number", "ProtocolElementNumber", "US", "1" }, + { Tag(0x0018, 0x9922), + "Protocol Element Name", "ProtocolElementName", "LO", "1" }, + { Tag(0x0018, 0x9923), + "Protocol Element Characteristics Summary", "ProtocolElementCharacteristicsSummary", "UT", "1" }, + { Tag(0x0018, 0x9924), + "Protocol Element Purpose", "ProtocolElementPurpose", "UT", "1" }, + { Tag(0x0018, 0x9930), + "Acquisition Motion", "AcquisitionMotion", "CS", "1" }, + { Tag(0x0018, 0x9931), + "Acquisition Start Location Sequence", "AcquisitionStartLocationSequence", "SQ", "1" }, + { Tag(0x0018, 0x9932), + "Acquisition End Location Sequence", "AcquisitionEndLocationSequence", "SQ", "1" }, + { Tag(0x0018, 0x9933), + "Reconstruction Protocol Element Specification Sequence", "ReconstructionProtocolElementSpecificationSequence", "SQ", "1" }, + { Tag(0x0018, 0x9934), + "Reconstruction Protocol Element Sequence", "ReconstructionProtocolElementSequence", "SQ", "1" }, + { Tag(0x0018, 0x9935), + "Storage Protocol Element Specification Sequence", "StorageProtocolElementSpecificationSequence", "SQ", "1" }, + { Tag(0x0018, 0x9936), + "Storage Protocol Element Sequence", "StorageProtocolElementSequence", "SQ", "1" }, + { Tag(0x0018, 0x9937), + "Requested Series Description", "RequestedSeriesDescription", "LO", "1" }, + { Tag(0x0018, 0x9938), + "Source Acquisition Protocol Element Number", "SourceAcquisitionProtocolElementNumber", "US", "1-n" }, + { Tag(0x0018, 0x9939), + "Source Acquisition Beam Number", "SourceAcquisitionBeamNumber", "US", "1-n" }, + { Tag(0x0018, 0x993a), + "Source Reconstruction Protocol Element Number", "SourceReconstructionProtocolElementNumber", "US", "1-n" }, + { Tag(0x0018, 0x993b), + "Reconstruction Start Location Sequence", "ReconstructionStartLocationSequence", "SQ", "1" }, + { Tag(0x0018, 0x993c), + "Reconstruction End Location Sequence", "ReconstructionEndLocationSequence", "SQ", "1" }, + { Tag(0x0018, 0x993d), + "Reconstruction Algorithm Sequence", "ReconstructionAlgorithmSequence", "SQ", "1" }, + { Tag(0x0018, 0x993e), + "Reconstruction Target Center Location Sequence", "ReconstructionTargetCenterLocationSequence", "SQ", "1" }, + { Tag(0x0018, 0x9941), + "Image Filter Description", "ImageFilterDescription", "UT", "1" }, + { Tag(0x0018, 0x9942), + "CTDIvol Notification Trigger", "CTDIvolNotificationTrigger", "FD", "1" }, + { Tag(0x0018, 0x9943), + "DLP Notification Trigger", "DLPNotificationTrigger", "FD", "1" }, + { Tag(0x0018, 0x9944), + "Auto KVP Selection Type", "AutoKVPSelectionType", "CS", "1" }, + { Tag(0x0018, 0x9945), + "Auto KVP Upper Bound", "AutoKVPUpperBound", "FD", "1" }, + { Tag(0x0018, 0x9946), + "Auto KVP Lower Bound", "AutoKVPLowerBound", "FD", "1" }, + { Tag(0x0018, 0x9947), + "Protocol Defined Patient Position", "ProtocolDefinedPatientPosition", "CS", "1" }, { Tag(0x0018, 0xa001), "Contributing Equipment Sequence", "ContributingEquipmentSequence", "SQ", "1" }, { Tag(0x0018, 0xa002), @@ -2664,6 +2820,8 @@ ElementsDictionary create_public_dictionary() "Images in Study", "ImagesInStudy", "IS", "1" }, { Tag(0x0020, 0x1020), "Reference", "Reference", "LO", "1-n" }, + { Tag(0x0020, 0x103f), + "Target Position Reference Indicator", "TargetPositionReferenceIndicator", "LO", "1" }, { Tag(0x0020, 0x1040), "Position Reference Indicator", "PositionReferenceIndicator", "LO", "1" }, { Tag(0x0020, 0x1041), @@ -5686,6 +5844,8 @@ ElementsDictionary create_public_dictionary() "Fiducial Set Sequence", "FiducialSetSequence", "SQ", "1" }, { Tag(0x0070, 0x031e), "Fiducial Sequence", "FiducialSequence", "SQ", "1" }, + { Tag(0x0070, 0x031f), + "Fiducials Property Category Code Sequence", "FiducialsPropertyCategoryCodeSequence", "SQ", "1" }, { Tag(0x0070, 0x0401), "Graphic Layer Recommended Display CIELab Value", "GraphicLayerRecommendedDisplayCIELabValue", "US", "3" }, { Tag(0x0070, 0x0402), @@ -6330,6 +6490,8 @@ ElementsDictionary create_public_dictionary() "Constraint Violation Significance", "ConstraintViolationSignificance", "CS", "1" }, { Tag(0x0082, 0x0037), "Constraint Violation Condition", "ConstraintViolationCondition", "UT", "1" }, + { Tag(0x0082, 0x0038), + "Modifiable Constraint Flag", "ModifiableConstraintFlag", "CS", "1" }, { Tag(0x0088, 0x0130), "Storage Media File-set ID", "StorageMediaFileSetID", "SH", "1" }, { Tag(0x0088, 0x0140), @@ -8550,7 +8712,10 @@ std::map<std::string, odil::Tag> create_public_tags() "Mapping Resource Name", "MappingResourceName", "LO", "1" }, { Tag(0x0008, 0x0123), "Context Group Identification Sequence", "ContextGroupIdentificationSequence", "SQ", "1" }, { Tag(0x0008, 0x0124), "Mapping Resource Identification Sequence", "MappingResourceIdentificationSequence", "SQ", "1" }, { Tag(0x0008, 0x0201), - "Timezone Offset From UTC", "TimezoneOffsetFromUTC", "SH", "1" }, { Tag(0x0008, 0x0300), + "Timezone Offset From UTC", "TimezoneOffsetFromUTC", "SH", "1" }, { Tag(0x0008, 0x0220), + "Responsible Group Code Sequence", "ResponsibleGroupCodeSequence", "SQ", "1" }, { Tag(0x0008, 0x0221), + "Equipment Modality", "EquipmentModality", "CS", "1" }, { Tag(0x0008, 0x0222), + "Manufacturer's Related Model Group", "ManufacturerRelatedModelGroup", "LO", "1" }, { Tag(0x0008, 0x0300), "Private Data Element Characteristics Sequence", "PrivateDataElementCharacteristicsSequence", "SQ", "1" }, { Tag(0x0008, 0x0301), "Private Group Reference", "PrivateGroupReference", "US", "1" }, { Tag(0x0008, 0x0302), "Private Creator Reference", "PrivateCreatorReference", "LO", "1" }, { Tag(0x0008, 0x0303), @@ -8558,7 +8723,16 @@ std::map<std::string, odil::Tag> create_public_tags() "Nonidentifying Private Elements", "NonidentifyingPrivateElements", "US", "1-n" }, { Tag(0x0008, 0x0306), "Identifying Private Elements", "IdentifyingPrivateElements", "US", "1-n" }, { Tag(0x0008, 0x0305), "Deidentification Action Sequence", "DeidentificationActionSequence", "SQ", "1" }, { Tag(0x0008, 0x0307), - "Deidentification Action", "DeidentificationAction", "CS", "1" }, { Tag(0x0008, 0x1000), + "Deidentification Action", "DeidentificationAction", "CS", "1" }, { Tag(0x0008, 0x0308), + "Private Data Element", "PrivateDataElement", "US", "1" }, { Tag(0x0008, 0x0309), + "Private Data Element Value Multiplicity", "PrivateDataElementValueMultiplicity", "UL", "1-3" }, { Tag(0x0008, 0x030a), + "Private Data Element Value Representation", "PrivateDataElementValueRepresentation", "CS", "1" }, { Tag(0x0008, 0x030b), + "Private Data Element Number of Items", "PrivateDataElementNumberOfItems", "UL", "1-2" }, { Tag(0x0008, 0x030c), + "Private Data Element Name", "PrivateDataElementName", "UC", "1" }, { Tag(0x0008, 0x030d), + "Private Data Element Keyword", "PrivateDataElementKeyword", "UC", "1" }, { Tag(0x0008, 0x030e), + "Private Data Element Description", "PrivateDataElementDescription", "UT", "1" }, { Tag(0x0008, 0x030f), + "Private Data Element Encoding", "PrivateDataElementEncoding", "UT", "1" }, { Tag(0x0008, 0x0310), + "Private Data Element Definition Sequence", "PrivateDataElementDefinitionSequence", "SQ", "1" }, { Tag(0x0008, 0x1000), "Network ID", "NetworkID", "AE", "1" }, { Tag(0x0008, 0x1010), "Station Name", "StationName", "SH", "1" }, { Tag(0x0008, 0x1030), "Study Description", "StudyDescription", "LO", "1" }, { Tag(0x0008, 0x1032), @@ -8702,7 +8876,10 @@ std::map<std::string, odil::Tag> create_public_tags() "Patient's Birth Name", "PatientBirthName", "PN", "1" }, { Tag(0x0010, 0x1010), "Patient's Age", "PatientAge", "AS", "1" }, { Tag(0x0010, 0x1020), "Patient's Size", "PatientSize", "DS", "1" }, { Tag(0x0010, 0x1021), - "Patient's Size Code Sequence", "PatientSizeCodeSequence", "SQ", "1" }, { Tag(0x0010, 0x1030), + "Patient's Size Code Sequence", "PatientSizeCodeSequence", "SQ", "1" }, { Tag(0x0010, 0x1022), + "Patient's Body Mass Index", "PatientBodyMassIndex", "DS", "1" }, { Tag(0x0010, 0x1023), + "Measured AP Dimension", "MeasuredAPDimension", "DS", "1" }, { Tag(0x0010, 0x1024), + "Measured Lateral Dimension", "MeasuredLateralDimension", "DS", "1" }, { Tag(0x0010, 0x1030), "Patient's Weight", "PatientWeight", "DS", "1" }, { Tag(0x0010, 0x1040), "Patient's Address", "PatientAddress", "LO", "1" }, { Tag(0x0010, 0x1050), "Insurance Plan Identification", "InsurancePlanIdentification", "LO", "1-n" }, { Tag(0x0010, 0x1060), @@ -8757,7 +8934,9 @@ std::map<std::string, odil::Tag> create_public_tags() "Clinical Trial Protocol Ethics Committee Approval Number", "ClinicalTrialProtocolEthicsCommitteeApprovalNumber", "LO", "1" }, { Tag(0x0012, 0x0083), "Consent for Clinical Trial Use Sequence", "ConsentForClinicalTrialUseSequence", "SQ", "1" }, { Tag(0x0012, 0x0084), "Distribution Type", "DistributionType", "CS", "1" }, { Tag(0x0012, 0x0085), - "Consent for Distribution Flag", "ConsentForDistributionFlag", "CS", "1" }, { Tag(0x0014, 0x0023), + "Consent for Distribution Flag", "ConsentForDistributionFlag", "CS", "1" }, { Tag(0x0012, 0x0086), + "Ethics Committee Approval Effectiveness Start Date", "EthicsCommitteeApprovalEffectivenessStartDate", "DA", "1" }, { Tag(0x0012, 0x0087), + "Ethics Committee Approval Effectiveness End Date", "EthicsCommitteeApprovalEffectivenessEndDate", "DA", "1" }, { Tag(0x0014, 0x0023), "CAD File Format", "CADFileFormat", "ST", "1" }, { Tag(0x0014, 0x0024), "Component Reference System", "ComponentReferenceSystem", "ST", "1" }, { Tag(0x0014, 0x0025), "Component Manufacturing Procedure", "ComponentManufacturingProcedure", "ST", "1" }, { Tag(0x0014, 0x0028), @@ -9009,7 +9188,9 @@ std::map<std::string, odil::Tag> create_public_tags() "Generator ID", "GeneratorID", "LO", "1" }, { Tag(0x0018, 0x1006), "Grid ID", "GridID", "LO", "1" }, { Tag(0x0018, 0x1007), "Cassette ID", "CassetteID", "LO", "1" }, { Tag(0x0018, 0x1008), - "Gantry ID", "GantryID", "LO", "1" }, { Tag(0x0018, 0x1010), + "Gantry ID", "GantryID", "LO", "1" }, { Tag(0x0018, 0x1009), + "Unique Device Identifier", "UniqueDeviceIdentifier", "UT", "1" }, { Tag(0x0018, 0x100a), + "UDI Sequence", "UDISequence", "SQ", "1" }, { Tag(0x0018, 0x1010), "Secondary Capture Device ID", "SecondaryCaptureDeviceID", "LO", "1" }, { Tag(0x0018, 0x1011), "Hardcopy Creation Device ID", "HardcopyCreationDeviceID", "LO", "1" }, { Tag(0x0018, 0x1012), "Date of Secondary Capture", "DateOfSecondaryCapture", "DA", "1" }, { Tag(0x0018, 0x1014), @@ -9503,7 +9684,7 @@ std::map<std::string, odil::Tag> create_public_tags() "Image Filter", "ImageFilter", "SH", "1" }, { Tag(0x0018, 0x9321), "CT Exposure Sequence", "CTExposureSequence", "SQ", "1" }, { Tag(0x0018, 0x9322), "Reconstruction Pixel Spacing", "ReconstructionPixelSpacing", "FD", "2" }, { Tag(0x0018, 0x9323), - "Exposure Modulation Type", "ExposureModulationType", "CS", "1" }, { Tag(0x0018, 0x9324), + "Exposure Modulation Type", "ExposureModulationType", "CS", "1-n" }, { Tag(0x0018, 0x9324), "Estimated Dose Saving", "EstimatedDoseSaving", "FD", "1" }, { Tag(0x0018, 0x9325), "CT X-Ray Details Sequence", "CTXRayDetailsSequence", "SQ", "1" }, { Tag(0x0018, 0x9326), "CT Position Sequence", "CTPositionSequence", "SQ", "1" }, { Tag(0x0018, 0x9327), @@ -9688,7 +9869,66 @@ std::map<std::string, odil::Tag> create_public_tags() "Transducer Geometry Code Sequence", "TransducerGeometryCodeSequence", "SQ", "1" }, { Tag(0x0018, 0x980e), "Transducer Beam Steering Code Sequence", "TransducerBeamSteeringCodeSequence", "SQ", "1" }, { Tag(0x0018, 0x980f), "Transducer Application Code Sequence", "TransducerApplicationCodeSequence", "SQ", "1" }, { Tag(0x0018, 0x9810), - "Zero Velocity Pixel Value", "ZeroVelocityPixelValue", "US or SS", "1" }, { Tag(0x0018, 0xa001), + "Zero Velocity Pixel Value", "ZeroVelocityPixelValue", "US or SS", "1" }, { Tag(0x0018, 0x9900), + "Reference Location Label", "ReferenceLocationLabel", "LO", "1" }, { Tag(0x0018, 0x9901), + "Reference Location Description", "ReferenceLocationDescription", "UT", "1" }, { Tag(0x0018, 0x9902), + "Reference Basis Code Sequence", "ReferenceBasisCodeSequence", "SQ", "1" }, { Tag(0x0018, 0x9903), + "Reference Geometry Code Sequence", "ReferenceGeometryCodeSequence", "SQ", "1" }, { Tag(0x0018, 0x9904), + "Offset Distance", "OffsetDistance", "DS", "1" }, { Tag(0x0018, 0x9905), + "Offset Direction", "OffsetDirection", "CS", "1" }, { Tag(0x0018, 0x9906), + "Potential Scheduled Protocol Code Sequence", "PotentialScheduledProtocolCodeSequence", "SQ", "1" }, { Tag(0x0018, 0x9907), + "Potential Requested Procedure Code Sequence", "PotentialRequestedProcedureCodeSequence", "SQ", "1" }, { Tag(0x0018, 0x9908), + "Potential Reasons for Procedure", "PotentialReasonsForProcedure", "UC", "1-n" }, { Tag(0x0018, 0x9909), + "Potential Reasons for Procedure Code Sequence", "PotentialReasonsForProcedureCodeSequence", "SQ", "1" }, { Tag(0x0018, 0x990a), + "Potential Diagnostic Tasks", "PotentialDiagnosticTasks", "UC", "1-n" }, { Tag(0x0018, 0x990b), + "Contraindications Code Sequence", "ContraindicationsCodeSequence", "SQ", "1" }, { Tag(0x0018, 0x990c), + "Referenced Defined Protocol Sequence", "ReferencedDefinedProtocolSequence", "SQ", "1" }, { Tag(0x0018, 0x990d), + "Referenced Performed Protocol Sequence", "ReferencedPerformedProtocolSequence", "SQ", "1" }, { Tag(0x0018, 0x990e), + "Predecessor Protocol Sequence", "PredecessorProtocolSequence", "SQ", "1" }, { Tag(0x0018, 0x990f), + "Protocol Planning Information", "ProtocolPlanningInformation", "UT", "1" }, { Tag(0x0018, 0x9910), + "Protocol Design Rationale", "ProtocolDesignRationale", "UT", "1" }, { Tag(0x0018, 0x9911), + "Patient Specification Sequence", "PatientSpecificationSequence", "SQ", "1" }, { Tag(0x0018, 0x9912), + "Model Specification Sequence", "ModelSpecificationSequence", "SQ", "1" }, { Tag(0x0018, 0x9913), + "Parameters Specification Sequence", "ParametersSpecificationSequence", "SQ", "1" }, { Tag(0x0018, 0x9914), + "Instruction Sequence", "InstructionSequence", "SQ", "1" }, { Tag(0x0018, 0x9915), + "Instruction Index", "InstructionIndex", "US", "1" }, { Tag(0x0018, 0x9916), + "Instruction Text", "InstructionText", "LO", "1" }, { Tag(0x0018, 0x9917), + "Instruction Description", "InstructionDescription", "UT", "1" }, { Tag(0x0018, 0x9918), + "Instruction Performed Flag", "InstructionPerformedFlag", "CS", "1" }, { Tag(0x0018, 0x9919), + "Instruction Performed DateTime", "InstructionPerformedDateTime", "DT", "1" }, { Tag(0x0018, 0x991a), + "Instruction Performance Comment", "InstructionPerformanceComment", "UT", "1" }, { Tag(0x0018, 0x991b), + "Patient Positioning Instruction Sequence", "PatientPositioningInstructionSequence", "SQ", "1" }, { Tag(0x0018, 0x991c), + "Positioning Method Code Sequence", "PositioningMethodCodeSequence", "SQ", "1" }, { Tag(0x0018, 0x991d), + "Positioning Landmark Sequence", "PositioningLandmarkSequence", "SQ", "1" }, { Tag(0x0018, 0x991e), + "Target Frame of Reference UID", "TargetFrameOfReferenceUID", "UI", "1" }, { Tag(0x0018, 0x991f), + "Acquisition Protocol Element Specification Sequence", "AcquisitionProtocolElementSpecificationSequence", "SQ", "1" }, { Tag(0x0018, 0x9920), + "Acquisition Protocol Element Sequence", "AcquisitionProtocolElementSequence", "SQ", "1" }, { Tag(0x0018, 0x9921), + "Protocol Element Number", "ProtocolElementNumber", "US", "1" }, { Tag(0x0018, 0x9922), + "Protocol Element Name", "ProtocolElementName", "LO", "1" }, { Tag(0x0018, 0x9923), + "Protocol Element Characteristics Summary", "ProtocolElementCharacteristicsSummary", "UT", "1" }, { Tag(0x0018, 0x9924), + "Protocol Element Purpose", "ProtocolElementPurpose", "UT", "1" }, { Tag(0x0018, 0x9930), + "Acquisition Motion", "AcquisitionMotion", "CS", "1" }, { Tag(0x0018, 0x9931), + "Acquisition Start Location Sequence", "AcquisitionStartLocationSequence", "SQ", "1" }, { Tag(0x0018, 0x9932), + "Acquisition End Location Sequence", "AcquisitionEndLocationSequence", "SQ", "1" }, { Tag(0x0018, 0x9933), + "Reconstruction Protocol Element Specification Sequence", "ReconstructionProtocolElementSpecificationSequence", "SQ", "1" }, { Tag(0x0018, 0x9934), + "Reconstruction Protocol Element Sequence", "ReconstructionProtocolElementSequence", "SQ", "1" }, { Tag(0x0018, 0x9935), + "Storage Protocol Element Specification Sequence", "StorageProtocolElementSpecificationSequence", "SQ", "1" }, { Tag(0x0018, 0x9936), + "Storage Protocol Element Sequence", "StorageProtocolElementSequence", "SQ", "1" }, { Tag(0x0018, 0x9937), + "Requested Series Description", "RequestedSeriesDescription", "LO", "1" }, { Tag(0x0018, 0x9938), + "Source Acquisition Protocol Element Number", "SourceAcquisitionProtocolElementNumber", "US", "1-n" }, { Tag(0x0018, 0x9939), + "Source Acquisition Beam Number", "SourceAcquisitionBeamNumber", "US", "1-n" }, { Tag(0x0018, 0x993a), + "Source Reconstruction Protocol Element Number", "SourceReconstructionProtocolElementNumber", "US", "1-n" }, { Tag(0x0018, 0x993b), + "Reconstruction Start Location Sequence", "ReconstructionStartLocationSequence", "SQ", "1" }, { Tag(0x0018, 0x993c), + "Reconstruction End Location Sequence", "ReconstructionEndLocationSequence", "SQ", "1" }, { Tag(0x0018, 0x993d), + "Reconstruction Algorithm Sequence", "ReconstructionAlgorithmSequence", "SQ", "1" }, { Tag(0x0018, 0x993e), + "Reconstruction Target Center Location Sequence", "ReconstructionTargetCenterLocationSequence", "SQ", "1" }, { Tag(0x0018, 0x9941), + "Image Filter Description", "ImageFilterDescription", "UT", "1" }, { Tag(0x0018, 0x9942), + "CTDIvol Notification Trigger", "CTDIvolNotificationTrigger", "FD", "1" }, { Tag(0x0018, 0x9943), + "DLP Notification Trigger", "DLPNotificationTrigger", "FD", "1" }, { Tag(0x0018, 0x9944), + "Auto KVP Selection Type", "AutoKVPSelectionType", "CS", "1" }, { Tag(0x0018, 0x9945), + "Auto KVP Upper Bound", "AutoKVPUpperBound", "FD", "1" }, { Tag(0x0018, 0x9946), + "Auto KVP Lower Bound", "AutoKVPLowerBound", "FD", "1" }, { Tag(0x0018, 0x9947), + "Protocol Defined Patient Position", "ProtocolDefinedPatientPosition", "CS", "1" }, { Tag(0x0018, 0xa001), "Contributing Equipment Sequence", "ContributingEquipmentSequence", "SQ", "1" }, { Tag(0x0018, 0xa002), "Contribution DateTime", "ContributionDateTime", "DT", "1" }, { Tag(0x0018, 0xa003), "Contribution Description", "ContributionDescription", "ST", "1" }, { Tag(0x0020, 0x000d), @@ -9730,7 +9970,8 @@ std::map<std::string, odil::Tag> create_public_tags() "Images in Series", "ImagesInSeries", "IS", "1" }, { Tag(0x0020, 0x1004), "Acquisitions in Study", "AcquisitionsInStudy", "IS", "1" }, { Tag(0x0020, 0x1005), "Images in Study", "ImagesInStudy", "IS", "1" }, { Tag(0x0020, 0x1020), - "Reference", "Reference", "LO", "1-n" }, { Tag(0x0020, 0x1040), + "Reference", "Reference", "LO", "1-n" }, { Tag(0x0020, 0x103f), + "Target Position Reference Indicator", "TargetPositionReferenceIndicator", "LO", "1" }, { Tag(0x0020, 0x1040), "Position Reference Indicator", "PositionReferenceIndicator", "LO", "1" }, { Tag(0x0020, 0x1041), "Slice Location", "SliceLocation", "DS", "1" }, { Tag(0x0020, 0x1070), "Other Study Numbers", "OtherStudyNumbers", "IS", "1-n" }, { Tag(0x0020, 0x1200), @@ -11226,7 +11467,8 @@ std::map<std::string, odil::Tag> create_public_tags() "Graphic Coordinates Data Sequence", "GraphicCoordinatesDataSequence", "SQ", "1" }, { Tag(0x0070, 0x031a), "Fiducial UID", "FiducialUID", "UI", "1" }, { Tag(0x0070, 0x031c), "Fiducial Set Sequence", "FiducialSetSequence", "SQ", "1" }, { Tag(0x0070, 0x031e), - "Fiducial Sequence", "FiducialSequence", "SQ", "1" }, { Tag(0x0070, 0x0401), + "Fiducial Sequence", "FiducialSequence", "SQ", "1" }, { Tag(0x0070, 0x031f), + "Fiducials Property Category Code Sequence", "FiducialsPropertyCategoryCodeSequence", "SQ", "1" }, { Tag(0x0070, 0x0401), "Graphic Layer Recommended Display CIELab Value", "GraphicLayerRecommendedDisplayCIELabValue", "US", "3" }, { Tag(0x0070, 0x0402), "Blending Sequence", "BlendingSequence", "SQ", "1" }, { Tag(0x0070, 0x0403), "Relative Opacity", "RelativeOpacity", "FL", "1" }, { Tag(0x0070, 0x0404), @@ -11548,7 +11790,8 @@ std::map<std::string, odil::Tag> create_public_tags() "Constraint Value Sequence", "ConstraintValueSequence", "SQ", "1" }, { Tag(0x0082, 0x0035), "Recommended Default Value Sequence", "RecommendedDefaultValueSequence", "SQ", "1" }, { Tag(0x0082, 0x0036), "Constraint Violation Significance", "ConstraintViolationSignificance", "CS", "1" }, { Tag(0x0082, 0x0037), - "Constraint Violation Condition", "ConstraintViolationCondition", "UT", "1" }, { Tag(0x0088, 0x0130), + "Constraint Violation Condition", "ConstraintViolationCondition", "UT", "1" }, { Tag(0x0082, 0x0038), + "Modifiable Constraint Flag", "ModifiableConstraintFlag", "CS", "1" }, { Tag(0x0088, 0x0130), "Storage Media File-set ID", "StorageMediaFileSetID", "SH", "1" }, { Tag(0x0088, 0x0140), "Storage Media File-set UID", "StorageMediaFileSetUID", "UI", "1" }, { Tag(0x0088, 0x0200), "Icon Image Sequence", "IconImageSequence", "SQ", "1" }, { Tag(0x0088, 0x0904), @@ -12740,6 +12983,8 @@ UIDsDictionary create_uids_dictionary() { "1.2.840.10008.5.1.4.1.1.129", "Standalone PET Curve Storage (Retired)", "StandalonePETCurveStorage_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.130", "Enhanced PET Image Storage", "EnhancedPETImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.131", "Basic Structured Display Storage", "BasicStructuredDisplayStorage", "SOP Class" }, + { "1.2.840.10008.5.1.4.1.1.200.1", "CT Defined Procedure Protocol Storage", "CTDefinedProcedureProtocolStorage", "SOP Class" }, + { "1.2.840.10008.5.1.4.1.1.200.2", "CT Performed Procedure Protocol Storage", "CTPerformedProcedureProtocolStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.481.1", "RT Image Storage", "RTImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.481.2", "RT Dose Storage", "RTDoseStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.481.3", "RT Structure Set Storage", "RTStructureSetStorage", "SOP Class" }, @@ -12770,6 +13015,9 @@ UIDsDictionary create_uids_dictionary() { "1.2.840.10008.5.1.4.1.2.4.2", "Composite Instance Root Retrieve - MOVE", "CompositeInstanceRootRetrieveMOVE", "SOP Class" }, { "1.2.840.10008.5.1.4.1.2.4.3", "Composite Instance Root Retrieve - GET", "CompositeInstanceRootRetrieveGET", "SOP Class" }, { "1.2.840.10008.5.1.4.1.2.5.3", "Composite Instance Retrieve Without Bulk Data - GET", "CompositeInstanceRetrieveWithoutBulkDataGET", "SOP Class" }, + { "1.2.840.10008.5.1.4.20.1", "Defined Procedure Protocol Information Model - FIND", "DefinedProcedureProtocolInformationModelFIND", "SOP Class" }, + { "1.2.840.10008.5.1.4.20.2", "Defined Procedure Protocol Information Model - MOVE", "DefinedProcedureProtocolInformationModelMOVE", "SOP Class" }, + { "1.2.840.10008.5.1.4.20.3", "Defined Procedure Protocol Information Model - GET", "DefinedProcedureProtocolInformationModelGET", "SOP Class" }, { "1.2.840.10008.5.1.4.31", "Modality Worklist Information Model - FIND", "ModalityWorklistInformationModelFIND", "SOP Class" }, { "1.2.840.10008.5.1.4.32", "General Purpose Worklist Management Meta SOP Class (Retired)", "GeneralPurposeWorklistManagementMetaSOPClass_Retired", "Meta SOP Class" }, { "1.2.840.10008.5.1.4.32.1", "General Purpose Worklist Information Model - FIND (Retired)", "GeneralPurposeWorklistInformationModelFIND_Retired", "SOP Class" }, @@ -12803,9 +13051,9 @@ UIDsDictionary create_uids_dictionary() { "1.2.840.10008.5.1.4.38.3", "Hanging Protocol Information Model - MOVE", "HangingProtocolInformationModelMOVE", "SOP Class" }, { "1.2.840.10008.5.1.4.38.4", "Hanging Protocol Information Model - GET", "HangingProtocolInformationModelGET", "SOP Class" }, { "1.2.840.10008.5.1.4.39.1", "Color Palette Storage", "ColorPaletteStorage", "Transfer" }, - { "1.2.840.10008.5.1.4.39.2", "Color Palette Information Model - FIND", "ColorPaletteInformationModelFIND", "Query/Retrieve" }, - { "1.2.840.10008.5.1.4.39.3", "Color Palette Information Model - MOVE", "ColorPaletteInformationModelMOVE", "Query/Retrieve" }, - { "1.2.840.10008.5.1.4.39.4", "Color Palette Information Model - GET", "ColorPaletteInformationModelGET", "Query/Retrieve" }, + { "1.2.840.10008.5.1.4.39.2", "Color Palette Query/Retrieve Information Model - FIND", "ColorPaletteQueryRetrieveInformationModelFIND", "SOP Class" }, + { "1.2.840.10008.5.1.4.39.3", "Color Palette Query/Retrieve Information Model - MOVE", "ColorPaletteQueryRetrieveInformationModelMOVE", "SOP Class" }, + { "1.2.840.10008.5.1.4.39.4", "Color Palette Query/Retrieve Information Model - GET", "ColorPaletteQueryRetrieveInformationModelGET", "SOP Class" }, { "1.2.840.10008.5.1.4.41", "Product Characteristics Query SOP Class", "ProductCharacteristicsQuerySOPClass", "SOP Class" }, { "1.2.840.10008.5.1.4.42", "Substance Approval Query SOP Class", "SubstanceApprovalQuerySOPClass", "SOP Class" }, { "1.2.840.10008.5.1.4.43.1", "Generic Implant Template Storage", "GenericImplantTemplateStorage", "SOP Class" }, diff --git a/src/odil/registry.h b/src/odil/registry.h index f19064a..ff10bf3 100644 --- a/src/odil/registry.h +++ b/src/odil/registry.h @@ -156,6 +156,9 @@ Tag const MappingResourceName(0x0008, 0x0122); Tag const ContextGroupIdentificationSequence(0x0008, 0x0123); Tag const MappingResourceIdentificationSequence(0x0008, 0x0124); Tag const TimezoneOffsetFromUTC(0x0008, 0x0201); +Tag const ResponsibleGroupCodeSequence(0x0008, 0x0220); +Tag const EquipmentModality(0x0008, 0x0221); +Tag const ManufacturerRelatedModelGroup(0x0008, 0x0222); Tag const PrivateDataElementCharacteristicsSequence(0x0008, 0x0300); Tag const PrivateGroupReference(0x0008, 0x0301); Tag const PrivateCreatorReference(0x0008, 0x0302); @@ -164,6 +167,15 @@ Tag const NonidentifyingPrivateElements(0x0008, 0x0304); Tag const IdentifyingPrivateElements(0x0008, 0x0306); Tag const DeidentificationActionSequence(0x0008, 0x0305); Tag const DeidentificationAction(0x0008, 0x0307); +Tag const PrivateDataElement(0x0008, 0x0308); +Tag const PrivateDataElementValueMultiplicity(0x0008, 0x0309); +Tag const PrivateDataElementValueRepresentation(0x0008, 0x030a); +Tag const PrivateDataElementNumberOfItems(0x0008, 0x030b); +Tag const PrivateDataElementName(0x0008, 0x030c); +Tag const PrivateDataElementKeyword(0x0008, 0x030d); +Tag const PrivateDataElementDescription(0x0008, 0x030e); +Tag const PrivateDataElementEncoding(0x0008, 0x030f); +Tag const PrivateDataElementDefinitionSequence(0x0008, 0x0310); Tag const NetworkID(0x0008, 0x1000); Tag const StationName(0x0008, 0x1010); Tag const StudyDescription(0x0008, 0x1030); @@ -308,6 +320,9 @@ Tag const PatientBirthName(0x0010, 0x1005); Tag const PatientAge(0x0010, 0x1010); Tag const PatientSize(0x0010, 0x1020); Tag const PatientSizeCodeSequence(0x0010, 0x1021); +Tag const PatientBodyMassIndex(0x0010, 0x1022); +Tag const MeasuredAPDimension(0x0010, 0x1023); +Tag const MeasuredLateralDimension(0x0010, 0x1024); Tag const PatientWeight(0x0010, 0x1030); Tag const PatientAddress(0x0010, 0x1040); Tag const InsurancePlanIdentification(0x0010, 0x1050); @@ -363,6 +378,8 @@ Tag const ClinicalTrialProtocolEthicsCommitteeApprovalNumber(0x0012, 0x0082); Tag const ConsentForClinicalTrialUseSequence(0x0012, 0x0083); Tag const DistributionType(0x0012, 0x0084); Tag const ConsentForDistributionFlag(0x0012, 0x0085); +Tag const EthicsCommitteeApprovalEffectivenessStartDate(0x0012, 0x0086); +Tag const EthicsCommitteeApprovalEffectivenessEndDate(0x0012, 0x0087); Tag const CADFileFormat(0x0014, 0x0023); Tag const ComponentReferenceSystem(0x0014, 0x0024); Tag const ComponentManufacturingProcedure(0x0014, 0x0025); @@ -615,6 +632,8 @@ Tag const GeneratorID(0x0018, 0x1005); Tag const GridID(0x0018, 0x1006); Tag const CassetteID(0x0018, 0x1007); Tag const GantryID(0x0018, 0x1008); +Tag const UniqueDeviceIdentifier(0x0018, 0x1009); +Tag const UDISequence(0x0018, 0x100a); Tag const SecondaryCaptureDeviceID(0x0018, 0x1010); Tag const HardcopyCreationDeviceID(0x0018, 0x1011); Tag const DateOfSecondaryCapture(0x0018, 0x1012); @@ -1294,6 +1313,65 @@ Tag const TransducerGeometryCodeSequence(0x0018, 0x980d); Tag const TransducerBeamSteeringCodeSequence(0x0018, 0x980e); Tag const TransducerApplicationCodeSequence(0x0018, 0x980f); Tag const ZeroVelocityPixelValue(0x0018, 0x9810); +Tag const ReferenceLocationLabel(0x0018, 0x9900); +Tag const ReferenceLocationDescription(0x0018, 0x9901); +Tag const ReferenceBasisCodeSequence(0x0018, 0x9902); +Tag const ReferenceGeometryCodeSequence(0x0018, 0x9903); +Tag const OffsetDistance(0x0018, 0x9904); +Tag const OffsetDirection(0x0018, 0x9905); +Tag const PotentialScheduledProtocolCodeSequence(0x0018, 0x9906); +Tag const PotentialRequestedProcedureCodeSequence(0x0018, 0x9907); +Tag const PotentialReasonsForProcedure(0x0018, 0x9908); +Tag const PotentialReasonsForProcedureCodeSequence(0x0018, 0x9909); +Tag const PotentialDiagnosticTasks(0x0018, 0x990a); +Tag const ContraindicationsCodeSequence(0x0018, 0x990b); +Tag const ReferencedDefinedProtocolSequence(0x0018, 0x990c); +Tag const ReferencedPerformedProtocolSequence(0x0018, 0x990d); +Tag const PredecessorProtocolSequence(0x0018, 0x990e); +Tag const ProtocolPlanningInformation(0x0018, 0x990f); +Tag const ProtocolDesignRationale(0x0018, 0x9910); +Tag const PatientSpecificationSequence(0x0018, 0x9911); +Tag const ModelSpecificationSequence(0x0018, 0x9912); +Tag const ParametersSpecificationSequence(0x0018, 0x9913); +Tag const InstructionSequence(0x0018, 0x9914); +Tag const InstructionIndex(0x0018, 0x9915); +Tag const InstructionText(0x0018, 0x9916); +Tag const InstructionDescription(0x0018, 0x9917); +Tag const InstructionPerformedFlag(0x0018, 0x9918); +Tag const InstructionPerformedDateTime(0x0018, 0x9919); +Tag const InstructionPerformanceComment(0x0018, 0x991a); +Tag const PatientPositioningInstructionSequence(0x0018, 0x991b); +Tag const PositioningMethodCodeSequence(0x0018, 0x991c); +Tag const PositioningLandmarkSequence(0x0018, 0x991d); +Tag const TargetFrameOfReferenceUID(0x0018, 0x991e); +Tag const AcquisitionProtocolElementSpecificationSequence(0x0018, 0x991f); +Tag const AcquisitionProtocolElementSequence(0x0018, 0x9920); +Tag const ProtocolElementNumber(0x0018, 0x9921); +Tag const ProtocolElementName(0x0018, 0x9922); +Tag const ProtocolElementCharacteristicsSummary(0x0018, 0x9923); +Tag const ProtocolElementPurpose(0x0018, 0x9924); +Tag const AcquisitionMotion(0x0018, 0x9930); +Tag const AcquisitionStartLocationSequence(0x0018, 0x9931); +Tag const AcquisitionEndLocationSequence(0x0018, 0x9932); +Tag const ReconstructionProtocolElementSpecificationSequence(0x0018, 0x9933); +Tag const ReconstructionProtocolElementSequence(0x0018, 0x9934); +Tag const StorageProtocolElementSpecificationSequence(0x0018, 0x9935); +Tag const StorageProtocolElementSequence(0x0018, 0x9936); +Tag const RequestedSeriesDescription(0x0018, 0x9937); +Tag const SourceAcquisitionProtocolElementNumber(0x0018, 0x9938); +Tag const SourceAcquisitionBeamNumber(0x0018, 0x9939); +Tag const SourceReconstructionProtocolElementNumber(0x0018, 0x993a); +Tag const ReconstructionStartLocationSequence(0x0018, 0x993b); +Tag const ReconstructionEndLocationSequence(0x0018, 0x993c); +Tag const ReconstructionAlgorithmSequence(0x0018, 0x993d); +Tag const ReconstructionTargetCenterLocationSequence(0x0018, 0x993e); +Tag const ImageFilterDescription(0x0018, 0x9941); +Tag const CTDIvolNotificationTrigger(0x0018, 0x9942); +Tag const DLPNotificationTrigger(0x0018, 0x9943); +Tag const AutoKVPSelectionType(0x0018, 0x9944); +Tag const AutoKVPUpperBound(0x0018, 0x9945); +Tag const AutoKVPLowerBound(0x0018, 0x9946); +Tag const ProtocolDefinedPatientPosition(0x0018, 0x9947); Tag const ContributingEquipmentSequence(0x0018, 0xa001); Tag const ContributionDateTime(0x0018, 0xa002); Tag const ContributionDescription(0x0018, 0xa003); @@ -1336,6 +1414,7 @@ Tag const ImagesInSeries(0x0020, 0x1003); Tag const AcquisitionsInStudy(0x0020, 0x1004); Tag const ImagesInStudy(0x0020, 0x1005); Tag const Reference(0x0020, 0x1020); +Tag const TargetPositionReferenceIndicator(0x0020, 0x103f); Tag const PositionReferenceIndicator(0x0020, 0x1040); Tag const SliceLocation(0x0020, 0x1041); Tag const OtherStudyNumbers(0x0020, 0x1070); @@ -2842,6 +2921,7 @@ Tag const GraphicCoordinatesDataSequence(0x0070, 0x0318); Tag const FiducialUID(0x0070, 0x031a); Tag const FiducialSetSequence(0x0070, 0x031c); Tag const FiducialSequence(0x0070, 0x031e); +Tag const FiducialsPropertyCategoryCodeSequence(0x0070, 0x031f); Tag const GraphicLayerRecommendedDisplayCIELabValue(0x0070, 0x0401); Tag const BlendingSequence(0x0070, 0x0402); Tag const RelativeOpacity(0x0070, 0x0403); @@ -3164,6 +3244,7 @@ Tag const ConstraintValueSequence(0x0082, 0x0034); Tag const RecommendedDefaultValueSequence(0x0082, 0x0035); Tag const ConstraintViolationSignificance(0x0082, 0x0036); Tag const ConstraintViolationCondition(0x0082, 0x0037); +Tag const ModifiableConstraintFlag(0x0082, 0x0038); Tag const StorageMediaFileSetID(0x0088, 0x0130); Tag const StorageMediaFileSetUID(0x0088, 0x0140); Tag const IconImageSequence(0x0088, 0x0200); @@ -4409,6 +4490,8 @@ std::string const LegacyConvertedEnhancedPETImageStorage("1.2.840.10008.5.1.4.1. std::string const StandalonePETCurveStorage_Retired("1.2.840.10008.5.1.4.1.1.129"); std::string const EnhancedPETImageStorage("1.2.840.10008.5.1.4.1.1.130"); std::string const BasicStructuredDisplayStorage("1.2.840.10008.5.1.4.1.1.131"); +std::string const CTDefinedProcedureProtocolStorage("1.2.840.10008.5.1.4.1.1.200.1"); +std::string const CTPerformedProcedureProtocolStorage("1.2.840.10008.5.1.4.1.1.200.2"); std::string const RTImageStorage("1.2.840.10008.5.1.4.1.1.481.1"); std::string const RTDoseStorage("1.2.840.10008.5.1.4.1.1.481.2"); std::string const RTStructureSetStorage("1.2.840.10008.5.1.4.1.1.481.3"); @@ -4439,6 +4522,9 @@ std::string const PatientStudyOnlyQueryRetrieveInformationModelGET_Retired("1.2. std::string const CompositeInstanceRootRetrieveMOVE("1.2.840.10008.5.1.4.1.2.4.2"); std::string const CompositeInstanceRootRetrieveGET("1.2.840.10008.5.1.4.1.2.4.3"); std::string const CompositeInstanceRetrieveWithoutBulkDataGET("1.2.840.10008.5.1.4.1.2.5.3"); +std::string const DefinedProcedureProtocolInformationModelFIND("1.2.840.10008.5.1.4.20.1"); +std::string const DefinedProcedureProtocolInformationModelMOVE("1.2.840.10008.5.1.4.20.2"); +std::string const DefinedProcedureProtocolInformationModelGET("1.2.840.10008.5.1.4.20.3"); std::string const ModalityWorklistInformationModelFIND("1.2.840.10008.5.1.4.31"); std::string const GeneralPurposeWorklistManagementMetaSOPClass_Retired("1.2.840.10008.5.1.4.32"); std::string const GeneralPurposeWorklistInformationModelFIND_Retired("1.2.840.10008.5.1.4.32.1"); @@ -4472,9 +4558,9 @@ std::string const HangingProtocolInformationModelFIND("1.2.840.10008.5.1.4.38.2" std::string const HangingProtocolInformationModelMOVE("1.2.840.10008.5.1.4.38.3"); std::string const HangingProtocolInformationModelGET("1.2.840.10008.5.1.4.38.4"); std::string const ColorPaletteStorage("1.2.840.10008.5.1.4.39.1"); -std::string const ColorPaletteInformationModelFIND("1.2.840.10008.5.1.4.39.2"); -std::string const ColorPaletteInformationModelMOVE("1.2.840.10008.5.1.4.39.3"); -std::string const ColorPaletteInformationModelGET("1.2.840.10008.5.1.4.39.4"); +std::string const ColorPaletteQueryRetrieveInformationModelFIND("1.2.840.10008.5.1.4.39.2"); +std::string const ColorPaletteQueryRetrieveInformationModelMOVE("1.2.840.10008.5.1.4.39.3"); +std::string const ColorPaletteQueryRetrieveInformationModelGET("1.2.840.10008.5.1.4.39.4"); std::string const ProductCharacteristicsQuerySOPClass("1.2.840.10008.5.1.4.41"); std::string const SubstanceApprovalQuerySOPClass("1.2.840.10008.5.1.4.42"); std::string const GenericImplantTemplateStorage("1.2.840.10008.5.1.4.43.1"); diff --git a/tests/code/AssociationParameters.cpp b/tests/code/AssociationParameters.cpp index d2ffd2b..73f11d0 100644 --- a/tests/code/AssociationParameters.cpp +++ b/tests/code/AssociationParameters.cpp @@ -18,6 +18,9 @@ BOOST_AUTO_TEST_CASE(Constructor) BOOST_REQUIRE(parameters.get_user_identity().secondary_field.empty()); BOOST_REQUIRE_EQUAL(parameters.get_maximum_length(), 16384); + + BOOST_REQUIRE_EQUAL(parameters.get_maximum_number_operations_invoked(), 1); + BOOST_REQUIRE_EQUAL(parameters.get_maximum_number_operations_performed(), 1); } BOOST_AUTO_TEST_CASE(CalledAETITLE) @@ -164,6 +167,20 @@ BOOST_AUTO_TEST_CASE(MaximumLength) BOOST_REQUIRE_EQUAL(parameters.get_maximum_length(), 0x12345678); } +BOOST_AUTO_TEST_CASE(MaximumNumberOperationsInvoked) +{ + odil::AssociationParameters parameters; + parameters.set_maximum_number_operations_invoked(12); + BOOST_REQUIRE_EQUAL(parameters.get_maximum_number_operations_invoked(), 12); +} + +BOOST_AUTO_TEST_CASE(MaximumNumberOperationsPerformed) +{ + odil::AssociationParameters parameters; + parameters.set_maximum_number_operations_performed(12); + BOOST_REQUIRE_EQUAL(parameters.get_maximum_number_operations_performed(), 12); +} + BOOST_AUTO_TEST_CASE(ChainedSetters) { odil::AssociationParameters parameters; @@ -172,7 +189,9 @@ BOOST_AUTO_TEST_CASE(ChainedSetters) .set_calling_ae_title("calling") .set_presentation_contexts({ { 1, "abstract", { "transfer" }, true, true } }) .set_user_identity_to_username_and_password("foo", "bar") - .set_maximum_length(0x12345678); + .set_maximum_length(0x12345678) + .set_maximum_number_operations_invoked(12) + .set_maximum_number_operations_performed(34); BOOST_REQUIRE_EQUAL(parameters.get_called_ae_title(), "called"); BOOST_REQUIRE_EQUAL(parameters.get_calling_ae_title(), "calling"); @@ -185,4 +204,7 @@ BOOST_AUTO_TEST_CASE(ChainedSetters) BOOST_REQUIRE_EQUAL(parameters.get_user_identity().secondary_field, "bar"); BOOST_REQUIRE_EQUAL(parameters.get_maximum_length(), 0x12345678); + + BOOST_REQUIRE_EQUAL(parameters.get_maximum_number_operations_invoked(), 12); + BOOST_REQUIRE_EQUAL(parameters.get_maximum_number_operations_performed(), 34); } diff --git a/tests/code/dul/Transport.cpp b/tests/code/dul/Transport.cpp index fd50fea..338be12 100644 --- a/tests/code/dul/Transport.cpp +++ b/tests/code/dul/Transport.cpp @@ -41,5 +41,4 @@ BOOST_AUTO_TEST_CASE(NotConnected) BOOST_REQUIRE_THROW(transport.write("..."), odil::Exception); BOOST_REQUIRE_THROW(transport.read(1), odil::Exception); - BOOST_REQUIRE_THROW(transport.close(), odil::Exception); } diff --git a/tests/code/pdu/AsynchronousOperationsWindow.cpp b/tests/code/pdu/AsynchronousOperationsWindow.cpp new file mode 100644 index 0000000..2160969 --- /dev/null +++ b/tests/code/pdu/AsynchronousOperationsWindow.cpp @@ -0,0 +1,59 @@ +#define BOOST_TEST_MODULE AsynchronousOperationsWindow +#include <boost/test/unit_test.hpp> + +#include <sstream> +#include <string> + +#include "odil/Exception.h" +#include "odil/pdu/AsynchronousOperationsWindow.h" + +BOOST_AUTO_TEST_CASE(Constructor) +{ + odil::pdu::AsynchronousOperationsWindow const window(123, 456); + BOOST_REQUIRE_EQUAL(window.get_maximum_number_operations_invoked(), 123); + BOOST_REQUIRE_EQUAL(window.get_maximum_number_operations_performed(), 456); +} + +BOOST_AUTO_TEST_CASE(FromStream) +{ + std::string const data( + "\x53\x00\x00\x04" + "\x12\x34\x56\x78", + 8 + ); + std::istringstream stream(data); + + odil::pdu::AsynchronousOperationsWindow const window(stream); + + BOOST_REQUIRE_EQUAL(window.get_maximum_number_operations_invoked(), 0x1234); + BOOST_REQUIRE_EQUAL(window.get_maximum_number_operations_performed(), 0x5678); +} + +BOOST_AUTO_TEST_CASE(MaximumNumberOperationsInvoked) +{ + odil::pdu::AsynchronousOperationsWindow window(0, 0); + window.set_maximum_number_operations_invoked(123); + BOOST_REQUIRE_EQUAL(window.get_maximum_number_operations_invoked(), 123); +} + +BOOST_AUTO_TEST_CASE(MaximumNumberOperationsPerformed) +{ + odil::pdu::AsynchronousOperationsWindow window(0, 0); + window.set_maximum_number_operations_performed(123); + BOOST_REQUIRE_EQUAL(window.get_maximum_number_operations_performed(), 123); +} + +BOOST_AUTO_TEST_CASE(Write) +{ + odil::pdu::AsynchronousOperationsWindow const window(0x1234, 0x5678); + std::ostringstream data; + data << window; + + std::string const expected( + "\x53\x00\x00\x04" + "\x12\x34\x56\x78", + 8 + ); + + BOOST_REQUIRE_EQUAL(data.str(), expected); +} diff --git a/tests/code/pdu/SOPClassCommonExtendedNegotiation.cpp b/tests/code/pdu/SOPClassCommonExtendedNegotiation.cpp new file mode 100644 index 0000000..b92395e --- /dev/null +++ b/tests/code/pdu/SOPClassCommonExtendedNegotiation.cpp @@ -0,0 +1,87 @@ +#define BOOST_TEST_MODULE SOPClassCommonExtendedNegotiation +#include <boost/test/unit_test.hpp> + +#include <sstream> +#include <string> + +#include "odil/Exception.h" +#include "odil/pdu/SOPClassCommonExtendedNegotiation.h" + +BOOST_AUTO_TEST_CASE(Constructor) +{ + odil::pdu::SOPClassCommonExtendedNegotiation const item( + "sop_class", "service_class", {"foo", "bar"}); + BOOST_REQUIRE_EQUAL(item.get_sop_class_uid(), "sop_class"); + BOOST_REQUIRE_EQUAL(item.get_service_class_uid(), "service_class"); + BOOST_REQUIRE( + item.get_related_general_sop_class_uids() == + std::vector<std::string>({"foo", "bar"})); +} + +BOOST_AUTO_TEST_CASE(FromStream) +{ + std::string const data( + "\x57\x00\x00\x26" + "\x00\x09" "sop_class" + "\x00\x0d" "service_class" + "\x00\x0a" + "\x00\x03" "foo" + "\x00\x03" "bar", + 42 + ); + std::istringstream stream(data); + + odil::pdu::SOPClassCommonExtendedNegotiation const item(stream); + + BOOST_REQUIRE_EQUAL(item.get_sop_class_uid(), "sop_class"); + BOOST_REQUIRE_EQUAL(item.get_service_class_uid(), "service_class"); + BOOST_REQUIRE( + item.get_related_general_sop_class_uids() == + std::vector<std::string>({"foo", "bar"})); +} + +BOOST_AUTO_TEST_CASE(SOPClassUID) +{ + odil::pdu::SOPClassCommonExtendedNegotiation item( + "sop_class", "service_class", {"foo", "bar"}); + item.set_sop_class_uid("bar"); + BOOST_REQUIRE_EQUAL(item.get_sop_class_uid(), "bar"); +} + +BOOST_AUTO_TEST_CASE(ServiceClassUID) +{ + odil::pdu::SOPClassCommonExtendedNegotiation item( + "sop_class", "service_class", {"foo", "bar"}); + item.set_service_class_uid("bar"); + BOOST_REQUIRE_EQUAL(item.get_service_class_uid(), "bar"); +} + +BOOST_AUTO_TEST_CASE(RelatedClasses) +{ + odil::pdu::SOPClassCommonExtendedNegotiation item( + "sop_class", "service_class", {"foo", "bar"}); + item.set_related_general_sop_class_uids({"plip", "plop", "plup"}); + BOOST_REQUIRE( + item.get_related_general_sop_class_uids() == + std::vector<std::string>({"plip", "plop", "plup"})); +} + +BOOST_AUTO_TEST_CASE(Write) +{ + odil::pdu::SOPClassCommonExtendedNegotiation const item( + "sop_class", "service_class", {"foo", "bar"}); + std::ostringstream data; + data << item; + + std::string const expected( + "\x57\x00\x00\x26" + "\x00\x09" "sop_class" + "\x00\x0d" "service_class" + "\x00\x0a" + "\x00\x03" "foo" + "\x00\x03" "bar", + 42 + ); + + BOOST_REQUIRE_EQUAL(data.str(), expected); +} diff --git a/tests/code/pdu/SOPClassExtendedNegotiation.cpp b/tests/code/pdu/SOPClassExtendedNegotiation.cpp new file mode 100644 index 0000000..aaf61a5 --- /dev/null +++ b/tests/code/pdu/SOPClassExtendedNegotiation.cpp @@ -0,0 +1,71 @@ +#define BOOST_TEST_MODULE SOPClassExtendedNegotiation +#include <boost/test/unit_test.hpp> + +#include <sstream> +#include <string> + +#include "odil/Exception.h" +#include "odil/pdu/SOPClassExtendedNegotiation.h" + +BOOST_AUTO_TEST_CASE(Constructor) +{ + odil::pdu::SOPClassExtendedNegotiation const item( + "sop_class", {'\x01', '\x02', '\x03', '\x04'}); + BOOST_REQUIRE_EQUAL(item.get_sop_class_uid(), "sop_class"); + BOOST_REQUIRE( + item.get_service_class_application_information() == + std::vector<uint8_t>({'\x01', '\x02', '\x03', '\x04'})); +} + +BOOST_AUTO_TEST_CASE(FromStream) +{ + std::string const data( + "\x56\x00\x00\x0f" + "\x00\x09" "sop_class" + "\x01\x02\x03\x04", + 19 + ); + std::istringstream stream(data); + + odil::pdu::SOPClassExtendedNegotiation const item(stream); + + BOOST_REQUIRE_EQUAL(item.get_sop_class_uid(), "sop_class"); + BOOST_REQUIRE( + item.get_service_class_application_information() == + std::vector<uint8_t>({'\x01', '\x02', '\x03', '\x04'})); +} + +BOOST_AUTO_TEST_CASE(SOPClassUID) +{ + odil::pdu::SOPClassExtendedNegotiation item( + "sop_class", {'\x01', '\x02', '\x03', '\x04'}); + item.set_sop_class_uid("bar"); + BOOST_REQUIRE_EQUAL(item.get_sop_class_uid(), "bar"); +} + +BOOST_AUTO_TEST_CASE(ServiceClassApplicationInformation) +{ + odil::pdu::SOPClassExtendedNegotiation item( + "sop_class", {'\x01', '\x02', '\x03', '\x04'}); + item.set_service_class_application_information({'\x05', '\x06'}); + BOOST_REQUIRE( + item.get_service_class_application_information() == + std::vector<uint8_t>({'\x05', '\x06'})); +} + +BOOST_AUTO_TEST_CASE(Write) +{ + odil::pdu::SOPClassExtendedNegotiation const item( + "sop_class", {'\x01', '\x02', '\x03', '\x04'}); + std::ostringstream data; + data << item; + + std::string const expected( + "\x56\x00\x00\x0f" + "\x00\x09" "sop_class" + "\x01\x02\x03\x04", + 19 + ); + + BOOST_REQUIRE_EQUAL(data.str(), expected); +} diff --git a/wrappers/json_converter.cpp b/wrappers/json_converter.cpp index 8503719..6908da1 100644 --- a/wrappers/json_converter.cpp +++ b/wrappers/json_converter.cpp @@ -6,6 +6,8 @@ * for details. ************************************************************************/ +#include <memory> + #include <boost/python.hpp> #include <json/json.h> @@ -20,14 +22,14 @@ std::string as_json(odil::DataSet const & data_set, bool pretty_print) { auto const json = odil::as_json(data_set); - Json::Writer * writer = NULL; + std::shared_ptr<Json::Writer> writer; if(pretty_print) { - writer = new Json::StyledWriter(); + writer = std::make_shared<Json::StyledWriter>(); } else { - writer = new Json::FastWriter(); + writer = std::make_shared<Json::FastWriter>(); } auto const string = writer->write(json); -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/odil.git _______________________________________________ debian-med-commit mailing list debian-med-commit@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/debian-med-commit