PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
kcenon::pacs::core::dicom_element Class Reference

#include <dicom_element.h>

Collaboration diagram for kcenon::pacs::core::dicom_element:
Collaboration graph

Public Member Functions

 dicom_element (dicom_tag tag, encoding::vr_type vr) noexcept
 Construct an empty element with given tag and VR.
 
 dicom_element (dicom_tag tag, encoding::vr_type vr, std::span< const uint8_t > data)
 Construct an element with raw data.
 
 dicom_element (const dicom_element &)
 Copy constructor.
 
 dicom_element (dicom_element &&) noexcept
 Move constructor.
 
auto operator= (const dicom_element &) -> dicom_element &
 Copy assignment.
 
auto operator= (dicom_element &&) noexcept -> dicom_element &
 Move assignment.
 
 ~dicom_element ()
 Destructor.
 
constexpr auto tag () const noexcept -> dicom_tag
 Get the element's tag.
 
constexpr auto vr () const noexcept -> encoding::vr_type
 Get the element's VR.
 
auto length () const noexcept -> uint32_t
 Get the value length in bytes.
 
auto raw_data () const noexcept -> std::span< const uint8_t >
 Get the raw data bytes.
 
auto is_empty () const noexcept -> bool
 Check if the element has no value.
 
auto as_string () const -> kcenon::pacs::Result< std::string >
 Get the value as a string.
 
auto as_string_list () const -> kcenon::pacs::Result< std::vector< std::string > >
 Get multi-valued string as a list.
 
template<typename T >
requires std::is_arithmetic_v<T>
auto as_numeric () const -> kcenon::pacs::Result< T >
 Get the value as a numeric type.
 
template<typename T >
requires std::is_arithmetic_v<T>
auto as_numeric_list () const -> kcenon::pacs::Result< std::vector< T > >
 Get multi-valued numeric data as a list.
 
auto is_sequence () const noexcept -> bool
 Check if this element is a sequence.
 
auto sequence_item_count () const noexcept -> std::size_t
 Get the number of items in the sequence.
 
auto sequence_item (std::size_t index) const -> const dicom_dataset &
 Get a specific sequence item by index.
 
auto sequence_item (std::size_t index) -> dicom_dataset &
 Get a specific sequence item by index (mutable)
 
auto sequence_items () -> std::vector< dicom_dataset > &
 Get mutable access to sequence items.
 
auto sequence_items () const -> const std::vector< dicom_dataset > &
 Get read-only access to sequence items.
 
void add_sequence_item (dicom_dataset item)
 Add a new item to the sequence.
 
void set_value (std::span< const uint8_t > data)
 Set the raw value data.
 
void set_string (std::string_view value)
 Set the value from a string.
 
template<typename T >
requires std::is_arithmetic_v<T>
void set_numeric (T value)
 Set the value from a numeric value.
 

Static Public Member Functions

static auto from_string (dicom_tag tag, encoding::vr_type vr, std::string_view value) -> dicom_element
 Create an element from a string value.
 
template<typename T >
requires std::is_arithmetic_v<T>
static auto from_numeric (dicom_tag tag, encoding::vr_type vr, T value) -> dicom_element
 Create an element from a numeric value.
 
template<typename T >
requires std::is_arithmetic_v<T>
static auto from_numeric_list (dicom_tag tag, encoding::vr_type vr, std::span< const T > values) -> dicom_element
 Create an element from multiple numeric values.
 

Private Member Functions

auto apply_padding (std::string_view str) const -> std::string
 Apply DICOM padding to ensure even length.
 

Static Private Member Functions

static auto remove_padding (std::string_view str, encoding::vr_type vr) -> std::string
 Remove DICOM padding from a string value.
 

Private Attributes

dicom_tag tag_
 
encoding::vr_type vr_
 
std::vector< uint8_t > data_
 
std::vector< dicom_datasetsequence_items_
 

