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

#include <uid_mapping.h>

Collaboration diagram for kcenon::pacs::security::uid_mapping:
Collaboration graph

Public Member Functions

 uid_mapping ()=default
 Default constructor - creates empty mapping.
 
 uid_mapping (std::string uid_root)
 Constructor with custom UID root.
 
 uid_mapping (const uid_mapping &other)
 Copy constructor (creates independent copy of mappings)
 
 uid_mapping (uid_mapping &&other) noexcept
 Move constructor.
 
auto operator= (const uid_mapping &other) -> uid_mapping &
 Copy assignment.
 
auto operator= (uid_mapping &&other) noexcept -> uid_mapping &
 Move assignment.
 
 ~uid_mapping ()=default
 Default destructor.
 
auto get_or_create (std::string_view original_uid) -> kcenon::common::Result< std::string >
 Get existing mapping or create new one.
 
auto get_anonymized (std::string_view original_uid) const -> std::optional< std::string >
 Get existing mapping without creating new one.
 
auto get_original (std::string_view anonymized_uid) const -> std::optional< std::string >
 Get original UID from anonymized UID (reverse lookup)
 
auto add_mapping (std::string_view original_uid, std::string_view anonymized_uid) -> kcenon::common::VoidResult
 Add a specific mapping.
 
auto has_mapping (std::string_view original_uid) const -> bool
 Check if an original UID has been mapped.
 
auto size () const -> std::size_t
 Get the number of mappings.
 
auto empty () const -> bool
 Check if the mapping is empty.
 
void clear ()
 Clear all mappings.
 
auto remove (std::string_view original_uid) -> bool
 Remove a specific mapping.
 
auto to_json () const -> std::string
 Export mappings to JSON format.
 
auto from_json (std::string_view json) -> kcenon::common::VoidResult
 Import mappings from JSON format.
 
auto merge (const uid_mapping &other) -> std::size_t
 Merge mappings from another uid_mapping.
 
void set_uid_root (std::string root)
 Set the UID root for generated UIDs.
 
auto get_uid_root () const -> std::string
 Get the current UID root.
 
auto generate_uid () const -> std::string
 Generate a new unique UID.
 

Private Attributes

std::string uid_root_ {"1.2.826.0.1.3680043.8.498.1"}
 UID root for generated UIDs (default: pacs_system root)
 
std::map< std::string, std::string, std::less<> > original_to_anon_
 Forward mapping: original -> anonymized.
 
std::map< std::string, std::string, std::less<> > anon_to_original_
 Reverse mapping: anonymized -> original.
 
std::atomic< std::uint64_t > uid_counter_ {0}
 Counter for UID generation.
 
std::shared_mutex mutex_
 Mutex for thread-safe access.
 

Detailed Description

Examples
dcm_anonymize/main.cpp.

Definition at line 59 of file uid_mapping.h.

Constructor & Destructor Documentation

◆ uid_mapping() [1/4]

kcenon::pacs::security::uid_mapping::uid_mapping ( )
default

Default constructor - creates empty mapping.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

◆ uid_mapping() [2/4]

kcenon::pacs::security::uid_mapping::uid_mapping ( std::string uid_root)
explicit

Constructor with custom UID root.

Parameters
uid_rootCustom root for generated UIDs (e.g., "1.2.3.4")

Definition at line 20 of file uid_mapping.cpp.

21 : uid_root_{std::move(uid_root)} {}
std::string uid_root_
UID root for generated UIDs (default: pacs_system root)

◆ uid_mapping() [3/4]

kcenon::pacs::security::uid_mapping::uid_mapping ( const uid_mapping & other)

Copy constructor (creates independent copy of mappings)

Definition at line 23 of file uid_mapping.cpp.

23 {
24 std::shared_lock lock(other.mutex_);
25 uid_root_ = other.uid_root_;
26 original_to_anon_ = other.original_to_anon_;
27 anon_to_original_ = other.anon_to_original_;
28 uid_counter_.store(other.uid_counter_.load());
29}
std::map< std::string, std::string, std::less<> > anon_to_original_
Reverse mapping: anonymized -> original.
std::map< std::string, std::string, std::less<> > original_to_anon_
Forward mapping: original -> anonymized.
std::atomic< std::uint64_t > uid_counter_
Counter for UID generation.

References anon_to_original_, original_to_anon_, kcenon::pacs::security::other, uid_counter_, and uid_root_.

◆ uid_mapping() [4/4]

kcenon::pacs::security::uid_mapping::uid_mapping ( uid_mapping && other)
noexcept

Move constructor.

