Mercurial > hg > orthanc
comparison OrthancServer/Plugins/Engine/OrthancPlugins.cpp @ 4484:64f06e7d5fc7
new abstraction IMemoryBuffer to avoid unnecessary copies of std::string buffers
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 28 Jan 2021 19:03:19 +0100 |
parents | a926f8995d0b |
children | fa2311f94d9f |
comparison
equal
deleted
inserted
replaced
4483:a926f8995d0b | 4484:64f06e7d5fc7 |
---|---|
57 #include "../../../OrthancFramework/Sources/Images/JpegWriter.h" | 57 #include "../../../OrthancFramework/Sources/Images/JpegWriter.h" |
58 #include "../../../OrthancFramework/Sources/Images/PngReader.h" | 58 #include "../../../OrthancFramework/Sources/Images/PngReader.h" |
59 #include "../../../OrthancFramework/Sources/Images/PngWriter.h" | 59 #include "../../../OrthancFramework/Sources/Images/PngWriter.h" |
60 #include "../../../OrthancFramework/Sources/Logging.h" | 60 #include "../../../OrthancFramework/Sources/Logging.h" |
61 #include "../../../OrthancFramework/Sources/Lua/LuaFunctionCall.h" | 61 #include "../../../OrthancFramework/Sources/Lua/LuaFunctionCall.h" |
62 #include "../../../OrthancFramework/Sources/MallocMemoryBuffer.h" | |
62 #include "../../../OrthancFramework/Sources/MetricsRegistry.h" | 63 #include "../../../OrthancFramework/Sources/MetricsRegistry.h" |
63 #include "../../../OrthancFramework/Sources/OrthancException.h" | 64 #include "../../../OrthancFramework/Sources/OrthancException.h" |
64 #include "../../../OrthancFramework/Sources/SerializationToolbox.h" | 65 #include "../../../OrthancFramework/Sources/SerializationToolbox.h" |
65 #include "../../../OrthancFramework/Sources/Toolbox.h" | 66 #include "../../../OrthancFramework/Sources/Toolbox.h" |
66 #include "../../Sources/OrthancConfiguration.h" | 67 #include "../../Sources/OrthancConfiguration.h" |
196 } | 197 } |
197 } | 198 } |
198 }; | 199 }; |
199 | 200 |
200 | 201 |
201 class MemoryBuffer64Raii : public boost::noncopyable | |
202 { | |
203 private: | |
204 OrthancPluginMemoryBuffer64 buffer_; | |
205 | |
206 public: | |
207 MemoryBuffer64Raii() | |
208 { | |
209 buffer_.size = 0; | |
210 buffer_.data = NULL; | |
211 } | |
212 | |
213 ~MemoryBuffer64Raii() | |
214 { | |
215 if (buffer_.size != 0) | |
216 { | |
217 free(buffer_.data); | |
218 } | |
219 } | |
220 | |
221 OrthancPluginMemoryBuffer64* GetObject() | |
222 { | |
223 return &buffer_; | |
224 } | |
225 | |
226 void ToString(std::string& target) const | |
227 { | |
228 if ((buffer_.data == NULL && buffer_.size != 0) || | |
229 (buffer_.data != NULL && buffer_.size == 0)) | |
230 { | |
231 throw OrthancException(ErrorCode_Plugin); | |
232 } | |
233 else | |
234 { | |
235 target.resize(buffer_.size); | |
236 | |
237 if (buffer_.size != 0) | |
238 { | |
239 memcpy(&target[0], buffer_.data, buffer_.size); | |
240 } | |
241 } | |
242 } | |
243 }; | |
244 | |
245 | |
246 class StorageAreaBase : public IStorageArea | 202 class StorageAreaBase : public IStorageArea |
247 { | 203 { |
248 private: | 204 private: |
249 OrthancPluginStorageCreate create_; | 205 OrthancPluginStorageCreate create_; |
250 OrthancPluginStorageRemove remove_; | 206 OrthancPluginStorageRemove remove_; |
326 { | 282 { |
327 throw OrthancException(ErrorCode_Plugin, "Storage area plugin doesn't implement the \"Read\" primitive"); | 283 throw OrthancException(ErrorCode_Plugin, "Storage area plugin doesn't implement the \"Read\" primitive"); |
328 } | 284 } |
329 } | 285 } |
330 | 286 |
331 virtual void Read(std::string& content, | 287 virtual IMemoryBuffer* Read(const std::string& uuid, |
332 const std::string& uuid, | 288 FileContentType type) ORTHANC_OVERRIDE |
333 FileContentType type) ORTHANC_OVERRIDE | 289 { |
334 { | 290 std::unique_ptr<MallocMemoryBuffer> result(new MallocMemoryBuffer); |
291 | |
335 void* buffer = NULL; | 292 void* buffer = NULL; |
336 int64_t size = 0; | 293 int64_t size = 0; |
337 | 294 |
338 OrthancPluginErrorCode error = read_ | 295 OrthancPluginErrorCode error = read_ |
339 (&buffer, &size, uuid.c_str(), Plugins::Convert(type)); | 296 (&buffer, &size, uuid.c_str(), Plugins::Convert(type)); |
340 | 297 |
341 if (error != OrthancPluginErrorCode_Success) | 298 if (error == OrthancPluginErrorCode_Success) |
299 { | |
300 result->Assign(buffer, size, free_); | |
301 return result.release(); | |
302 } | |
303 else | |
342 { | 304 { |
343 GetErrorDictionary().LogError(error, true); | 305 GetErrorDictionary().LogError(error, true); |
344 throw OrthancException(static_cast<ErrorCode>(error)); | 306 throw OrthancException(static_cast<ErrorCode>(error)); |
345 } | 307 } |
346 | |
347 try | |
348 { | |
349 content.resize(static_cast<size_t>(size)); | |
350 } | |
351 catch (...) | |
352 { | |
353 Free(buffer); | |
354 throw OrthancException(ErrorCode_NotEnoughMemory); | |
355 } | |
356 | |
357 if (size > 0) | |
358 { | |
359 memcpy(&content[0], buffer, static_cast<size_t>(size)); | |
360 } | |
361 | |
362 Free(buffer); | |
363 } | 308 } |
364 }; | 309 }; |
365 | 310 |
366 | 311 |
367 // New in Orthanc 1.9.0 | 312 // New in Orthanc 1.9.0 |
382 { | 327 { |
383 throw OrthancException(ErrorCode_Plugin, "Storage area plugin doesn't implement the \"ReadWhole\" primitive"); | 328 throw OrthancException(ErrorCode_Plugin, "Storage area plugin doesn't implement the \"ReadWhole\" primitive"); |
384 } | 329 } |
385 } | 330 } |
386 | 331 |
387 virtual void Read(std::string& content, | 332 virtual IMemoryBuffer* Read(const std::string& uuid, |
388 const std::string& uuid, | 333 FileContentType type) ORTHANC_OVERRIDE |
389 FileContentType type) ORTHANC_OVERRIDE | 334 { |
390 { | 335 std::unique_ptr<MallocMemoryBuffer> result(new MallocMemoryBuffer); |
391 MemoryBuffer64Raii buffer; | 336 |
337 OrthancPluginMemoryBuffer64 buffer; | |
392 | 338 |
393 OrthancPluginErrorCode error = readWhole_ | 339 OrthancPluginErrorCode error = readWhole_(&buffer, uuid.c_str(), Plugins::Convert(type)); |
394 (buffer.GetObject(), uuid.c_str(), Plugins::Convert(type)); | 340 |
395 | 341 if (error == OrthancPluginErrorCode_Success) |
396 if (error != OrthancPluginErrorCode_Success) | 342 { |
343 result->Assign(buffer.data, buffer.size, ::free); | |
344 return result.release(); | |
345 } | |
346 else | |
397 { | 347 { |
398 GetErrorDictionary().LogError(error, true); | 348 GetErrorDictionary().LogError(error, true); |
399 throw OrthancException(static_cast<ErrorCode>(error)); | 349 throw OrthancException(static_cast<ErrorCode>(error)); |
400 } | 350 } |
401 | |
402 buffer.ToString(content); | |
403 } | 351 } |
404 }; | 352 }; |
405 | 353 |
406 | 354 |
407 class StorageAreaFactory : public boost::noncopyable | 355 class StorageAreaFactory : public boost::noncopyable |
4194 case _OrthancPluginService_StorageAreaRead: | 4142 case _OrthancPluginService_StorageAreaRead: |
4195 { | 4143 { |
4196 const _OrthancPluginStorageAreaRead& p = | 4144 const _OrthancPluginStorageAreaRead& p = |
4197 *reinterpret_cast<const _OrthancPluginStorageAreaRead*>(parameters); | 4145 *reinterpret_cast<const _OrthancPluginStorageAreaRead*>(parameters); |
4198 IStorageArea& storage = *reinterpret_cast<IStorageArea*>(p.storageArea); | 4146 IStorageArea& storage = *reinterpret_cast<IStorageArea*>(p.storageArea); |
4199 std::string content; | 4147 std::unique_ptr<IMemoryBuffer> content(storage.Read(p.uuid, Plugins::Convert(p.type))); |
4200 storage.Read(content, p.uuid, Plugins::Convert(p.type)); | 4148 CopyToMemoryBuffer(*p.target, content->GetData(), content->GetSize()); |
4201 CopyToMemoryBuffer(*p.target, content); | |
4202 return true; | 4149 return true; |
4203 } | 4150 } |
4204 | 4151 |
4205 case _OrthancPluginService_StorageAreaRemove: | 4152 case _OrthancPluginService_StorageAreaRemove: |
4206 { | 4153 { |