From e47b1c9602a839b8100f2c44b5bf925dc200682d Mon Sep 17 00:00:00 2001 From: sunwen Date: Tue, 22 Aug 2023 10:47:19 +0800 Subject: [PATCH] Delete try catch from ReconClient. --- src/recon/ProtocolStructs.h | 8 +++ src/recon/ReconClient.cpp | 67 +++++++++++++++++++++----- src/recon/ReconClient.h | 1 + thirdParty/Req/pub/include/Request.h | 5 +- thirdParty/Req/pub/include/Response.h | 3 ++ thirdParty/Req/pub/lib/libReq.so | Bin 20408 -> 20256 bytes 6 files changed, 70 insertions(+), 14 deletions(-) diff --git a/src/recon/ProtocolStructs.h b/src/recon/ProtocolStructs.h index 28f8a4c..351a139 100644 --- a/src/recon/ProtocolStructs.h +++ b/src/recon/ProtocolStructs.h @@ -17,4 +17,12 @@ struct TaskQueryResult bool Start ; }; +struct PACSSetting +{ + std::string AETitle; + std::string ServerAETitle; + std::string ServerIP; + int Port = 0;; +}; + #endif // __SCAN_H__ \ No newline at end of file diff --git a/src/recon/ReconClient.cpp b/src/recon/ReconClient.cpp index 9c5be99..63e97f2 100644 --- a/src/recon/ReconClient.cpp +++ b/src/recon/ReconClient.cpp @@ -10,6 +10,7 @@ namespace { const char* QUERY_VERSION_URL = "/Version/"; const char* QUERY_RECON_URL = "/Task/Query/"; const char* QUERY_TRANSFER_URL = "/Transfer/Query/"; + const char* SET_PACS_URL = "/Transfer/Setting/"; } namespace Recon { @@ -46,11 +47,13 @@ namespace Recon { content.append(str); free(str); auto resp = mRequest.post(mHost+CREATE_URL,content,mHeaders); - if (resp.httpCode() == 201){ + if (resp->httpCode() == 201){ + delete resp; return RequestResult::Success(); } else{ - mErrorMessage = resp.getContent(); + mErrorMessage = resp->getContent(); + delete resp; return RequestResult::Fail(mErrorMessage); } } @@ -65,8 +68,9 @@ namespace Recon { content.append(str); free(str); auto resp = mRequest.post(mHost+QUERY_SCAN_URL,content,mHeaders); - if (resp.httpCode() == 200){ - cJSON * scans = cJSON_Parse(resp.getContent().data()); + if (resp->httpCode() == 200){ + cJSON * scans = cJSON_Parse(resp->getContent().data()); + delete resp; int size = cJSON_GetArraySize(scans); if (size == 1){ cJSON * scaninf = cJSON_GetArrayItem(scans, 0); @@ -81,7 +85,8 @@ namespace Recon { return RequestResult::Fail(mErrorMessage); } else{ - mErrorMessage = resp.getContent(); + mErrorMessage = resp->getContent(); + delete resp; return RequestResult::Fail(mErrorMessage); } } @@ -96,16 +101,18 @@ namespace Recon { content.append(str); free(str); auto resp = mRequest.post(mHost+QUERY_RECON_URL,content,mHeaders); - if (resp.httpCode() == 204){ + if (resp->httpCode() == 204){ + delete resp; return RequestResult::Success(); } - else if (resp.httpCode() == 200){ - - aReconID = resp.getContent(); + else if (resp->httpCode() == 200){ + aReconID = resp->getContent(); + delete resp; return RequestResult::Success(aReconID); } else{ - mErrorMessage = resp.getContent(); + mErrorMessage = resp->getContent(); + delete resp; return RequestResult::Fail(mErrorMessage); } @@ -121,8 +128,9 @@ namespace Recon { content.append(str); free(str); auto resp = mRequest.post(mHost+QUERY_RECON_URL,content,mHeaders); - if (resp.httpCode() == 200){ - cJSON * task = cJSON_Parse(resp.getContent().data()); + if (resp->httpCode() == 200){ + cJSON * task = cJSON_Parse(resp->getContent().data()); + delete resp; aTask.ReconID = cJSON_GetObjectItem(task, "ReconID")->valuestring; aTask.ScanID= cJSON_GetObjectItem(task, "ScanID")->valuestring; aTask.Start = cJSON_GetObjectItem(task, "Start")->valueint!=0; @@ -131,7 +139,40 @@ namespace Recon { return RequestResult::Success(); } else{ - mErrorMessage = resp.getContent(); + mErrorMessage = resp->getContent(); + delete resp; + return RequestResult::Fail(mErrorMessage); + } + } + + RequestResult ReconClient::SetPACSSetting(const PACSSetting& aSetting) + { + cJSON * obj = cJSON_CreateObject(); + if (!aSetting.AETitle.empty()){ + cJSON_AddStringToObject(obj, "AETitle", aSetting.AETitle.c_str()); + } + if (!aSetting.ServerIP.empty()){ + cJSON_AddStringToObject(obj, "IP", aSetting.ServerIP.c_str()); + } + if (!aSetting.ServerAETitle.empty()){ + cJSON_AddStringToObject(obj, "ServerAETitle", aSetting.ServerAETitle.c_str()); + } + if (aSetting.Port>0){ + cJSON_AddNumberToObject(obj, "Port", aSetting.Port); + } + char* str = cJSON_Print(obj); + cJSON_Delete(obj); + std::string content; + content.append(str); + free(str); + auto resp = mRequest.post(mHost+SET_PACS_URL,content,mHeaders); + if (resp->httpCode() == 200){ + delete resp; + return RequestResult::Success(); + } + else{ + mErrorMessage = resp->getContent(); + delete resp; return RequestResult::Fail(mErrorMessage); } } diff --git a/src/recon/ReconClient.h b/src/recon/ReconClient.h index 4f41e26..01fe763 100644 --- a/src/recon/ReconClient.h +++ b/src/recon/ReconClient.h @@ -16,6 +16,7 @@ namespace Recon { RequestResult QueryReconID(const std::string& aScanID, std::string& aReconID); RequestResult QueryReconTask(const std::string& aReconID, TaskQueryResult& aTask); RequestResult QueryVersion(); + RequestResult SetPACSSetting(const PACSSetting& aSetting); private: std::string mVersionContent; diff --git a/thirdParty/Req/pub/include/Request.h b/thirdParty/Req/pub/include/Request.h index 136ea34..de5c5dd 100644 --- a/thirdParty/Req/pub/include/Request.h +++ b/thirdParty/Req/pub/include/Request.h @@ -15,9 +15,10 @@ namespace Req { Request &operator=(Request &&) = delete; Request &operator=(const Request &) = delete; ~Request(); + bool isValid(); void setClientCertificate(const std::string &cerPath, const std::string &keyPath); void setVerbose(bool verbose); - Response post(const std::string& url, const std::string &body = std::string(), + Response* post(const std::string& url, const std::string &body = std::string(), const std::unordered_map& headers = std::unordered_map()); @@ -27,6 +28,8 @@ namespace Req { std::string mCert; std::string mKey; bool mVerbose; + bool mValid; + }; } #endif // __REQUEST_H__ \ No newline at end of file diff --git a/thirdParty/Req/pub/include/Response.h b/thirdParty/Req/pub/include/Response.h index b9ccbe8..1a9c906 100644 --- a/thirdParty/Req/pub/include/Response.h +++ b/thirdParty/Req/pub/include/Response.h @@ -7,6 +7,7 @@ namespace Req { { public: Response(); + static Response* ErrorResponse(const std::string & content); Response(Response &&) = default; Response(const Response &) = default; Response &operator=(Response &&) = delete; @@ -15,9 +16,11 @@ namespace Req { long httpCode(); void setHttpCode(long code); std::string& getContent(); + bool isResponsed(); private: long mHttpCode = 404; std::string mContent; + bool mResponsed; }; }; #endif // __RESPONSE_H__ \ No newline at end of file diff --git a/thirdParty/Req/pub/lib/libReq.so b/thirdParty/Req/pub/lib/libReq.so index a8f36c0d856cd9439b8cd8575761f34782dd9563..b6cffa88073f61412ee697632d917fd46ae8776c 100644 GIT binary patch literal 20256 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 literal 20408 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