19 return elements_.contains(tag);
23 auto it = elements_.find(tag);
24 if (it == elements_.end()) {
31 auto it = elements_.find(tag);
32 if (it == elements_.end()) {
43 std::string_view default_value)
const
45 const auto* elem = get(tag);
46 if (elem ==
nullptr) {
47 return std::string{default_value};
49 return elem->as_string().unwrap_or(std::string{default_value});
57 const auto* elem = get(tag);
58 return elem !=
nullptr && elem->is_sequence();
62 ->
const std::vector<dicom_dataset>* {
63 const auto* elem = get(tag);
64 if (elem ==
nullptr || !elem->is_sequence()) {
67 return &elem->sequence_items();
71 -> std::vector<dicom_dataset>* {
72 auto* elem = get(tag);
73 if (elem ==
nullptr || !elem->is_sequence()) {
76 return &elem->sequence_items();
80 -> std::vector<dicom_dataset>& {
81 auto* elem = get(tag);
82 if (elem !=
nullptr && elem->is_sequence()) {
83 return elem->sequence_items();
87 return get(tag)->sequence_items();
95 -> std::optional<std::string> {
96 const auto creator_tag = private_data_tag.private_creator_tag();
100 const auto* elem = get(*creator_tag);
101 if (elem ==
nullptr) {
104 auto result = elem->as_string();
105 if (result.is_ok()) {
106 return result.value();
112 uint16_t group)
const
113 -> std::vector<const dicom_element*> {
114 std::vector<const dicom_element*> result;
117 for (uint16_t slot = 0x0010; slot <= 0x00FF; ++slot) {
118 const dicom_tag creator_tag{group, slot};
119 const auto* creator_elem = get(creator_tag);
120 if (creator_elem ==
nullptr) {
123 auto str_result = creator_elem->as_string();
124 if (str_result.is_err() || str_result.value() != creator_id) {
129 const auto range = creator_tag.private_data_range();
133 const auto [first, last] = *range;
134 auto it = elements_.lower_bound(first);
135 while (it != elements_.end() && it->first <= last) {
136 result.push_back(&it->second);
147 uint8_t element_offset,
149 std::string_view value)
150 -> std::optional<dicom_tag> {
152 if ((group & 1) == 0 || group <= 0x0008) {
157 uint16_t block_number = 0;
160 for (uint16_t slot = 0x0010; slot <= 0x00FF; ++slot) {
161 const dicom_tag creator_tag{group, slot};
162 const auto* creator_elem = get(creator_tag);
163 if (creator_elem ==
nullptr) {
171 auto str_result = creator_elem->as_string();
172 if (str_result.is_ok() && str_result.value() == creator_id) {
185 const dicom_tag creator_tag{group, block_number};
186 if (get(creator_tag) ==
nullptr) {
191 const auto data_element_num =
static_cast<uint16_t
>(
192 (block_number << 8) | element_offset);
193 const dicom_tag data_tag{group, data_element_num};
194 set_string(data_tag,
vr, value);
200 uint16_t group) ->
size_t {
203 for (uint16_t slot = 0x0010; slot <= 0x00FF; ++slot) {
204 const dicom_tag creator_tag{group, slot};
205 const auto* creator_elem = get(creator_tag);
206 if (creator_elem ==
nullptr) {
209 auto str_result = creator_elem->as_string();
210 if (str_result.is_err() || str_result.value() != creator_id) {
215 const auto range = creator_tag.private_data_range();
217 const auto [first, last] = *range;
218 auto it = elements_.lower_bound(first);
219 while (it != elements_.end() && it->first <= last) {
220 it = elements_.erase(it);
226 elements_.erase(creator_tag);
236 std::vector<dicom_tag> orphans;
238 for (
const auto& [tag, elem] : elements_) {
239 if (!tag.is_private_creator()) {
243 const auto range = tag.private_data_range();
247 const auto [first, last] = *range;
248 auto it = elements_.lower_bound(first);
249 if (it == elements_.end() || it->first > last) {
250 orphans.push_back(tag);
254 for (
const auto& tag : orphans) {
255 elements_.erase(tag);
263 std::vector<dicom_tag> missing_creators;
265 for (
const auto& [tag, elem] :
elements_) {
266 if (!tag.is_private_data()) {
269 const auto creator_tag = tag.private_creator_tag();
270 if (!creator_tag || !
contains(*creator_tag)) {
271 missing_creators.push_back(tag);
275 return missing_creators;
283 elements_.insert_or_assign(element.
tag(), std::move(element));
287 std::string_view value) {
292 return elements_.erase(tag) > 0;
345 return copy_with_tags(std::span{tags.begin(), tags.size()});
352 for (
const auto& tag : tags) {
353 const auto* elem = get(tag);
354 if (elem !=
nullptr) {
363 for (
const auto& [tag, element] : other) {
369 for (
auto& [tag, element] : other.elements_) {
370 insert(std::move(element));
auto cleanup_orphaned_creators() -> size_t
Remove orphaned Private Creator elements that have no data elements.
auto has_sequence(dicom_tag tag) const noexcept -> bool
Check if the dataset contains a sequence element with the given tag.
auto get(dicom_tag tag) noexcept -> dicom_element *
Get a pointer to the element with the given tag.
auto remove(dicom_tag tag) -> bool
Remove an element from the dataset.
auto set_private_element(std::string_view creator_id, uint16_t group, uint8_t element_offset, encoding::vr_type vr, std::string_view value) -> std::optional< dicom_tag >
Insert a private data element with automatic creator management.
void insert(dicom_element element)
Insert or replace an element in the dataset.
auto empty() const noexcept -> bool
Check if the dataset is empty.
storage_type::iterator iterator
Iterator type.
auto size() const noexcept -> size_t
Get the number of elements in the dataset.
auto cend() const noexcept -> const_iterator
Get const iterator past the last element.
auto validate_private_tags() const -> std::vector< dicom_tag >
Validate private tag relationships in this dataset.
auto get_sequence(dicom_tag tag) const noexcept -> const std::vector< dicom_dataset > *
auto end() noexcept -> iterator
Get iterator past the last element.
auto cbegin() const noexcept -> const_iterator
Get const iterator to the first element.
void clear() noexcept
Remove all elements from the dataset.
auto begin() noexcept -> iterator
Get iterator to the first element.
void merge(const dicom_dataset &other)
Merge elements from another dataset.
auto copy_with_tags(std::initializer_list< dicom_tag > tags) const -> dicom_dataset
Create a copy containing only the specified tags.
void set_string(dicom_tag tag, encoding::vr_type vr, std::string_view value)
Set a string value for the given tag.
auto get_private_block(std::string_view creator_id, uint16_t group) const -> std::vector< const dicom_element * >
Get all private data elements belonging to a specific creator.
auto get_or_create_sequence(dicom_tag tag) -> std::vector< dicom_dataset > &
Insert or create a sequence element with the given tag.
auto contains(dicom_tag tag) const noexcept -> bool
Check if the dataset contains an element with the given tag.
storage_type::const_iterator const_iterator
Const iterator type.
auto remove_private_block(std::string_view creator_id, uint16_t group) -> size_t
Remove all private data elements and their creator for a given creator.
auto get_string(dicom_tag tag, std::string_view default_value="") const -> std::string
Get the string value of an element.
auto get_private_creator(dicom_tag private_data_tag) const -> std::optional< std::string >
Get the Private Creator identification string for a private data element.
static auto from_string(dicom_tag tag, encoding::vr_type vr, std::string_view value) -> dicom_element
Create an element from a string value.
constexpr auto tag() const noexcept -> dicom_tag
Get the element's tag.
DICOM Dataset - ordered collection of Data Elements.
vr_type
DICOM Value Representation (VR) types.
@ SQ
Sequence of Items (undefined length)
@ LO
Long String (64 chars max)