/// <summary> /// base function for communication with PhotoShop /// </summary> /// <param name="toSend"> /// <see cref="DataBlock"/> containing data to pass to PhotoShop</param> /// <returns>PhotoShop Response w.r.t <paramref name="toSend"/></returns> /// <exception cref="ObjectDisposedException"> /// thrown when invoking on disposed object /// </exception> private PhotoShopResponse SendAndReceive( DataBlock toSend) { // 01. check if object is disposed if (IsDisposed) throw new ObjectDisposedException("IOHandler"); var commError = new PhotoShopResponse() { Status = CommunicationStatus.ERROR_COMMUNICATION }; lock (_netStream) { // 02. send data to PS if (false == sendDataBlock(toSend)) return commError; // 03. receive data from PS for dedicated transaction ID return getPhotoShopResponseUntil(toSend.TransactionID); } }
/// <summary> /// change notification from PhotoShop is sent with transaction id, /// which is the transaction id when subscribing given event. /// Let's say, we subscribe foregroundColorChanged with transaction id 123, /// and toolChanged with transaction id 567. /// Then PhotoShop sends us foregroundColorChanged with transaction id 123, /// and toolChanged with transaction id 567 respectively. /// </summary> /// <param name="response"> /// <see cref="PhotoShopResponse"/> to handle. /// </param> private void processNotification( PhotoShopResponse response) { if (CommunicationStatus.OK != response.Status) return; var isEventNotification = (1 + _notificationSubscribedTransactionID) > response.ResponseBlock.TransactionID; if (false == isEventNotification) return; var actionToInvoke = PhotoShopNotificationProc; if (null == actionToInvoke) return; var strNotification = response.ReturnString .Split( new string[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries); if (null == strNotification || strNotification.Length < 1) return; var psEvent = PhotoShopNotification.INVALID_NOTIFICATION; var isValidPhotoShopEvent = Enum.TryParse<PhotoShopNotification>(strNotification[0], out psEvent); //if (false == isValidPhotoShopEvent) // return; var extraData = (strNotification.Length < 2) ? string.Empty : strNotification[1]; try { switch (psEvent) { case PhotoShopNotification.foregroundColorChanged: case PhotoShopNotification.backgroundColorChanged: case PhotoShopNotification.toolChanged: case PhotoShopNotification.closedDocument: case PhotoShopNotification.newDocumentViewCreated: case PhotoShopNotification.currentDocumentChanged: case PhotoShopNotification.activeViewChanged: case PhotoShopNotification.documentNamesChanged: case PhotoShopNotification.colorSettingsChanged: case PhotoShopNotification.keyboardShortcutsChanged: case PhotoShopNotification.preferencesChanged: case PhotoShopNotification.quickMaskStateChanged: case PhotoShopNotification.screenModeChanged: case PhotoShopNotification.gaussianBlur: actionToInvoke(psEvent, extraData); break; default: actionToInvoke(PhotoShopNotification.INVALID_NOTIFICATION, response.ReturnString); break; } } catch { // do nothing. } }
/// <summary> /// construct new <see cref="PhotoShopResponse"/> from given parameters. /// </summary> /// <param name="commStatus"> /// communication status returned from PhotoShop /// </param> /// <param name="replyBytes"> /// byte array returned from PhotoShop /// </param> /// <returns> /// new <see cref="PhotoShopResponse"/> from given parameters. /// </returns> /// <exception cref="ArgumentNullException"> /// thrown when <paramref name="replyBytes"/> is null /// </exception> private PhotoShopResponse constructPhotoShopResponse( int commStatus, byte[] replyBytes) { if (null == replyBytes) throw new ArgumentNullException("replyBytes"); try { switch (commStatus) { // when PS reports no-error, case PhotoShopConstants.NO_COMM_ERROR: writeAsRunLog( "Read this encrypted message : " + replyBytes.Length, replyBytes); var recvDataBlock = DataBlock.CreateNonErrorDataBlock( _encryptDecrypt, replyBytes); writeAsRunLog( "Decrypted Message : ", recvDataBlock); var resultOK = new PhotoShopResponse() { Status = CommunicationStatus.OK, ResponseBlock = recvDataBlock, }; writeAsRunLog( "PS Response" + Environment.NewLine + resultOK.ToString()); return resultOK; // when PS reports error of its own default: writeAsRunLog( "Read this error message : " + replyBytes.Length, replyBytes); var errorBlock = DataBlock.CreateErrorDataBlock(replyBytes); var resultError = new PhotoShopResponse() { Status = CommunicationStatus.ERROR_PS_REPORT, ResponseBlock = errorBlock }; writeAsRunLog( "PS Response" + Environment.NewLine + resultError.ToString()); return resultError; } } catch { return new PhotoShopResponse() { Status = CommunicationStatus.ERROR_COMMUNICATION }; } }