/// <summary>
        /// Fail the remaining SOP Instances for sending.
        /// </summary>
        private void FailRemaining(DicomStatus status)
        {
            while (_fileListIndex < _storageInstanceList.Count)
            {
                StorageInstance fileToSend = _storageInstanceList[_fileListIndex];

                OnImageStoreStarted(fileToSend);

                fileToSend.SendStatus = status;

                _failureSubOperations++;
                _remainingSubOperations--;

                fileToSend.ExtendedFailureDescription = "The association was aborted.";

                OnImageStoreCompleted(fileToSend);

                _fileListIndex++;
            }
        }
        private void LogError(StorageInstance instance, DicomMessage msg, DicomStatus dicomStatus)
        {
            if (dicomStatus == DicomStatuses.SOPClassNotSupported)
            {
                var log = new StringBuilder();

                log.AppendLine(string.Format("Unable to transfer SOP {0} in study {1}. Remote device does not accept {2} in {3} transfer syntax",
                                             instance.SopInstanceUid, instance.StudyInstanceUid, msg.SopClass, msg.TransferSyntax));

                if (instance.TransferSyntax.Encapsulated)
                {
                    var codecExists = DicomCodecRegistry.GetCodec(instance.TransferSyntax) != null;

                    log.AppendLine(codecExists
                                       ? string.Format("Note: codec is available for {0} but remote device does not support it?", instance.TransferSyntax)
                                       : string.Format("Note: codec is NOT available for {0}", instance.TransferSyntax));
                }

                Platform.Log(LogLevel.Error, log.ToString());
            }
        }
        /// <summary>
        /// Generic routine to send the next C-STORE-RQ message in the <see cref="StorageInstanceList"/>.
        /// </summary>
        /// <param name="client">DICOM Client class</param>
        /// <param name="association">Association Parameters</param>
        private bool SendCStore(DicomClient client, ClientAssociationParameters association)
        {
            StorageInstance fileToSend = _storageInstanceList[_fileListIndex];

            OnImageStoreStarted(fileToSend);

            DicomFile dicomFile;

            try
            {
                // Check to see if image does not exist or is corrupted
                if (fileToSend.SendStatus == DicomStatuses.ProcessingFailure)
                {
                    _failureSubOperations++;
                    _remainingSubOperations--;
                    OnImageStoreCompleted(fileToSend);
                    return(false);
                }

                dicomFile = fileToSend.LoadFile();
            }
            catch (DicomException e)
            {
                Platform.Log(LogLevel.Error, e, "Unexpected exception when loading DICOM file {0}", fileToSend.Filename);

                fileToSend.ExtendedFailureDescription = e.GetType().Name + " " + e.Message;
                _failureSubOperations++;
                _remainingSubOperations--;
                OnImageStoreCompleted(fileToSend);
                return(false);
            }

            try
            {
                DicomMessage msg;

                byte pcid = SelectPresentationContext(association, fileToSend, dicomFile, out msg);

                if (pcid == 0)
                {
                    fileToSend.SendStatus = DicomStatuses.SOPClassNotSupported;
                    fileToSend.ExtendedFailureDescription = string.Format(SR.ErrorSendSopClassNotSupported, msg.SopClass);

                    LogError(fileToSend, msg, DicomStatuses.SOPClassNotSupported);

                    _failureSubOperations++;
                    _remainingSubOperations--;
                    OnImageStoreCompleted(fileToSend);
                    return(false);
                }

                try
                {
                    SendOnPresentationContext(client, association, pcid, fileToSend, msg);
                }
                catch (DicomCodecUnsupportedSopException e)
                {
                    if (!msg.TransferSyntax.Encapsulated)
                    {
                        pcid = SelectUncompressedPresentationContext(association, msg);
                        if (pcid != 0)
                        {
                            SendOnPresentationContext(client, association, pcid, fileToSend, msg);
                            Platform.Log(LogLevel.Warn, "Could not send SOP as compressed, sent as uncompressed: {0}, file: {1}", e.Message, fileToSend.SopInstanceUid);
                            return(true);
                        }
                    }

                    throw;
                }
            }
            catch (DicomNetworkException)
            {
                throw; //This is a DicomException-derived class that we want to throw.
            }
            catch (DicomCodecException e)
            {
                Platform.Log(LogLevel.Error, e, "Unexpected exception when compressing or decompressing file before send {0}", fileToSend.Filename);

                fileToSend.SendStatus = DicomStatuses.ProcessingFailure;
                fileToSend.ExtendedFailureDescription = string.Format("Error decompressing or compressing file before send: {0}", e.Message);
                _failureSubOperations++;
                _remainingSubOperations--;
                OnImageStoreCompleted(fileToSend);
                return(false);
            }
            catch (DicomException e)
            {
                Platform.Log(LogLevel.Error, e, "Unexpected exception while sending file {0}", fileToSend.Filename);

                fileToSend.SendStatus = DicomStatuses.ProcessingFailure;
                fileToSend.ExtendedFailureDescription = string.Format("Unexpected exception while sending file: {0}", e.Message);
                _failureSubOperations++;
                _remainingSubOperations--;
                OnImageStoreCompleted(fileToSend);
                return(false);
            }

            return(true);
        }
        private void SendOnPresentationContext(DicomClient client, ClientAssociationParameters association, byte pcid, StorageInstance fileToSend, DicomMessage msg)
        {
            var presContext = association.GetPresentationContext(pcid);

            if (msg.TransferSyntax.Encapsulated &&
                presContext.AcceptedTransferSyntax.Encapsulated &&
                !msg.TransferSyntax.Equals(presContext.AcceptedTransferSyntax))
            {
                // Compressed in different syntaxes, decompress here first, ChangeTransferSyntax does not convert syntaxes properly in this case.
                msg.ChangeTransferSyntax(TransferSyntax.ExplicitVrLittleEndian);
            }

            fileToSend.SentMessageId = client.NextMessageID();

            if (_moveOriginatorAe == null)
            {
                client.SendCStoreRequest(pcid, fileToSend.SentMessageId, DicomPriority.Medium, msg);
            }
            else
            {
                client.SendCStoreRequest(pcid, fileToSend.SentMessageId, DicomPriority.Medium, _moveOriginatorAe,
                                         _moveOriginatorMessageId, msg);
            }
        }
        private byte SelectPresentationContext(ClientAssociationParameters association, StorageInstance fileToSend, DicomFile dicomFile, out DicomMessage msg)
        {
            byte pcid = 0;

            if (PresentationContextSelectionDelegate != null)
            {
                // Note, this may do a conversion of the file according to codecs, need to catch a codec exception if it occurs
                pcid = PresentationContextSelectionDelegate(association, dicomFile, out msg);
            }
            else
            {
                msg = new DicomMessage(dicomFile);

                if (fileToSend.TransferSyntax.Encapsulated)
                {
                    pcid = association.FindAbstractSyntaxWithTransferSyntax(msg.SopClass,
                                                                            msg.TransferSyntax);

                    if (DicomCodecRegistry.GetCodec(fileToSend.TransferSyntax) != null)
                    {
                        // We can compress/decompress the file. Check if remote device accepts it
                        if (pcid == 0)
                        {
                            pcid = SelectUncompressedPresentationContext(association, msg);
                        }
                    }
                }
                else
                {
                    if (pcid == 0)
                    {
                        pcid = SelectUncompressedPresentationContext(association, msg);
                    }
                }
            }
            return(pcid);
        }
 /// <summary>
 /// Adds the specified storage instanceto <see cref="StorageInstanceList"/>.
 /// </summary>
 /// <param name="storageInstance">The storage instance.</param>
 public void AddStorageInstance(StorageInstance storageInstance)
 {
     StorageInstanceList.Add(storageInstance);
 }