PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
storage_scu.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
20#ifndef PACS_SERVICES_STORAGE_SCU_HPP
21#define PACS_SERVICES_STORAGE_SCU_HPP
22
23#include "storage_status.h"
28
29#include <atomic>
30#include <cstdint>
31#include <filesystem>
32#include <functional>
33#include <string>
34#include <vector>
35
36namespace kcenon::pacs::services {
37
45 std::string sop_instance_uid;
46
48 uint16_t status{0};
49
51 std::string error_comment;
52
54 [[nodiscard]] bool is_success() const noexcept {
55 return status == 0x0000;
56 }
57
59 [[nodiscard]] bool is_warning() const noexcept {
60 return (status & 0xF000) == 0xB000;
61 }
62
64 [[nodiscard]] bool is_error() const noexcept {
65 return !is_success() && !is_warning();
66 }
67};
68
75using store_progress_callback = std::function<void(size_t completed, size_t total)>;
76
82 uint16_t default_priority = 0;
83
85 std::chrono::milliseconds response_timeout{30000};
86
88 bool continue_on_error = true;
89};
90
168public:
169 // =========================================================================
170 // Construction
171 // =========================================================================
172
178 explicit storage_scu(std::shared_ptr<di::ILogger> logger = nullptr);
179
186 explicit storage_scu(const storage_scu_config& config,
187 std::shared_ptr<di::ILogger> logger = nullptr);
188
189 ~storage_scu() = default;
190
191 // Non-copyable, non-movable (due to atomic members)
192 storage_scu(const storage_scu&) = delete;
196
197 // =========================================================================
198 // Single Image Operations
199 // =========================================================================
200
213 const core::dicom_dataset& dataset);
214
215 // =========================================================================
216 // Batch Operations
217 // =========================================================================
218
230 [[nodiscard]] std::vector<store_result> store_batch(
232 const std::vector<core::dicom_dataset>& datasets,
233 store_progress_callback progress_callback = nullptr);
234
235 // =========================================================================
236 // File-based Operations
237 // =========================================================================
238
250 const std::filesystem::path& file_path);
251
264 [[nodiscard]] std::vector<store_result> store_files(
266 const std::vector<std::filesystem::path>& file_paths,
267 store_progress_callback progress_callback = nullptr);
268
280 [[nodiscard]] std::vector<store_result> store_directory(
282 const std::filesystem::path& directory,
283 bool recursive = true,
284 store_progress_callback progress_callback = nullptr);
285
286 // =========================================================================
287 // Statistics
288 // =========================================================================
289
294 [[nodiscard]] size_t images_sent() const noexcept;
295
300 [[nodiscard]] size_t failures() const noexcept;
301
306 [[nodiscard]] size_t bytes_sent() const noexcept;
307
311 void reset_statistics() noexcept;
312
313private:
314 // =========================================================================
315 // Private Implementation
316 // =========================================================================
317
321 [[nodiscard]] network::Result<store_result> store_impl(
322 network::association& assoc,
323 const core::dicom_dataset& dataset,
324 uint16_t message_id);
325
329 [[nodiscard]] uint16_t next_message_id() noexcept;
330
334 [[nodiscard]] std::vector<std::filesystem::path> collect_dicom_files(
335 const std::filesystem::path& directory,
336 bool recursive) const;
337
338 // =========================================================================
339 // Private Members
340 // =========================================================================
341
343 std::shared_ptr<di::ILogger> logger_;
344
347
349 std::atomic<uint16_t> message_id_counter_{1};
350
352 std::atomic<size_t> images_sent_{0};
353
355 std::atomic<size_t> failures_{0};
356
358 std::atomic<size_t> bytes_sent_{0};
359};
360
361} // namespace kcenon::pacs::services
362
363#endif // PACS_SERVICES_STORAGE_SCU_HPP
DICOM Association management per PS3.8.
std::atomic< size_t > failures_
Statistics: number of failed operations.
size_t bytes_sent() const noexcept
Get the total bytes sent since construction.
std::atomic< uint16_t > message_id_counter_
Message ID counter.
storage_scu & operator=(storage_scu &&)=delete
network::Result< store_result > store_file(network::association &assoc, const std::filesystem::path &file_path)
Store a DICOM file.
std::atomic< size_t > images_sent_
Statistics: number of images sent successfully.
storage_scu(std::shared_ptr< di::ILogger > logger=nullptr)
Construct a Storage SCU with default configuration.
std::vector< store_result > store_batch(network::association &assoc, const std::vector< core::dicom_dataset > &datasets, store_progress_callback progress_callback=nullptr)
Store multiple DICOM datasets.
size_t images_sent() const noexcept
Get the number of images sent since construction.
network::Result< store_result > store(network::association &assoc, const core::dicom_dataset &dataset)
Store a single DICOM dataset.
size_t failures() const noexcept
Get the number of failed store operations since construction.
storage_scu & operator=(const storage_scu &)=delete
storage_scu_config config_
Configuration.
void reset_statistics() noexcept
Reset statistics counters to zero.
std::atomic< size_t > bytes_sent_
Statistics: total bytes sent.
std::vector< std::filesystem::path > collect_dicom_files(const std::filesystem::path &directory, bool recursive) const
Collect DICOM files from a directory.
std::vector< store_result > store_directory(network::association &assoc, const std::filesystem::path &directory, bool recursive=true, store_progress_callback progress_callback=nullptr)
Store all DICOM files in a directory.
uint16_t next_message_id() noexcept
Get the next message ID for DIMSE operations.
storage_scu(storage_scu &&)=delete
std::shared_ptr< di::ILogger > logger_
Logger instance for service logging.
network::Result< store_result > store_impl(network::association &assoc, const core::dicom_dataset &dataset, uint16_t message_id)
Internal implementation of single store operation.
std::vector< store_result > store_files(network::association &assoc, const std::vector< std::filesystem::path > &file_paths, store_progress_callback progress_callback=nullptr)
Store multiple DICOM files.
storage_scu(const storage_scu &)=delete
DICOM Dataset - ordered collection of Data Elements.
DIMSE message encoding and decoding.
Logger interface for dependency injection.
@ completed
Procedure completed successfully.
std::function< void(size_t completed, size_t total)> store_progress_callback
Progress callback type for batch operations.
Definition storage_scu.h:75
Storage SCP status codes for C-STORE operations.
Configuration for Storage SCU service.
Definition storage_scu.h:80
std::chrono::milliseconds response_timeout
Timeout for receiving C-STORE response (milliseconds)
Definition storage_scu.h:85
bool continue_on_error
Continue batch operation on error (true) or stop on first error (false)
Definition storage_scu.h:88
uint16_t default_priority
Default priority for C-STORE requests (0=medium, 1=high, 2=low)
Definition storage_scu.h:82
Result of a C-STORE operation.
Definition storage_scu.h:43
uint16_t status
DIMSE status code (0x0000 = success)
Definition storage_scu.h:48
bool is_warning() const noexcept
Check if this was a warning status.
Definition storage_scu.h:59
bool is_error() const noexcept
Check if this was an error status.
Definition storage_scu.h:64
std::string error_comment
Error comment from the SCP (if any)
Definition storage_scu.h:51
std::string sop_instance_uid
SOP Instance UID of the stored instance.
Definition storage_scu.h:45
bool is_success() const noexcept
Check if the store operation was successful.
Definition storage_scu.h:54