# HG changeset patch # User Sebastien Jodogne # Date 1611849580 -3600 # Node ID a926f8995d0b6c3c60e261aed9ad60475069f767 # Parent 8efeaba1b7f995c72899e3e5a72779418c39f583 sample for OrthancPluginRegisterStorageArea2() diff -r 8efeaba1b7f9 -r a926f8995d0b OrthancServer/Plugins/Engine/OrthancPlugins.cpp --- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Thu Jan 28 15:54:30 2021 +0100 +++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Thu Jan 28 16:59:40 2021 +0100 @@ -264,6 +264,11 @@ remove_(remove), errorDictionary_(errorDictionary) { + if (create_ == NULL || + remove_ == NULL) + { + throw OrthancException(ErrorCode_Plugin, "Storage area plugin doesn't implement all the required primitives"); + } } virtual void Create(const std::string& uuid, @@ -317,6 +322,10 @@ read_(callbacks.read), free_(callbacks.free) { + if (read_ == NULL) + { + throw OrthancException(ErrorCode_Plugin, "Storage area plugin doesn't implement the \"Read\" primitive"); + } } virtual void Read(std::string& content, @@ -369,6 +378,10 @@ readWhole_(callbacks.readWhole), readRange_(callbacks.readRange) { + if (readWhole_ == NULL) + { + throw OrthancException(ErrorCode_Plugin, "Storage area plugin doesn't implement the \"ReadWhole\" primitive"); + } } virtual void Read(std::string& content, diff -r 8efeaba1b7f9 -r a926f8995d0b OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h --- a/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Thu Jan 28 15:54:30 2021 +0100 +++ b/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Thu Jan 28 16:59:40 2021 +0100 @@ -1274,12 +1274,12 @@ * reads a portion of a file from the storage area. Orthanc * indicates the start position and the length of the range. * - * @param target Memory buffer where to store the content of the range. It must be allocated by the - * plugin using OrthancPluginCreateMemoryBuffer64(). The core of Orthanc will free it. + * @param target Memory buffer where to store the content of the range. + * The memory buffer is allocated and freed by Orthanc. The length of the range + * of interest corresponds to the size of this buffer. * @param uuid The UUID of the file of interest. * @param type The content type corresponding to this file. * @param rangeStart Start position of the requested range in the file. - * @param rangeSize Length of the range of interest. * @return 0 if success, other value if error. * @ingroup Callbacks **/ @@ -1287,8 +1287,7 @@ OrthancPluginMemoryBuffer64* target, const char* uuid, OrthancPluginContentType type, - uint64_t rangeStart, - uint64_t rangeSize); + uint64_t rangeStart); diff -r 8efeaba1b7f9 -r a926f8995d0b OrthancServer/Plugins/Samples/StorageArea/Plugin.cpp --- a/OrthancServer/Plugins/Samples/StorageArea/Plugin.cpp Thu Jan 28 15:54:30 2021 +0100 +++ b/OrthancServer/Plugins/Samples/StorageArea/Plugin.cpp Thu Jan 28 16:59:40 2021 +0100 @@ -25,6 +25,10 @@ #include #include + +#define USE_LEGACY_API 0 + + static OrthancPluginContext* context = NULL; @@ -34,6 +38,47 @@ } +static bool ReadFile(std::string& content, + const std::string& path) +{ + FILE* fp = fopen(path.c_str(), "rb"); + if (!fp) + { + return false; + } + + if (fseek(fp, 0, SEEK_END) < 0) + { + fclose(fp); + return false; + } + + long size = ftell(fp); + + if (fseek(fp, 0, SEEK_SET) < 0) + { + fclose(fp); + return false; + } + else + { + content.resize(size); + + if (size != 0) + { + bool success = (fread(&content[0], size, 1, fp) == 1); + fclose(fp); + return success; + } + else + { + fclose(fp); + return true; + } + } +} + + static OrthancPluginErrorCode StorageCreate(const char* uuid, const void* content, int64_t size, @@ -54,53 +99,108 @@ } +#if USE_LEGACY_API == 1 static OrthancPluginErrorCode StorageRead(void** content, int64_t* size, const char* uuid, OrthancPluginContentType type) { - std::string path = GetPath(uuid); + const std::string path = GetPath(uuid); + + std::string s; + if (ReadFile(s, path)) + { + *size = s.size(); - FILE* fp = fopen(path.c_str(), "rb"); - if (!fp) + if (s.size() == 0) + { + *content = NULL; + } + else + { + *content = malloc(s.size()); + if (*content == NULL) + { + return OrthancPluginErrorCode_StorageAreaPlugin; + } + + if (!s.empty()) + { + memcpy(*content, s.c_str(), s.size()); + } + } + + return OrthancPluginErrorCode_Success; + } + else { return OrthancPluginErrorCode_StorageAreaPlugin; } +} - if (fseek(fp, 0, SEEK_END) < 0) - { - fclose(fp); - return OrthancPluginErrorCode_StorageAreaPlugin; - } +#else - *size = ftell(fp); +static OrthancPluginErrorCode StorageReadWhole(OrthancPluginMemoryBuffer64* target, + const char* uuid, + OrthancPluginContentType type) +{ + const std::string path = GetPath(uuid); - if (fseek(fp, 0, SEEK_SET) < 0) + std::string s; + if (ReadFile(s, path)) { - fclose(fp); - return OrthancPluginErrorCode_StorageAreaPlugin; - } + if (OrthancPluginCreateMemoryBuffer64(context, target, s.size()) != OrthancPluginErrorCode_Success) + { + return OrthancPluginErrorCode_NotEnoughMemory; + } - bool ok = true; + if (!s.empty()) + { + memcpy(target->data, s.c_str(), s.size()); + } - if (*size == 0) - { - *content = NULL; + return OrthancPluginErrorCode_Success; } else { - *content = malloc(*size); - if (*content == NULL || - fread(*content, *size, 1, fp) != 1) + return OrthancPluginErrorCode_StorageAreaPlugin; + } +} + +static OrthancPluginErrorCode StorageReadRange(OrthancPluginMemoryBuffer64* target, + const char* uuid, + OrthancPluginContentType type, + uint64_t rangeStart) +{ + const size_t rangeSize = target->size; // The buffer is allocated by Orthanc + const std::string path = GetPath(uuid); + + std::string s; + + if (rangeSize == 0) + { + return OrthancPluginErrorCode_Success; + } + else if (ReadFile(s, path)) + { + if (rangeStart + rangeSize > s.size()) { - ok = false; + return OrthancPluginErrorCode_BadRange; } - } + else + { + memcpy(target->data, &s[rangeStart], rangeSize); + } - fclose(fp); + return OrthancPluginErrorCode_Success; + } + else + { + return OrthancPluginErrorCode_StorageAreaPlugin; + } +} - return ok ? OrthancPluginErrorCode_Success : OrthancPluginErrorCode_StorageAreaPlugin; -} +#endif static OrthancPluginErrorCode StorageRemove(const char* uuid, @@ -139,7 +239,11 @@ return -1; } +#if USE_LEGACY_API == 1 OrthancPluginRegisterStorageArea(context, StorageCreate, StorageRead, StorageRemove); +#else + OrthancPluginRegisterStorageArea2(context, StorageCreate, StorageReadWhole, StorageReadRange, StorageRemove); +#endif return 0; }