Detailed Description

Constructor & Destructor Documentation

◆ dicom_element() [1/4]

kcenon::pacs::core::dicom_element::dicom_element ( dicom_tag tag,
encoding::vr_type vr )
noexcept

Construct an empty element with given tag and VR.

Parameters
tagThe DICOM tag
vrThe value representation
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h.

Definition at line 24 of file dicom_element.cpp.

25 : tag_{tag}, vr_{vr}, data_{}, sequence_items_{} {}
constexpr auto tag() const noexcept -> dicom_tag
Get the element's tag.
std::vector< dicom_dataset > sequence_items_
constexpr auto vr() const noexcept -> encoding::vr_type
Get the element's VR.

◆ dicom_element() [2/4]

kcenon::pacs::core::dicom_element::dicom_element ( dicom_tag tag,
encoding::vr_type vr,
std::span< const uint8_t > data )

Construct an element with raw data.

Parameters
tagThe DICOM tag
vrThe value representation
dataThe raw byte data

Definition at line 27 of file dicom_element.cpp.

29 : tag_{tag}, vr_{vr}, data_(data.begin(), data.end()), sequence_items_{} {}

◆ dicom_element() [3/4]

kcenon::pacs::core::dicom_element::dicom_element ( const dicom_element & )
default

Copy constructor.

◆ dicom_element() [4/4]

kcenon::pacs::core::dicom_element::dicom_element ( dicom_element && )
defaultnoexcept

Move constructor.

◆ ~dicom_element()

kcenon::pacs::core::dicom_element::~dicom_element ( )
default

Member Function Documentation

◆ add_sequence_item()

void kcenon::pacs::core::dicom_element::add_sequence_item ( dicom_dataset item)

Add a new item to the sequence.

Parameters
itemThe dataset to add (will be moved)
Note
Only valid if is_sequence() returns true
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h.

Definition at line 179 of file dicom_element.cpp.

179 {
180 sequence_items_.push_back(std::move(item));
181}

References sequence_items_.

◆ apply_padding()

auto kcenon::pacs::core::dicom_element::apply_padding ( std::string_view str) const -> std::string
nodiscardprivate

Apply DICOM padding to ensure even length.

Parameters
strThe input string
Returns
Padded string with even length
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h.

Definition at line 201 of file dicom_element.cpp.

201 {
202 std::string result{str};
203
204 // DICOM requires even length for all values
205 if (result.length() % 2 != 0) {
206 result += encoding::padding_char(vr_);
207 }
208
209 return result;
210}
constexpr char padding_char(vr_type vr) noexcept
Gets the padding character for a VR.
Definition vr_type.h:292

References kcenon::pacs::encoding::padding_char().

Referenced by set_string().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ as_numeric()

template<typename T >
requires std::is_arithmetic_v<T>
auto kcenon::pacs::core::dicom_element::as_numeric ( ) const -> kcenon::pacs::Result<T>
nodiscard

Get the value as a numeric type.

Template Parameters
TThe target numeric type
Returns
Result containing the numeric value, or error if conversion fails
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h, and dcm_dump/main.cpp.

Definition at line 369 of file dicom_element.h.

369 {
370 if (data_.size() < sizeof(T)) {
373 "Insufficient data for numeric conversion: expected " +
374 std::to_string(sizeof(T)) + " bytes, got " +
375 std::to_string(data_.size()));
376 }
377
378 T result{};
379 std::memcpy(&result, data_.data(), sizeof(T));
380 return kcenon::pacs::ok(result);
381}
constexpr int data_size_mismatch
Definition result.h:73
Result< T > pacs_error(int code, const std::string &message, const std::string &details="")
Create a PACS error result with module context.
Definition result.h:234

References data_, kcenon::pacs::error_codes::data_size_mismatch, and kcenon::pacs::pacs_error().

Referenced by as_string().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ as_numeric_list()