Definition at line 31 of file uid_mapping.cpp.

31 {
32 std::unique_lock lock(other.mutex_);
33 uid_root_ = std::move(other.uid_root_);
34 original_to_anon_ = std::move(other.original_to_anon_);
35 anon_to_original_ = std::move(other.anon_to_original_);
36 uid_counter_.store(other.uid_counter_.load());
37}

References kcenon::pacs::security::other.

◆ ~uid_mapping()

kcenon::pacs::security::uid_mapping::~uid_mapping ( )
default

Member Function Documentation

◆ add_mapping()

auto kcenon::pacs::security::uid_mapping::add_mapping ( std::string_view original_uid,
std::string_view anonymized_uid ) -> kcenon::common::VoidResult
nodiscard

Add a specific mapping.

Adds a mapping between original and anonymized UIDs. Fails if the original UID is already mapped to a different value.

Parameters
original_uidThe original UID
anonymized_uidThe anonymized UID
Returns
Result indicating success or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

Definition at line 111 of file uid_mapping.cpp.

114 {
115 std::unique_lock lock(mutex_);
116
117 auto existing = original_to_anon_.find(original_uid);
118 if (existing != original_to_anon_.end()) {
119 if (existing->second != anonymized_uid) {
120 return kcenon::common::make_error<std::monostate>(
121 1,
122 "Original UID already mapped to different value",
123 "uid_mapping"
124 );
125 }
126 return kcenon::common::ok();
127 }
128
129 std::string original_str{original_uid};
130 std::string anon_str{anonymized_uid};
131
132 original_to_anon_[original_str] = anon_str;
133 anon_to_original_[anon_str] = original_str;
134
135 return kcenon::common::ok();
136}
std::shared_mutex mutex_
Mutex for thread-safe access.

◆ clear()

void kcenon::pacs::security::uid_mapping::clear ( )

Clear all mappings.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

Definition at line 153 of file uid_mapping.cpp.

153 {
154 std::unique_lock lock(mutex_);
155 original_to_anon_.clear();
156 anon_to_original_.clear();
157}

References anon_to_original_, mutex_, and original_to_anon_.

◆ empty()

auto kcenon::pacs::security::uid_mapping::empty ( ) const -> bool
nodiscard

Check if the mapping is empty.

Returns
true if no mappings exist
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h, and dcm_anonymize/main.cpp.

Definition at line 148 of file uid_mapping.cpp.

148 {
149 std::shared_lock lock(mutex_);
150 return original_to_anon_.empty();
151}

References mutex_, and original_to_anon_.

Referenced by main().

Here is the caller graph for this function:

◆ from_json()

auto kcenon::pacs::security::uid_mapping::from_json ( std::string_view json) -> kcenon::common::VoidResult
nodiscard

Import mappings from JSON format.

Parameters
jsonJSON string containing mappings
Returns
Result indicating success or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h, and dcm_anonymize/main.cpp.

Definition at line 198 of file uid_mapping.cpp.

199 {
200 // Simple JSON parsing - in production, use a proper JSON library
201 // This is a placeholder implementation
202 return kcenon::common::make_error<std::monostate>(
203 1, "JSON parsing not yet implemented", "uid_mapping"
204 );
205}

◆ generate_uid()

auto kcenon::pacs::security::uid_mapping::generate_uid ( ) const -> std::string
nodiscard

Generate a new unique UID.

Returns
A new UID string
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

Definition at line 233 of file uid_mapping.cpp.

233 {
234 // Generate UID based on timestamp and counter
235 auto now = std::chrono::system_clock::now();
236 auto timestamp = std::chrono::duration_cast<std::chrono::microseconds>(
237 now.time_since_epoch()
238 ).count();
239
240 auto counter = uid_counter_.fetch_add(1);
241
242 // Random component for additional uniqueness
243 std::random_device rd;
244 std::mt19937 gen(rd());
245 std::uniform_int_distribution<std::uint32_t> dist(0, 999999);
246 auto random_part = dist(gen);
247
248 std::ostringstream oss;
249 oss << uid_root_ << "." << timestamp << "." << counter << "." << random_part;
250
251 return oss.str();
252}
@ counter
Monotonic increasing value.

References uid_counter_, and uid_root_.

◆ get_anonymized()

auto kcenon::pacs::security::uid_mapping::get_anonymized ( std::string_view original_uid) const -> std::optional<std::string>
nodiscard

Get existing mapping without creating new one.

Parameters
original_uidThe original UID to look up
Returns
Optional containing the anonymized UID, or nullopt if not found
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

