Mercurial > hg > orthanc
comparison Plugins/Samples/Common/OrthancPluginCppWrapper.h @ 3414:b9cba6a91780
simplification
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 11 Jun 2019 19:44:10 +0200 |
parents | f09bfdea3fc3 |
children | 2a821deece64 |
comparison
equal
deleted
inserted
replaced
3413:f09bfdea3fc3 | 3414:b9cba6a91780 |
---|---|
55 (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER == minor && \ | 55 (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER == minor && \ |
56 ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER >= revision)))) | 56 ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER >= revision)))) |
57 #endif | 57 #endif |
58 | 58 |
59 | 59 |
60 #if !defined(ORTHANC_FRAMEWORK_VERSION_IS_ABOVE) | |
61 #define ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(major, minor, revision) \ | |
62 (defined(HAS_ORTHANC_FRAMEWORK) && \ | |
63 defined(ORTHANC_FRAMEWORK_VERSION_MAJOR) && \ | |
64 defined(ORTHANC_FRAMEWORK_VERSION_MINOR) && \ | |
65 defined(ORTHANC_FRAMEWORK_VERSION_REVISION) && \ | |
66 HAS_ORTHANC_FRAMEWORK == 1 && \ | |
67 ORTHANC_FRAMEWORK_VERSION_MAJOR > major || \ | |
68 (ORTHANC_FRAMEWORK_VERSION_MAJOR == major && \ | |
69 (ORTHANC_FRAMEWORK_VERSION_MINOR > minor || \ | |
70 (ORTHANC_FRAMEWORK_VERSION_MINOR == minor && \ | |
71 ORTHANC_FRAMEWORK_VERSION_REVISION >= revision)))) | |
72 #endif | |
73 | |
74 | |
75 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 2, 0) | 60 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 2, 0) |
76 // The "OrthancPluginFindMatcher()" primitive was introduced in Orthanc 1.2.0 | 61 // The "OrthancPluginFindMatcher()" primitive was introduced in Orthanc 1.2.0 |
77 # define HAS_ORTHANC_PLUGIN_FIND_MATCHER 1 | 62 # define HAS_ORTHANC_PLUGIN_FIND_MATCHER 1 |
78 #else | 63 #else |
79 # define HAS_ORTHANC_PLUGIN_FIND_MATCHER 0 | 64 # define HAS_ORTHANC_PLUGIN_FIND_MATCHER 0 |
111 #else | 96 #else |
112 # define HAS_ORTHANC_PLUGIN_CHUNKED_HTTP_CLIENT 0 | 97 # define HAS_ORTHANC_PLUGIN_CHUNKED_HTTP_CLIENT 0 |
113 #endif | 98 #endif |
114 | 99 |
115 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 7) | 100 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 7) |
116 # define HAS_ORTHANC_PLUGIN_HTTP_MULTIPART_SERVER 1 | 101 # define HAS_ORTHANC_PLUGIN_CHUNKED_HTTP_SERVER 1 |
117 #else | 102 #else |
118 # define HAS_ORTHANC_PLUGIN_HTTP_MULTIPART_SERVER 0 | 103 # define HAS_ORTHANC_PLUGIN_CHUNKED_HTTP_SERVER 0 |
119 #endif | 104 #endif |
120 | 105 |
121 | 106 |
122 | 107 |
123 namespace OrthancPlugins | 108 namespace OrthancPlugins |
124 { | 109 { |
125 typedef void (*RestCallback) (OrthancPluginRestOutput* output, | 110 typedef void (*RestCallback) (OrthancPluginRestOutput* output, |
126 const char* url, | 111 const char* url, |
127 const OrthancPluginHttpRequest* request); | 112 const OrthancPluginHttpRequest* request); |
128 | |
129 | 113 |
130 void SetGlobalContext(OrthancPluginContext* context); | 114 void SetGlobalContext(OrthancPluginContext* context); |
131 | 115 |
132 bool HasGlobalContext(); | 116 bool HasGlobalContext(); |
133 | 117 |
934 }; | 918 }; |
935 #endif | 919 #endif |
936 | 920 |
937 | 921 |
938 | 922 |
939 class MultipartRestCallback : public boost::noncopyable | 923 class IChunkedRequestReader : public boost::noncopyable |
940 { | 924 { |
941 public: | 925 public: |
942 class IHandler : public boost::noncopyable | 926 virtual ~IChunkedRequestReader() |
943 { | 927 { |
944 public: | 928 } |
945 virtual ~IHandler() | 929 |
946 { | 930 virtual void AddChunk(const void* data, |
947 } | 931 size_t size) = 0; |
948 | 932 |
949 virtual OrthancPluginErrorCode AddPart(const std::string& contentType, | 933 virtual void Execute(OrthancPluginRestOutput* output) = 0; |
950 const std::map<std::string, std::string>& headers, | |
951 const void* data, | |
952 size_t size) = 0; | |
953 | |
954 virtual OrthancPluginErrorCode Execute(OrthancPluginRestOutput* output) = 0; | |
955 }; | |
956 | |
957 | |
958 virtual ~MultipartRestCallback() | |
959 { | |
960 } | |
961 | |
962 virtual IHandler* CreateHandler(OrthancPluginHttpMethod method, | |
963 const std::string& url, | |
964 const std::string& contentType, | |
965 const std::string& subType, // Possibly empty | |
966 const std::vector<std::string>& groups, | |
967 const std::map<std::string, std::string>& headers) = 0; | |
968 | |
969 void Register(const std::string& regularExpression); | |
970 }; | 934 }; |
935 | |
936 | |
937 typedef IChunkedRequestReader* (*ChunkedRestCallback) (OrthancPluginRestOutput* output, | |
938 const char* url, | |
939 const OrthancPluginHttpRequest* request); | |
940 | |
941 | |
942 namespace Internals | |
943 { | |
944 #if HAS_ORTHANC_PLUGIN_CHUNKED_HTTP_SERVER == 1 | |
945 template <ChunkedRestCallback Callback> | |
946 OrthancPluginErrorCode Protect(OrthancPluginRestOutput* output, | |
947 OrthancPluginServerChunkedRequestReader** reader, | |
948 const char* url, | |
949 const OrthancPluginHttpRequest* request) | |
950 { | |
951 try | |
952 { | |
953 switch (request->method) | |
954 { | |
955 case OrthancPluginHttpMethod_Get: | |
956 case OrthancPluginHttpMethod_Delete: | |
957 if (output == NULL || | |
958 reader != NULL || | |
959 Callback(output, url, request) != NULL) | |
960 { | |
961 return OrthancPluginErrorCode_InternalError; | |
962 } | |
963 | |
964 return OrthancPluginErrorCode_Success; | |
965 | |
966 case OrthancPluginHttpMethod_Post: | |
967 case OrthancPluginHttpMethod_Put: | |
968 if (output != NULL || | |
969 reader == NULL) | |
970 { | |
971 return OrthancPluginErrorCode_InternalError; | |
972 } | |
973 else | |
974 { | |
975 *reader = reinterpret_cast<OrthancPluginServerChunkedRequestReader*>(Callback(NULL, url, request)); | |
976 if (*reader == NULL) | |
977 { | |
978 return OrthancPluginErrorCode_Plugin; | |
979 } | |
980 } | |
981 | |
982 return OrthancPluginErrorCode_Success; | |
983 | |
984 default: | |
985 return OrthancPluginErrorCode_InternalError; | |
986 } | |
987 } | |
988 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) | |
989 { | |
990 #if HAS_ORTHANC_EXCEPTION == 1 && HAS_ORTHANC_PLUGIN_EXCEPTION_DETAILS == 1 | |
991 if (HasGlobalContext() && | |
992 e.HasDetails()) | |
993 { | |
994 // The "false" instructs Orthanc not to log the detailed | |
995 // error message. This is to avoid duplicating the details, | |
996 // because "OrthancException" already does it on construction. | |
997 OrthancPluginSetHttpErrorDetails | |
998 (GetGlobalContext(), output, e.GetDetails(), false); | |
999 } | |
1000 #endif | |
1001 | |
1002 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); | |
1003 } | |
1004 catch (boost::bad_lexical_cast&) | |
1005 { | |
1006 return OrthancPluginErrorCode_BadFileFormat; | |
1007 } | |
1008 catch (...) | |
1009 { | |
1010 return OrthancPluginErrorCode_Plugin; | |
1011 } | |
1012 } | |
1013 | |
1014 static OrthancPluginErrorCode ChunkedRequestReaderAddChunk( | |
1015 OrthancPluginServerChunkedRequestReader* reader, | |
1016 const void* data, | |
1017 uint32_t size) | |
1018 { | |
1019 try | |
1020 { | |
1021 if (reader == NULL) | |
1022 { | |
1023 return OrthancPluginErrorCode_InternalError; | |
1024 } | |
1025 | |
1026 reinterpret_cast<IChunkedRequestReader*>(reader)->AddChunk(data, size); | |
1027 return OrthancPluginErrorCode_Success; | |
1028 } | |
1029 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) | |
1030 { | |
1031 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); | |
1032 } | |
1033 catch (boost::bad_lexical_cast&) | |
1034 { | |
1035 return OrthancPluginErrorCode_BadFileFormat; | |
1036 } | |
1037 catch (...) | |
1038 { | |
1039 return OrthancPluginErrorCode_Plugin; | |
1040 } | |
1041 } | |
1042 | |
1043 static OrthancPluginErrorCode ChunkedRequestReaderExecute( | |
1044 OrthancPluginServerChunkedRequestReader* reader, | |
1045 OrthancPluginRestOutput* output) | |
1046 { | |
1047 try | |
1048 { | |
1049 if (reader == NULL) | |
1050 { | |
1051 return OrthancPluginErrorCode_InternalError; | |
1052 } | |
1053 | |
1054 reinterpret_cast<IChunkedRequestReader*>(reader)->Execute(output); | |
1055 return OrthancPluginErrorCode_Success; | |
1056 } | |
1057 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) | |
1058 { | |
1059 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); | |
1060 } | |
1061 catch (boost::bad_lexical_cast&) | |
1062 { | |
1063 return OrthancPluginErrorCode_BadFileFormat; | |
1064 } | |
1065 catch (...) | |
1066 { | |
1067 return OrthancPluginErrorCode_Plugin; | |
1068 } | |
1069 } | |
1070 | |
1071 static void ChunkedRequestReaderFinalize( | |
1072 OrthancPluginServerChunkedRequestReader* reader) | |
1073 { | |
1074 if (reader != NULL) | |
1075 { | |
1076 delete reinterpret_cast<IChunkedRequestReader*>(reader); | |
1077 } | |
1078 } | |
1079 | |
1080 #else | |
1081 | |
1082 template <ChunkedRestCallback Callback> | |
1083 void ChunkedRestCompatibility(OrthancPluginRestOutput* output, | |
1084 const char* url, | |
1085 const OrthancPluginHttpRequest* request) | |
1086 { | |
1087 switch (request->method) | |
1088 { | |
1089 case OrthancPluginHttpMethod_Get: | |
1090 case OrthancPluginHttpMethod_Delete: | |
1091 if (Callback(output, url, request) != NULL) | |
1092 { | |
1093 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
1094 } | |
1095 else | |
1096 { | |
1097 return; | |
1098 } | |
1099 | |
1100 case OrthancPluginHttpMethod_Post: | |
1101 case OrthancPluginHttpMethod_Put: | |
1102 { | |
1103 std::auto_ptr<IChunkedRequestReader> reader(Callback(NULL, url, request)); | |
1104 if (reader.get() == NULL) | |
1105 { | |
1106 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
1107 } | |
1108 else | |
1109 { | |
1110 if (request->bodySize != 0) | |
1111 { | |
1112 reader->AddChunk(request->body, request->bodySize); | |
1113 } | |
1114 reader->Execute(output); | |
1115 } | |
1116 return; | |
1117 } | |
1118 | |
1119 default: | |
1120 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
1121 } | |
1122 } | |
1123 #endif | |
1124 } | |
1125 | |
1126 | |
1127 template <ChunkedRestCallback Callback> | |
1128 void RegisterChunkedRestCallback(const std::string& uri) | |
1129 { | |
1130 #if HAS_ORTHANC_PLUGIN_CHUNKED_HTTP_SERVER == 1 | |
1131 OrthancPluginRegisterChunkedRestCallback( | |
1132 GetGlobalContext(), uri.c_str(), Internals::Protect<Callback>, | |
1133 Internals::ChunkedRequestReaderAddChunk, | |
1134 Internals::ChunkedRequestReaderExecute, | |
1135 Internals::ChunkedRequestReaderFinalize); | |
1136 #else | |
1137 LogWarning("Performance warning: The plugin was compiled against a pre-1.5.7 version " | |
1138 "of the Orthanc SDK. Multipart transfers will be entirely stored in RAM."); | |
1139 OrthancPluginRegisterRestCallback( | |
1140 GetGlobalContext(), uri.c_str(), | |
1141 Internals::Protect< Internals::ChunkedRestCompatibility<Callback> >); | |
1142 #endif | |
1143 } | |
971 } | 1144 } |