template<typename T >
requires std::is_arithmetic_v<T>
auto kcenon::pacs::core::dicom_element::as_numeric_list ( ) const -> kcenon::pacs::Result<std::vector<T>>
nodiscard

Get multi-valued numeric data as a list.

Template Parameters
TThe target numeric type
Returns
Result containing vector of numeric values, or error if conversion fails
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h, dcm_to_json/main.cpp, and dcm_to_xml/main.cpp.

Definition at line 385 of file dicom_element.h.

385 {
386 if (data_.size() % sizeof(T) != 0) {
387 return kcenon::pacs::pacs_error<std::vector<T>>(
389 "Data size not aligned for numeric type: " +
390 std::to_string(data_.size()) + " bytes is not divisible by " +
391 std::to_string(sizeof(T)));
392 }
393
394 const size_t count = data_.size() / sizeof(T);
395 std::vector<T> result(count);
396
397 for (size_t i = 0; i < count; ++i) {
398 std::memcpy(&result[i], data_.data() + i * sizeof(T), sizeof(T));
399 }
400
401 return kcenon::pacs::ok(result);
402}

References data_, and kcenon::pacs::error_codes::data_size_mismatch.

◆ as_string()

auto kcenon::pacs::core::dicom_element::as_string ( ) const -> kcenon::pacs::Result<std::string>
nodiscard

Get the value as a string.

For string VRs, returns the value with trailing padding removed. For numeric VRs, converts the value to a string representation.

Returns
Result containing the string value, or error if conversion fails
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h, dcm_dump/main.cpp, dcm_to_json/main.cpp, and dcm_to_xml/main.cpp.

Definition at line 52 of file dicom_element.cpp.

52 {
53 if (data_.empty()) {
54 return kcenon::pacs::ok(std::string{});
55 }
56
57 // For string VRs, convert bytes to string and remove padding
59 std::string_view raw{reinterpret_cast<const char*>(data_.data()),
60 data_.size()};
61 return kcenon::pacs::ok(remove_padding(raw, vr_));
62 }
63
64 // For numeric VRs, convert to string representation
66 switch (vr_) {
68 if (data_.size() >= 2) {
69 if (auto val = as_numeric<uint16_t>(); val.is_ok())
70 return kcenon::pacs::ok(std::to_string(val.value()));
71 }
72 break;
74 if (data_.size() >= 2) {
75 if (auto val = as_numeric<int16_t>(); val.is_ok())
76 return kcenon::pacs::ok(std::to_string(val.value()));
77 }
78 break;
80 if (data_.size() >= 4) {
81 if (auto val = as_numeric<uint32_t>(); val.is_ok())
82 return kcenon::pacs::ok(std::to_string(val.value()));
83 }
84 break;
86 if (data_.size() >= 4) {
87 if (auto val = as_numeric<int32_t>(); val.is_ok())
88 return kcenon::pacs::ok(std::to_string(val.value()));
89 }
90 break;
92 if (data_.size() >= 8) {
93 if (auto val = as_numeric<uint64_t>(); val.is_ok())
94 return kcenon::pacs::ok(std::to_string(val.value()));
95 }
96 break;
98 if (data_.size() >= 8) {
99 if (auto val = as_numeric<int64_t>(); val.is_ok())
100 return kcenon::pacs::ok(std::to_string(val.value()));
101 }
102 break;
104 if (data_.size() >= 4) {
105 if (auto val = as_numeric<float>(); val.is_ok())
106 return kcenon::pacs::ok(std::to_string(val.value()));
107 }
108 break;
110 if (data_.size() >= 8) {
111 if (auto val = as_numeric<double>(); val.is_ok())
112 return kcenon::pacs::ok(std::to_string(val.value()));
113 }
114 break;
115 default:
116 break;
117 }
118 }
119
120 // For binary VRs or unknown, return raw bytes as string
121 return kcenon::pacs::ok(
122 std::string{reinterpret_cast<const char*>(data_.data()), data_.size()});
123}
auto as_numeric() const -> kcenon::pacs::Result< T >
Get the value as a numeric type.
static auto remove_padding(std::string_view str, encoding::vr_type vr) -> std::string
Remove DICOM padding from a string value.
constexpr bool is_numeric_vr(vr_type vr) noexcept
Checks if a VR is a numeric type.
Definition vr_type.h:214
@ UL
Unsigned Long (4 bytes)
@ SL
Signed Long (4 bytes)
@ US
Unsigned Short (2 bytes)
@ FD
Floating Point Double (8 bytes)
@ FL
Floating Point Single (4 bytes)
@ SV
Signed 64-bit Very Long (8 bytes)
@ SS
Signed Short (2 bytes)
@ UV
Unsigned 64-bit Very Long (8 bytes)
constexpr bool is_string_vr(vr_type vr) noexcept
Checks if a VR is a string type.
Definition vr_type.h:175

