This file is indexed.

/usr/include/dcmtk/dcmnet/dstorscu.h is in libdcmtk-dev 3.6.1~20150924-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
/*
 *
 *  Copyright (C) 2011-2014, OFFIS e.V.
 *  All rights reserved.  See COPYRIGHT file for details.
 *
 *  This software and supporting documentation were developed by
 *
 *    OFFIS e.V.
 *    R&D Division Health
 *    Escherweg 2
 *    D-26121 Oldenburg, Germany
 *
 *
 *  Module:  dcmnet
 *
 *  Author:  Joerg Riesmeier
 *
 *  Purpose: DICOM Storage Service Class User (SCU)
 *
 */

#ifndef DSTORSCU_H
#define DSTORSCU_H

#include "dcmtk/config/osconfig.h"  /* make sure OS specific configuration is included first */

#include "dcmtk/dcmnet/scu.h"       /* for base class DcmSCU */


/*---------------------*
 *  class declaration  *
 *---------------------*/

/** Interface class for a Storage Service Class User (SCU).
 *  This class supports C-STORE messages as an SCU.  In a first step, the SOP instances to be
 *  sent are added to a transfer list.  In a second step, the association negotiation takes
 *  place where the required presentation contexts are proposed, i.e. it is checked which SOP
 *  classes and transfer syntaxes are needed for transferring the SOP instances.  Finally, the
 *  SOP instances are sent to the SCP (if possible).
 *  \note
 *    \li The current implementation does not sort the transfer list according to the SOP
 *        Class UID and Transfer Syntax UID of the SOP instances and, therefore, might propose
 *        more presentation contexts than required for the transfer of all SOP instances.  A
 *        simple optimization that is performed internally is to check whether the current SOP
 *        instance can be sent using a presentation context that has previously been added for
 *        another SOP instance (of the same kind).  This approach also makes sure that studies
 *        and series are not mixed up, assuming that they have been added to the transfer list
 *        in the "correct" order.
 *    \li Another limitation of the current implementation is the handling of the "Default
 *        Transfer Syntax" in case of compression.  According to the DICOM standard, the
 *        default transfer syntax for "Lossless JPEG Compression", "Lossy JPEG Compression"
 *        and so on has to be proposed in at least one presentation context for the particular
 *        SOP class.  This is not (yet) implemented since the re-encoding of compressed
 *        datasets is not supported.  Nevertheless, depending on the options used, the default
 *        transfer syntax for the uncompressed case is always proposed (if possible).
 */