Definition at line 91 of file uid_mapping.cpp.

92 {
93 std::shared_lock lock(mutex_);
94 auto it = original_to_anon_.find(original_uid);
95 if (it != original_to_anon_.end()) {
96 return it->second;
97 }
98 return std::nullopt;
99}

◆ get_or_create()

auto kcenon::pacs::security::uid_mapping::get_or_create ( std::string_view original_uid) -> kcenon::common::Result<std::string>
nodiscard

Get existing mapping or create new one.

If the original UID has been mapped before, returns the existing anonymized UID. Otherwise, generates a new UID and stores the mapping.

Parameters
original_uidThe original UID to map
Returns
Result containing the anonymized UID
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

Definition at line 61 of file uid_mapping.cpp.

62 {
63 // First try read-only lookup
64 {
65 std::shared_lock lock(mutex_);
66 auto it = original_to_anon_.find(original_uid);
67 if (it != original_to_anon_.end()) {
68 return it->second;
69 }
70 }
71
72 // Need to create new mapping - upgrade to write lock
73 std::unique_lock lock(mutex_);
74
75 // Double-check after acquiring write lock
76 auto it = original_to_anon_.find(original_uid);
77 if (it != original_to_anon_.end()) {
78 return it->second;
79 }
80
81 // Generate new UID
82 auto new_uid = generate_uid();
83 std::string original_str{original_uid};
84
85 original_to_anon_[original_str] = new_uid;
86 anon_to_original_[new_uid] = original_str;
87
88 return new_uid;
89}
auto generate_uid() const -> std::string
Generate a new unique UID.

Referenced by kcenon::pacs::security::anonymizer::apply_action().

Here is the caller graph for this function:

◆ get_original()

auto kcenon::pacs::security::uid_mapping::get_original ( std::string_view anonymized_uid) const -> std::optional<std::string>
nodiscard

Get original UID from anonymized UID (reverse lookup)

Parameters
anonymized_uidThe anonymized UID to look up
Returns
Optional containing the original UID, or nullopt if not found
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

Definition at line 101 of file uid_mapping.cpp.

102 {
103 std::shared_lock lock(mutex_);
104 auto it = anon_to_original_.find(anonymized_uid);
105 if (it != anon_to_original_.end()) {
106 return it->second;
107 }
108 return std::nullopt;
109}

◆ get_uid_root()

auto kcenon::pacs::security::uid_mapping::get_uid_root ( ) const -> std::string
nodiscard

Get the current UID root.

Returns
The UID root string
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

Definition at line 228 of file uid_mapping.cpp.

228 {
229 std::shared_lock lock(mutex_);
230 return uid_root_;
231}

References mutex_, and uid_root_.

◆ has_mapping()

auto kcenon::pacs::security::uid_mapping::has_mapping ( std::string_view original_uid) const -> bool
nodiscard

Check if an original UID has been mapped.

Parameters
original_uidThe original UID to check
Returns
true if a mapping exists
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

Definition at line 138 of file uid_mapping.cpp.

138 {
139 std::shared_lock lock(mutex_);
140 return original_to_anon_.contains(original_uid);
141}

◆ merge()

auto kcenon::pacs::security::uid_mapping::merge ( const uid_mapping & other) -> std::size_t

Merge mappings from another uid_mapping.

Adds all mappings from 'other' that don't conflict with existing mappings.

Parameters
otherThe uid_mapping to merge from
Returns
Number of mappings added
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

Definition at line 207 of file uid_mapping.cpp.

207 {
208 std::shared_lock other_lock(other.mutex_);
209 std::unique_lock this_lock(mutex_);
210
211 std::size_t added = 0;
212 for (const auto& [original, anon] : other.original_to_anon_) {
213 if (!original_to_anon_.contains(original)) {
216 ++added;
217 }
218 }
219
220 return added;
221}

References kcenon::pacs::security::other.

◆ operator=() [1/2]

auto kcenon::pacs::security::uid_mapping::operator= ( const uid_mapping & other) -> uid_mapping&

Copy assignment.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

Definition at line 39 of file uid_mapping.cpp.

39 {
40 if (this != &other) {
41 std::scoped_lock lock(mutex_, other.mutex_);
42 uid_root_ = other.uid_root_;
43 original_to_anon_ = other.original_to_anon_;
44 anon_to_original_ = other.anon_to_original_;
45 uid_counter_.store(other.uid_counter_.load());
46 }
47 return *this;
48}

References kcenon::pacs::security::other.

◆ operator=() [2/2]