References as_numeric(), data_, kcenon::pacs::encoding::FD, kcenon::pacs::encoding::FL, kcenon::pacs::encoding::is_numeric_vr(), kcenon::pacs::encoding::is_string_vr(), remove_padding(), kcenon::pacs::encoding::SL, kcenon::pacs::encoding::SS, kcenon::pacs::encoding::SV, kcenon::pacs::encoding::UL, kcenon::pacs::encoding::US, kcenon::pacs::encoding::UV, and vr_.

Referenced by as_string_list().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ as_string_list()

auto kcenon::pacs::core::dicom_element::as_string_list ( ) const -> kcenon::pacs::Result<std::vector<std::string>>
nodiscard

Get multi-valued string as a list.

Splits the value by backslash delimiter (DICOM VM > 1).

Returns
Result containing vector of individual string values, or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h.

Definition at line 125 of file dicom_element.cpp.

126 {
127 auto str_result = as_string();
128 if (str_result.is_err()) {
129 return kcenon::pacs::pacs_error<std::vector<std::string>>(
130 str_result.error().code, str_result.error().message);
131 }
132 const std::string str = str_result.value();
133
134 std::vector<std::string> result;
135 if (str.empty()) {
136 return kcenon::pacs::ok(result);
137 }
138
139 // Split by backslash (DICOM VM delimiter)
140 std::string::size_type start = 0;
141 std::string::size_type pos = 0;
142
143 while ((pos = str.find('\\', start)) != std::string::npos) {
144 result.push_back(str.substr(start, pos - start));
145 start = pos + 1;
146 }
147
148 // Add the last segment
149 result.push_back(str.substr(start));
150
151 return kcenon::pacs::ok(result);
152}
auto as_string() const -> kcenon::pacs::Result< std::string >
Get the value as a string.
std::string_view code

References as_string(), and code.

Here is the call graph for this function:

◆ from_numeric()

template<typename T >
requires std::is_arithmetic_v<T>
auto kcenon::pacs::core::dicom_element::from_numeric ( dicom_tag tag,
encoding::vr_type vr,
T value ) -> dicom_element
staticnodiscard

Create an element from a numeric value.

Template Parameters
TThe numeric type (uint16_t, int32_t, float, double, etc.)
Parameters
tagThe DICOM tag
vrThe value representation (should be a numeric VR)
valueThe numeric value
Returns
A new dicom_element containing the value
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_dataset.h, and /home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h.

Definition at line 345 of file dicom_element.h.

346 {
347 dicom_element elem{tag, vr};
348 elem.set_numeric(value);
349 return elem;
350}

References set_numeric(), tag(), and vr().

Referenced by kcenon::pacs::integration::container_adapter::from_container_value(), and kcenon::pacs::core::dicom_dataset::set_numeric().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ from_numeric_list()