class DCMTK_DCMNET_EXPORT DcmStorageSCU
  : public DcmSCU
{

  public:

    /** dataset decompression modes
     */
    enum E_DecompressionMode
    {
        /// never decompress datasets
        DM_never,
        /// decompress lossless only
        DM_losslessOnly,
        /// default value: decompress lossless only
        DM_default = DM_losslessOnly,
        /// decompress both lossy and lossless
        DM_lossyAndLossless
    };

    /** dataset handling modes
     */
    enum E_HandlingMode
    {
        /// do nothing with the dataset
        HM_doNothing,
        /// compact the dataset after it has been sent
        HM_compactAfterSend,
        /// delete the dataset after it has been sent
        HM_deleteAfterSend,
        /// delete the dataset after it has been removed from the transfer list
        HM_deleteAfterRemove
    };

    /** default constructor
     */
    DcmStorageSCU();

    /** destructor
     */
    virtual ~DcmStorageSCU();

    /** clear the internal member variables
     */
    virtual void clear();

    /** get value of the association counter.  This counter is initialized with 0 (that means
     *  no association exists) and increased by 1 for every new association.  The counter is
     *  only reset when clear() is called.
     *  @return value of the association counter
     */
    unsigned long getAssociationCounter() const;

    /** get number of SOP instances stored in the transfer list
     *  @return number of SOP instances stored in the transfer list
     */
    size_t getNumberOfSOPInstances() const;

    /** get number of SOP instances that are to be sent (i.e.\ that are not yet sent).  Please
     *  note that internally the transfer list is iterated to determine this number, so
     *  depending on the size of the list it might take some time.
     *  @return number of SOP instances that are to be sent
     */
    size_t getNumberOfSOPInstancesToBeSent() const;

    /** get mode that specifies whether or not compressed datasets are decompressed if needed,
     *  i.e.\ whether the transfer syntax of the dataset is changed for network transmission.
     *  @return decompression mode. See definition of DcmStorageSCU::E_DecompressionMode for
     *    possible values.
     */
    E_DecompressionMode getDecompressionMode() const;

    /** get mode that specifies whether to halt if an invalid file is encountered during batch
     *  processing (e.g.\ when adding SOP instances from a DICOMDIR) or whether to continue
     *  with the next SOP instance.
     *  @return mode indicating whether to halt on invalid file or not
     */
    OFBool getHaltOnInvalidFileMode() const;

    /** get mode that specifies whether to halt if unsuccessful store encountered or whether
     *  to continue with the next SOP instance.
     *  @return mode indicating whether to halt on unsuccessful store or not
     */
    OFBool getHaltOnUnsuccessfulStoreMode() const;

    /** get mode that specifies whether to propose presentation contexts that do not contain
     *  the default transfer syntax although it is needed, which might result in a violation
     *  of the DICOM standard.
     *  @return mode indicating whether illegal proposals are allowed or not
     */
    OFBool getAllowIllegalProposalMode() const;

    /** get mode that specifies whether to read information on SOP instances to be sent from
     *  the DICOMDIR files that are added to the transfer list.
     *  @return mode indicating whether to read from DICOMDIR files or not
     */
    OFBool getReadFromDICOMDIRMode() const;

    /** get C-MOVE originator information (if set)
     *  @param  aeTitle    the AE title of the originating C-MOVE client.  Empty if not set.
     *  @param  messageID  the message ID used within the originating C-MOVE request.  0 if
     *                     not set.
     *  @return OFTrue if either of both parameters is set
     */
    OFBool getMOVEOriginatorInfo(OFString &aeTitle,
                                 Uint16 &messageID) const;

    /** set mode that specifies whether or not compressed datasets are decompressed if needed,
     *  i.e.\ whether the transfer syntax of the dataset is changed for network transmission.
     *  @param  decompressionMode  decompression mode. See definition of
     *                             DcmStorageSCU::E_DecompressionMode for both possible values
     *                             and the default value.
     */
    void setDecompressionMode(const E_DecompressionMode decompressionMode);

    /** set mode that specifies whether to halt if an invalid file is encountered during batch
     *  processing (e.g.\ when adding SOP instances from a DICOMDIR) or whether to continue
     *  with the next SOP instance.
     *  @param  haltMode  mode indicating whether to halt or not (default: OFTrue, i.e.\ halt)
     */
    void setHaltOnInvalidFileMode(const OFBool haltMode);

    /** set mode that specifies whether to halt if unsuccessful store encountered or whether
     *  to continue with the next SOP instance.
     *  @param  haltMode  mode indicating whether to halt or not (default: OFTrue, i.e.\ halt)
     */
    void setHaltOnUnsuccessfulStoreMode(const OFBool haltMode);

    /** set mode that specifies whether to propose presentation contexts that do not contain
     *  the default transfer syntax, although it is needed, which might result in a violation
     *  of the DICOM standard.  For example, if a lossless compressed SOP instance is to be
     *  sent, there should be at least one presentation context for this SOP class that also
     *  proposes the default transfer syntax (Implicit VR Little Endian).
     *  @param  allowMode  mode indicating whether illegal proposals are allowed or not
     *                     (default: OFTrue, i.e.\ allowed)
     */
    void setAllowIllegalProposalMode(const OFBool allowMode);

    /** set mode that specifies whether to read information on SOP instances to be sent from
     *  the DICOMDIR files that are added to the transfer list.  If this mode is disabled, a
     *  DICOMDIR file is treated like any other input file.  If this mode is enabled, a
     *  DICOMDIR file is not added to the transfer list, but the DICOM files referenced from
     *  it are.
     *  @param  readMode  mode indicating whether to read from DICOMDIR files or not
     *                    (default: OFFalse, i.e.\ do not read)
     */
    void setReadFromDICOMDIRMode(const OFBool readMode);

    /** set C-MOVE originator information.
     *  If the C-STORE operation was initiated by a client's C-MOVE request, it is possible
     *  to convey the C-MOVE originating information (AE title and the message ID of the
     *  corresponding C-MOVE message) as part of the C-STORE messages in order to inform the
     *  C-STORE receiver (Storage SCP) about the original sender (Move SCU).
     *  @param  aeTitle    the AE title of the originating C-MOVE client. If empty, none is
     *                     sent.
     *  @param  messageID  message ID of the originating C-MOVE request.  If 0, none is sent.
     */
    void setMOVEOriginatorInfo(const OFString &aeTitle = "",
                               const Uint16 messageID = 0);

    /** reset the sent status for all SOP instances in the transfer list.  This allows for
     *  sending the same SOP instances again - on the same or a different association.
     *  @param  sameAssociation  flag indicating whether the same association will be used for
     *                           the transfer as last time.  If a different association will
     *                           be used, also the presentation context IDs are set to 0
     *                           (undefined), which means that addPresentationContexts() has
     *                           to be called again.  Please make sure that all dataset
     *                           pointers in the transfer list are still valid, i.e. the
     *                           datasets have not been deleted.
     */
    void resetSentStatus(const OFBool sameAssociation = OFFalse);

    /** remove all SOP instances from the transfer list.  If an entry contains a reference to
     *  a DICOM dataset, this dataset is deleted if the handling mode HM_deleteAfterRemove was
     *  used to add it to the transfer list.
     */
    void removeAllSOPInstances();

    /** remove a particular SOP instance from the transfer list.  If the corresponding entry
     *  contains a reference to a DICOM dataset, this dataset is deleted if the handling mode
     *  HM_deleteAfterRemove was used to add it to the transfer list.
     *  @param  sopClassUID     SOP Class UID of the SOP instance to be removed
     *  @param  sopInstanceUID  SOP Instance UID of the SOP instance to be removed
     *  @param  allOccurrences  flag specifying whether to delete all occurrences of the
     *                          SOP instance if it has been added to the list multiple times.
     *                          If OFFalse, only the first occurrence is removed.
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    OFCondition removeSOPInstance(const OFString &sopClassUID,
                                  const OFString &sopInstanceUID,
                                  const OFBool allOccurrences = OFTrue);

    /** add a SOP instance stored as a DICOM file or a number of SOP instances referenced from
     *  a DICOMDIR to the list of instances to be transferred.  Before adding a SOP instance
     *  to the list, it is checked for validity and conformance to the DICOM standard
     *  (see checkSOPInstance() for details).  However, duplicate instances are not
     *  recognized, i.e. they are added to the list and later on transferred to the storage
     *  SCP when calling sendSOPInstances().  If the specified DICOM file is a DICOMDIR and
     *  the 'ReadFromDICOMDIRMode' is enabled, the referenced SOP instances are added to the
     *  transfer list (using the relevant information from the DICOMDIR) and not the DICOMDIR
     *  itself, which is not meant to be transferred anyway.  Please note that it is not
     *  checked whether the referenced files really exist.
     *  @param  filename     name of the DICOM file that contains the SOP instance or name of
     *                       the DICOMDIR file that references the SOP instances to be sent
     *  @param  readMode     read mode passed to the DcmFileFormat::loadFile() method.  If
     *                       ERM_fileOnly, only the file meta information header is loaded,
     *                       i.e. the behavior is identical to using ERM_metaOnly.
     *  @param  checkValues  flag indicating whether to check the UID values for validity and
     *                       conformance.  If OFFalse, only empty values are rejected.
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    OFCondition addDicomFile(const OFString &filename,
                             const E_FileReadMode readMode = ERM_fileOnly,
                             const OFBool checkValues = OFTrue);

    /** add a SOP instance from a given DICOM dataset to the list of instances to be
     *  transferred.  Before adding the SOP instance to the list, it is checked for validity
     *  and conformance to the DICOM standard (see checkSOPInstance() for details).  However,
     *  duplicate instances are not recognized, i.e. they are added to the list and later on
     *  transferred to the storage SCP when calling sendSOPInstances().
     *  @param  dataset       DICOM dataset that contains the SOP instance to be sent
     *  @param  datasetXfer   transfer syntax of the dataset (determined automatically if
     *                        unknown, which is also the default)
     *  @param  handlingMode  mode specifying what to do with the dataset if no longer needed.
     *                        HM_xxxAfterSend has no effect if the C-STORE request could not
     *                        be sent.
     *                        Please do not add the same dataset multiple times with a mode of
     *                        HM_deleteAfterXXX, since it will result in deleting the same
     *                        object multiple times!
     *  @param  checkValues   flag indicating whether to check the UID values for validity and
     *                        conformance.  If OFFalse, only empty values are rejected.
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    OFCondition addDataset(DcmDataset *dataset,
                           const E_TransferSyntax datasetXfer = EXS_Unknown,
                           const E_HandlingMode handlingMode = HM_compactAfterSend,
                           const OFBool checkValues = OFTrue);

    /** add presentation contexts for all SOP instances in the transfer list, which were not
     *  yet sent (either successfully or unsuccessfully).  Initially, the internal list of
     *  presentation contexts is cleared.  Then, the transfer list is iterated and a new
     *  presentation context is added for each SOP instance that cannot be sent using any of
     *  the previously added presentation contexts.  If the maximum of 128 presentation
     *  contexts, which can be negotiated during a single association, is reached, this method
     *  returns and any subsequent call adds the next bunch of presentation contexts needed.
     *  @return status, EC_Normal if successful, an error code otherwise.  If no presentation
     *     contexts have been added, NET_EC_NoPresentationContextsDefined is returned.  This
     *     code can, therefore, be used to check that all SOP instances from the transfer list
     *     have been negotiated and sent in previous calls.
     */
    OFCondition addPresentationContexts();

    /** negotiate association by using presentation contexts and parameters as defined by
     *  earlier method calls.  If negotiation fails, there is no need to close the
     *  association or to do anything else with this class.
     *  In addition to the implementation inherited from the base class DcmSCU, this method
     *  also handles the case that none of the proposed presentation contexts was accepted.
     *  And, it also increases the association counter by 1 for each new association
     *  (including the ones that are not successful).
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    virtual OFCondition negotiateAssociation();

    /** send SOP instances to be transferred to the specified peer.  After the presentation
     *  contexts for the current association have been added and negotiated, the SOP instances
     *  that are to be sent on this association can be transferred with this method.  Unless
     *  the corresponding mode is disabled using setHaltOnUnsuccessfulStoreMode(), the
     *  transfer is stopped on the first SOP instance that could not be "stored" successfully.
     *  Please note, however, that the DIMSE status is not checked for this purpose, i.e. the
     *  transfer is never stopped when the DIMSE status is different from 0x0000 (success).
     *  Each time a SOP instance from the transfer list has been processed, the virtual method
     *  notifySOPInstanceSent() is called, which can be overwritten by a derived class.
     *  The sending process can be stopped by overwriting shouldStopAfterCurrentSOPInstance()
     *  in a derived class.  The sending process can be continued with the next SOP instance
     *  by calling sendSOPInstances() again.
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    OFCondition sendSOPInstances();

    /** get some status information on the overall sending process.  This text can for example
     *  be output to the logger (on the level at the user's option).
     *  @param  summary  reference to a string in which the summary is stored
     */
    void getStatusSummary(OFString &summary) const;

    /** create a text file with a detailed report on the transfer of DICOM SOP instances.  In
     *  addition to a general header and some status information at the end (as generated by
     *  getStatusSummary()), a couple of basic details on each SOP instance in the transfer
     *  list are written to the file:
     *  - Consecutive number
     *  - Name of the DICOM file
     *  - SOP Instance UID
     *  - SOP Class UID (and associated name)
     *  - Transfer Syntax UID (and associated name)
     *  - Number of the association (that was used to transfer the instance)
     *  - Presentation Context ID (that was used to transfer the instance)
     *  - DIMSE Status (if instance was sent) or reason why it was not sent
     *  @param  filename  name of the text file in which the report is stored
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    OFCondition createReportFile(const OFString &filename) const;


  protected:

    /** internal class/struct for a single transfer entry
     */
    struct DCMTK_DCMNET_EXPORT TransferEntry
    {
        /** constructor. Initializes member variables with reasonable values.
         *  @param  filename           filename of the SOP instance to be transferred
         *  @param  readMode           mode to read the given SOP instance from file
         *  @param  sopClassUID        SOP Class UID of the SOP instance to be transferred
         *  @param  sopInstanceUID     SOP Instance UID of the SOP instance to be transferred
         *  @param  transferSyntaxUID  Transfer Syntax UID of the SOP instance to be
         *                             transferred
         */
        TransferEntry(const OFString &filename,
                      const E_FileReadMode readMode,
                      const OFString &sopClassUID,
                      const OFString &sopInstanceUID,
                      const OFString &transferSyntaxUID);

        /** constructor. Initializes member variables with reasonable values.
         *  @param  dataset            pointer to the dataset of the SOP instance to be
         *                             transferred
         *  @param  handlingMode       mode specifying what to do with the dataset if no
         *                             longer needed
         *  @param  sopClassUID        SOP Class UID of the SOP instance to be transferred
         *  @param  sopInstanceUID     SOP Instance UID of the SOP instance to be transferred
         *  @param  transferSyntaxUID  Transfer Syntax UID of the SOP instance to be
         *                             transferred
         */
        TransferEntry(DcmDataset *dataset,
                      const E_HandlingMode handlingMode,
                      const OFString &sopClassUID,
                      const OFString &sopInstanceUID,
                      const OFString &transferSyntaxUID);

        /** destructor
         */
        ~TransferEntry();

        /// filename of the SOP instance to be transferred (if no 'Dataset' given)
        const OFString Filename;
        /// read mode that should be used to read the given SOP instance from file
        const E_FileReadMode FileReadMode;
        /// dataset of the SOP instance to be transferred (if no 'Filename' given)
        DcmDataset *Dataset;
        /// handling mode specifying what to do with the dataset if no longer needed
        const E_HandlingMode DatasetHandlingMode;
        /// SOP Class UID of the SOP instance to be transferred
        const OFString SOPClassUID;
        /// SOP Instance UID of the SOP instance to be transferred
        const OFString SOPInstanceUID;
        /// Transfer Syntax UID of the SOP instance to be transferred
        const OFString TransferSyntaxUID;
        /// transfer syntax that was used to send this SOP instance
        E_TransferSyntax NetworkTransferSyntax;
        /// flag indicating whether the SOP instance is uncompressed, i.e.\ uses any of the
        /// three uncompressed transfer syntaxes
        OFBool Uncompressed;
        /// association number that was used to send this SOP instance (0 = not sent)
        unsigned long AssociationNumber;
        /// presentation context ID to be used for sending this SOP instance
        T_ASC_PresentationContextID PresentationContextID;
        /// flag indicating whether the C-STORE request has been sent (OFTrue = sent)
        OFBool RequestSent;
        /// DIMSE status of the C-STORE response (0x0000 = success)
        Uint16 ResponseStatusCode;

      private:

        /** initialize further member variables
         */
        void Init();

        // private undefined copy constructor
        TransferEntry(const TransferEntry &);

        // private undefined assignment operator
        TransferEntry &operator=(const TransferEntry &);
    };

    /** add SOP instances referenced from a given DICOMDIR to the list of instances to be
     *  transferred.  Please note that the referenced DICOM files are not loaded during this
     *  process.  Only the relevant information contained in the DICOMDIR is used.
     *  @param  filename     name of the DICOMDIR file that contains the references to SOP
     *                       instances to be sent
     *  @param  readMode     read mode passed to the DcmFileFormat::loadFile() method when
     *                       reading the referenced DICOM files.  Not used for the DICOMDIR.
     *  @param  checkValues  flag indicating whether to check the UID values of the SOP
     *                       instances to be added for validity and conformance.  If OFFalse,
     *                       only empty values are rejected.
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    OFCondition addDicomFilesFromDICOMDIR(const OFString &filename,
                                          const E_FileReadMode readMode,
                                          const OFBool checkValues);

    // --- static methods ---

    /** check given SOP Class UID, SOP Instance UID and Transfer Syntax UID for validity and
     *  conformance to the DICOM standard.  For all UID values, the compliance with the
     *  requirements of the value representation "Unique Identifier" (UI) and value
     *  multiplicity is checked.  For the SOP Class UID, it is also checked whether it is a
     *  known or at least a possible storage SOP class (either a standard or a private one).
     *  For the Transfer Syntax UID, it is checked whether it is known and generally
     *  supported.  Further checks will be performed when the list of presentation contexts is
     *  created for the association negotiation.
     *  @param  sopClassUID        value of the SOP Class UID to be checked
     *  @param  sopInstanceUID     value of the SOP Instance UID to be checked
     *  @param  transferSyntaxUID  value of the Transfer Syntax UID to be checked
     *  @param  checkValues        flag indicating whether to check the UID values for
     *                             validity and conformance.  If OFFalse, only empty values
     *                             are rejected.
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    static OFCondition checkSOPInstance(const OFString &sopClassUID,
                                        const OFString &sopInstanceUID,
                                        const OFString &transferSyntaxUID,
                                        const OFBool checkValues);

    /** This method is called each time a SOP instance is sent to a peer.  Since it is called
     *  after the SOP instance has been processed, the transfer entry passed to this method
     *  contains current information, e.g. the DIMSE status of the C-STORE response.  This
     *  also allows for counting the number of successful and failed transfers.
     *  @param  transferEntry  reference to current transfer entry that has been processed
     */
    virtual void notifySOPInstanceSent(const TransferEntry &transferEntry);

    /** This method is called each time after a SOP instance is sent to a peer.  If the
     *  return value is OFTrue, the SCU will stop the sending process after the current SOP
     *  instance.  This could for example make sense when transferring SOP instances due to
     *  a C-MOVE request, which is externally canceled by a C-CANCEL message.  The default
     *  implementation always returns OFFalse.  A derived class may change this behavior.
     *  @return OFTrue if sending should stop after current SOP instance, OFFalse otherwise.
     */
    virtual OFBool shouldStopAfterCurrentSOPInstance();


  private:

    /// association counter
    unsigned long AssociationCounter;
    /// presentation context counter
    unsigned long PresentationContextCounter;
    /// decompression mode, i.e.\ whether a dataset is decompressed for transmission
    E_DecompressionMode DecompressionMode;
    /// flag indicating whether to halt on invalid file
    OFBool HaltOnInvalidFileMode;
    /// flag indicating whether to halt on unsuccessful store
    OFBool HaltOnUnsuccessfulStoreMode;
    /// flag indicating whether to allow illegal proposals
    OFBool AllowIllegalProposalMode;
    /// flag indicating whether to read from DICOMDIR files
    OFBool ReadFromDICOMDIRMode;
    /// AE title of the C-MOVE client that initiated the C-STORE operation (if applicable)
    OFString MoveOriginatorAETitle;
    /// message ID of the C-MOVE message that initiated the C-STORE operation (if applicable)
    Uint16 MoveOriginatorMsgID;
    /// list of SOP instances to be transferred
    OFList<TransferEntry *> TransferList;
    /// iterator pointing to the current entry in the list of SOP instances to be transferred
    OFListIterator(TransferEntry *) CurrentTransferEntry;

    // private undefined copy constructor
    DcmStorageSCU(const DcmStorageSCU &);

    // private undefined assignment operator
    DcmStorageSCU &operator=(const DcmStorageSCU &);
};

#endif // DSTORSCU_H