Mercurial > hg > orthanc
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) |