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 }