template<typename T >
requires std::is_arithmetic_v<T>
auto kcenon::pacs::core::dicom_element::from_numeric_list ( dicom_tag tag,
encoding::vr_type vr,
std::span< const T > values ) -> dicom_element
staticnodiscard

Create an element from multiple numeric values.

Template Parameters
TThe numeric type
Parameters
tagThe DICOM tag
vrThe value representation
valuesThe numeric values
Returns
A new dicom_element containing all values
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h.

Definition at line 354 of file dicom_element.h.

355 {
356 dicom_element elem{tag, vr};
357 std::vector<uint8_t> data(values.size() * sizeof(T));
358
359 for (size_t i = 0; i < values.size(); ++i) {
360 std::memcpy(data.data() + i * sizeof(T), &values[i], sizeof(T));
361 }
362
363 elem.set_value(data);
364 return elem;
365}

References tag(), and vr().

Here is the call graph for this function:

◆ from_string()

auto kcenon::pacs::core::dicom_element::from_string ( dicom_tag tag,
encoding::vr_type vr,
std::string_view value ) -> dicom_element
staticnodiscard

Create an element from a string value.

Parameters
tagThe DICOM tag
vrThe value representation (should be a string VR)
valueThe string value
Returns
A new dicom_element containing the string
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h.

Definition at line 41 of file dicom_element.cpp.

42 {
43 dicom_element elem{tag, vr};
44 elem.set_string(value);
45 return elem;
46}

References set_string(), and vr.

Referenced by kcenon::pacs::integration::container_adapter::from_container_value(), kcenon::pacs::encoding::set_encoded_string(), and kcenon::pacs::core::dicom_dataset::set_string().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_empty()

auto kcenon::pacs::core::dicom_element::is_empty ( ) const -> bool
inlinenodiscardnoexcept

Check if the element has no value.

Returns
true if the value is empty
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h, dcm_dump/main.cpp, dcm_to_json/main.cpp, and dcm_to_xml/main.cpp.

Definition at line 186 of file dicom_element.h.

186{ return data_.empty(); }

References data_.

◆ is_sequence()

auto kcenon::pacs::core::dicom_element::is_sequence ( ) const -> bool
inlinenodiscardnoexcept

◆ length()

auto kcenon::pacs::core::dicom_element::length ( ) const -> uint32_t
inlinenodiscardnoexcept

Get the value length in bytes.

Returns
The number of bytes in the value
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h.

Definition at line 170 of file dicom_element.h.

170 {
171 return static_cast<uint32_t>(data_.size());
172 }

References data_.

◆ operator=() [1/2]

auto kcenon::pacs::core::dicom_element::operator= ( const dicom_element & ) -> dicom_element &
default

◆ operator=() [2/2]

auto kcenon::pacs::core::dicom_element::operator= ( dicom_element && ) -> dicom_element &
defaultnoexcept

Move assignment.

◆ raw_data()

auto kcenon::pacs::core::dicom_element::raw_data ( ) const -> std::span<const uint8_t>
inlinenodiscardnoexcept

◆ remove_padding()

auto kcenon::pacs::core::dicom_element::remove_padding ( std::string_view str,
encoding::vr_type vr ) -> std::string
staticnodiscardprivate

Remove DICOM padding from a string value.

Parameters
strThe padded string
Returns
String with padding removed
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h.

Definition at line 212 of file dicom_element.cpp.

213 {
214 if (str.empty()) {
215 return {};
216 }
217
218 std::string result{str};
219
220 // Determine padding character based on VR
221 const char pad = encoding::padding_char(vr);
222
223 // Remove trailing padding characters
224 while (!result.empty() && result.back() == pad) {
225 result.pop_back();
226 }
227
228 // For string VRs (except UI), also trim trailing spaces
230 while (!result.empty() && result.back() == ' ') {
231 result.pop_back();
232 }
233 }
234
235 return result;
236}
@ UI
Unique Identifier (64 chars max)

