comparison OrthancServer/ParsedDicomFile.cpp @ 1519:8bd0d897763f

refactoring: IHttpStreamAnswer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 11 Aug 2015 13:15:16 +0200
parents f967bdf8534e
children 4a503a8c7749
comparison
equal deleted inserted replaced
1518:eb46cc06389a 1519:8bd0d897763f
253 return 1; 253 return 1;
254 } 254 }
255 } 255 }
256 256
257 257
258 static void AnswerDicomField(RestApiOutput& output, 258 namespace
259 DcmElement& element, 259 {
260 E_TransferSyntax transferSyntax) 260 class DicomFieldStream : public IHttpStreamAnswer
261 { 261 {
262 // This element is nor a sequence, neither a pixel-data 262 private:
263 std::string buffer; 263 DcmElement& element_;
264 buffer.resize(65536); 264 uint32_t length_;
265 Uint32 length = element.getLength(transferSyntax); 265 uint32_t offset_;
266 Uint32 offset = 0; 266 std::string chunk_;
267 267 size_t chunkSize_;
268 output.GetLowLevelOutput().SetContentType(CONTENT_TYPE_OCTET_STREAM); 268
269 output.GetLowLevelOutput().SetContentLength(length); 269 public:
270 270 DicomFieldStream(DcmElement& element,
271 while (offset < length) 271 E_TransferSyntax transferSyntax) :
272 { 272 element_(element),
273 Uint32 nbytes; 273 length_(element.getLength(transferSyntax)),
274 if (length - offset < buffer.size()) 274 offset_(0)
275 { 275 {
276 nbytes = length - offset; 276 static const size_t CHUNK_SIZE = 64 * 1024; // Use a 64KB chunk
277 } 277 chunk_.resize(CHUNK_SIZE);
278 else 278 }
279 { 279
280 nbytes = buffer.size(); 280 virtual HttpCompression GetHttpCompression(bool /*gzipAllowed*/,
281 } 281 bool /*deflateAllowed*/)
282 282 {
283 OFCondition cond = element.getPartialValue(&buffer[0], offset, nbytes); 283 // No support for compression
284 284 return HttpCompression_None;
285 if (cond.good()) 285 }
286 { 286
287 output.GetLowLevelOutput().SendBody(&buffer[0], nbytes); 287 virtual bool HasContentFilename(std::string& filename)
288 offset += nbytes; 288 {
289 } 289 return false;
290 else 290 }
291 { 291
292 LOG(ERROR) << "Error while sending a DICOM field: " << cond.text(); 292 virtual std::string GetContentType()
293 return; 293 {
294 } 294 return "";
295 } 295 }
296 296
297 output.MarkLowLevelOutputDone(); 297 virtual uint64_t GetContentLength()
298 {
299 return length_;
300 }
301
302 virtual bool ReadNextChunk()
303 {
304 assert(offset_ < length_);
305
306 if (offset_ == length_)
307 {
308 return false;
309 }
310 else
311 {
312 if (length_ - offset_ < chunk_.size())
313 {
314 chunkSize_ = length_ - offset_;
315 }
316 else
317 {
318 chunkSize_ = chunk_.size();
319 }
320
321 OFCondition cond = element_.getPartialValue(&chunk_[0], offset_, chunkSize_);
322
323 offset_ += chunkSize_;
324
325 if (!cond.good())
326 {
327 LOG(ERROR) << "Error while sending a DICOM field: " << cond.text();
328 throw OrthancException(ErrorCode_InternalError);
329 }
330
331 return true;
332 }
333 }
334
335 virtual const char *GetChunkContent()
336 {
337 return chunk_.c_str();
338 }
339
340 virtual size_t GetChunkSize()
341 {
342 return chunkSize_;
343 }
344 };
298 } 345 }
299 346
300 347
301 static bool AnswerPixelData(RestApiOutput& output, 348 static bool AnswerPixelData(RestApiOutput& output,
302 DcmItem& dicom, 349 DcmItem& dicom,
363 } 410 }
364 else 411 else
365 { 412 {
366 // This is the case for raw, uncompressed image buffers 413 // This is the case for raw, uncompressed image buffers
367 assert(*blockUri == "0"); 414 assert(*blockUri == "0");
368 AnswerDicomField(output, *element, transferSyntax); 415 DicomFieldStream stream(*element, transferSyntax);
416 output.AnswerStream(stream);
369 } 417 }
370 } 418 }
371 } 419 }
372 catch (boost::bad_lexical_cast&) 420 catch (boost::bad_lexical_cast&)
373 { 421 {
404 if (dicom.findAndGetElement(k, element).good() && 452 if (dicom.findAndGetElement(k, element).good() &&
405 element != NULL && 453 element != NULL &&
406 //element->getVR() != EVR_UNKNOWN && // This would forbid private tags 454 //element->getVR() != EVR_UNKNOWN && // This would forbid private tags
407 element->getVR() != EVR_SQ) 455 element->getVR() != EVR_SQ)
408 { 456 {
409 AnswerDicomField(output, *element, transferSyntax); 457 DicomFieldStream stream(*element, transferSyntax);
458 output.AnswerStream(stream);
410 } 459 }
411 } 460 }
412 461
413 void ParsedDicomFile::SendPathValue(RestApiOutput& output, 462 void ParsedDicomFile::SendPathValue(RestApiOutput& output,
414 const UriComponents& uri) 463 const UriComponents& uri)