auto kcenon::pacs::security::uid_mapping::operator= ( uid_mapping && other) -> uid_mapping&
noexcept

Move assignment.

Definition at line 50 of file uid_mapping.cpp.

50 {
51 if (this != &other) {
52 std::scoped_lock lock(mutex_, other.mutex_);
53 uid_root_ = std::move(other.uid_root_);
54 original_to_anon_ = std::move(other.original_to_anon_);
55 anon_to_original_ = std::move(other.anon_to_original_);
56 uid_counter_.store(other.uid_counter_.load());
57 }
58 return *this;
59}

References kcenon::pacs::security::other.

◆ remove()

auto kcenon::pacs::security::uid_mapping::remove ( std::string_view original_uid) -> bool

Remove a specific mapping.

Parameters
original_uidThe original UID to remove
Returns
true if a mapping was removed

Definition at line 159 of file uid_mapping.cpp.

159 {
160 std::unique_lock lock(mutex_);
161
162 auto it = original_to_anon_.find(original_uid);
163 if (it == original_to_anon_.end()) {
164 return false;
165 }
166
167 auto anon_uid = it->second;
168 original_to_anon_.erase(it);
169 anon_to_original_.erase(anon_uid);
170
171 return true;
172}

◆ set_uid_root()

void kcenon::pacs::security::uid_mapping::set_uid_root ( std::string root)

Set the UID root for generated UIDs.

Parameters
rootThe UID root (e.g., "1.2.3.4")
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

Definition at line 223 of file uid_mapping.cpp.

223 {
224 std::unique_lock lock(mutex_);
225 uid_root_ = std::move(root);
226}

References mutex_, and uid_root_.

◆ size()

auto kcenon::pacs::security::uid_mapping::size ( ) const -> std::size_t
nodiscard

Get the number of mappings.

Returns
The count of UID mappings
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h, and dcm_anonymize/main.cpp.

Definition at line 143 of file uid_mapping.cpp.

143 {
144 std::shared_lock lock(mutex_);
145 return original_to_anon_.size();
146}

References mutex_, and original_to_anon_.

Referenced by main().

Here is the caller graph for this function:

◆ to_json()

auto kcenon::pacs::security::uid_mapping::to_json ( ) const -> std::string
nodiscard

Export mappings to JSON format.

Returns
JSON string containing all mappings
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h, and dcm_anonymize/main.cpp.

Definition at line 174 of file uid_mapping.cpp.

174 {
175 std::shared_lock lock(mutex_);
176
177 std::ostringstream oss;
178 oss << "{\n";
179 oss << " \"uid_root\": \"" << uid_root_ << "\",\n";
180 oss << " \"mappings\": [\n";
181
182 bool first = true;
183 for (const auto& [original, anon] : original_to_anon_) {
184 if (!first) {
185 oss << ",\n";
186 }
187 oss << " {\"original\": \"" << original
188 << "\", \"anonymized\": \"" << anon << "\"}";
189 first = false;
190 }
191
192 oss << "\n ]\n";
193 oss << "}";
194
195 return oss.str();
196}

References mutex_, original_to_anon_, and uid_root_.

Member Data Documentation

◆ anon_to_original_

std::map<std::string, std::string, std::less<> > kcenon::pacs::security::uid_mapping::anon_to_original_
private

Reverse mapping: anonymized -> original.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

Definition at line 243 of file uid_mapping.h.

Referenced by clear(), and uid_mapping().

◆ mutex_

std::shared_mutex kcenon::pacs::security::uid_mapping::mutex_
mutableprivate

◆ original_to_anon_

std::map<std::string, std::string, std::less<> > kcenon::pacs::security::uid_mapping::original_to_anon_
private

Forward mapping: original -> anonymized.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

Definition at line 240 of file uid_mapping.h.

Referenced by clear(), empty(), size(), to_json(), and uid_mapping().

◆ uid_counter_

std::atomic<std::uint64_t> kcenon::pacs::security::uid_mapping::uid_counter_ {0}
mutableprivate

Counter for UID generation.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

Definition at line 246 of file uid_mapping.h.

246{0};

Referenced by generate_uid(), and uid_mapping().

◆ uid_root_

std::string kcenon::pacs::security::uid_mapping::uid_root_ {"1.2.826.0.1.3680043.8.498.1"}
private

UID root for generated UIDs (default: pacs_system root)

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/uid_mapping.h.

Definition at line 237 of file uid_mapping.h.

237{"1.2.826.0.1.3680043.8.498.1"};

Referenced by generate_uid(), get_uid_root(), set_uid_root(), to_json(), and uid_mapping().


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