References kcenon::pacs::encoding::is_string_vr(), kcenon::pacs::encoding::padding_char(), kcenon::pacs::encoding::UI, and vr.

Referenced by as_string().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sequence_item() [1/2]

auto kcenon::pacs::core::dicom_element::sequence_item ( std::size_t index) -> dicom_dataset&
nodiscard

Get a specific sequence item by index (mutable)

Parameters
indexThe zero-based index of the item
Returns
Reference to the dataset at the given index
Exceptions
std::out_of_rangeif index >= sequence_item_count()
Note
Only valid if is_sequence() returns true

Definition at line 167 of file dicom_element.cpp.

167 {
168 return sequence_items_.at(index);
169}

◆ sequence_item() [2/2]

auto kcenon::pacs::core::dicom_element::sequence_item ( std::size_t index) const -> const dicom_dataset&
nodiscard

Get a specific sequence item by index.

Parameters
indexThe zero-based index of the item
Returns
Const reference to the dataset at the given index
Exceptions
std::out_of_rangeif index >= sequence_item_count()
Note
Only valid if is_sequence() returns true
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h.

Definition at line 162 of file dicom_element.cpp.

163 {
164 return sequence_items_.at(index);
165}

◆ sequence_item_count()

auto kcenon::pacs::core::dicom_element::sequence_item_count ( ) const -> std::size_t
nodiscardnoexcept

Get the number of items in the sequence.

Returns
Number of sequence items, or 0 if not a sequence or empty
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h.

Definition at line 158 of file dicom_element.cpp.

158 {
159 return sequence_items_.size();
160}

References sequence_items_.

◆ sequence_items() [1/2]

◆ sequence_items() [2/2]

auto kcenon::pacs::core::dicom_element::sequence_items ( ) const -> const std::vector<dicom_dataset>&
nodiscard

Get read-only access to sequence items.

Returns
Const reference to the sequence items vector
Note
Only valid if is_sequence() returns true

Definition at line 175 of file dicom_element.cpp.

175 {
176 return sequence_items_;
177}

References sequence_items_.

◆ set_numeric()

template<typename T >
requires std::is_arithmetic_v<T>
void kcenon::pacs::core::dicom_element::set_numeric ( T value)

Set the value from a numeric value.

Template Parameters
TThe numeric type
Parameters
valueThe numeric value
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h.

Definition at line 406 of file dicom_element.h.

406 {
407 data_.resize(sizeof(T));
408 std::memcpy(data_.data(), &value, sizeof(T));
409}

References data_.

Referenced by from_numeric().

Here is the caller graph for this function:

◆ set_string()

void kcenon::pacs::core::dicom_element::set_string ( std::string_view value)

Set the value from a string.

Parameters
valueThe string value (will be padded if needed)
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h.

Definition at line 191 of file dicom_element.cpp.

191 {
192 // Apply padding for string VRs
193 std::string padded = apply_padding(value);
194 data_.assign(padded.begin(), padded.end());
195}
auto apply_padding(std::string_view str) const -> std::string
Apply DICOM padding to ensure even length.

References apply_padding(), and data_.

Referenced by from_string().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_value()

◆ tag()

auto kcenon::pacs::core::dicom_element::tag ( ) const -> dicom_tag
inlinenodiscardconstexprnoexcept

◆ vr()

auto kcenon::pacs::core::dicom_element::vr ( ) const -> encoding::vr_type
inlinenodiscardconstexprnoexcept

Member Data Documentation

◆ data_

std::vector<uint8_t> kcenon::pacs::core::dicom_element::data_
private

◆ sequence_items_

std::vector<dicom_dataset> kcenon::pacs::core::dicom_element::sequence_items_
private

◆ tag_

dicom_tag kcenon::pacs::core::dicom_element::tag_
private

◆ vr_

encoding::vr_type kcenon::pacs::core::dicom_element::vr_
private

The documentation for this class was generated from the following files: