1 /*
2  *
3  *  Copyright (C) 2002-2017, OFFIS e.V.
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation were developed by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *
14  *  Module:  dcmdata
15  *
16  *  Author:  Marco Eichelberg
17  *
18  *  Purpose: DcmOutputBufferStream and related classes,
19  *    implements output to blocks of memory as needed in the dcmnet module.
20  *
21  */
22 
23 #include "dcmtk/config/osconfig.h"
24 #include "dcmtk/dcmdata/dcostrmb.h"
25 #include "dcmtk/dcmdata/dcerror.h"
26 
27 
DcmBufferConsumer(void * buf,offile_off_t bufLen)28 DcmBufferConsumer::DcmBufferConsumer(void *buf, offile_off_t bufLen)
29 : DcmConsumer()
30 , buffer_(OFstatic_cast(unsigned char *, buf))
31 , bufSize_(bufLen)
32 , filled_(0)
33 , status_(EC_Normal)
34 {
35   if (buffer_ == NULL) status_ = EC_IllegalCall;
36 }
37 
~DcmBufferConsumer()38 DcmBufferConsumer::~DcmBufferConsumer()
39 {
40 }
41 
good() const42 OFBool DcmBufferConsumer::good() const
43 {
44   return status_.good();
45 }
46 
status() const47 OFCondition DcmBufferConsumer::status() const
48 {
49   return status_;
50 }
51 
isFlushed() const52 OFBool DcmBufferConsumer::isFlushed() const
53 {
54   return (filled_ == 0);
55 }
56 
avail() const57 offile_off_t DcmBufferConsumer::avail() const
58 {
59   return bufSize_ - filled_;
60 }
61 
write(const void * buf,offile_off_t buflen)62 offile_off_t DcmBufferConsumer::write(const void *buf, offile_off_t buflen)
63 {
64   offile_off_t result = 0;
65   if (status_.good() && buf && buflen)
66   {
67     result = bufSize_ - filled_;
68     if (result > buflen) result = buflen;
69     memcpy(buffer_+ filled_, buf, OFstatic_cast(size_t, result));
70     filled_ += result;
71   }
72   return result;
73 }
74 
flush()75 void DcmBufferConsumer::flush()
76 {
77   // nothing to flush
78 }
79 
flushBuffer(void * & buffer,offile_off_t & length)80 void DcmBufferConsumer::flushBuffer(void *& buffer, offile_off_t& length)
81 {
82   buffer = buffer_;
83   length = filled_;
84   filled_ = 0;
85 }
86 
filled()87 offile_off_t DcmBufferConsumer::filled()
88 {
89   return filled_;
90 }
91 
92 /* ======================================================================= */
93 
DcmOutputBufferStream(void * buf,offile_off_t bufLen)94 DcmOutputBufferStream::DcmOutputBufferStream(void *buf, offile_off_t bufLen)
95 : DcmOutputStream(&consumer_) // safe because DcmOutputStream only stores pointer
96 , consumer_(buf, bufLen)
97 {
98 }
99 
~DcmOutputBufferStream()100 DcmOutputBufferStream::~DcmOutputBufferStream()
101 {
102 #ifdef DEBUG
103   if (! isFlushed())
104   {
105     DCMDATA_WARN("DcmOutputBufferStream: Closing unflushed DcmOutputBufferStream, loss of data!");
106   }
107 #endif
108 }
109 
flushBuffer(void * & buffer,offile_off_t & length)110 void DcmOutputBufferStream::flushBuffer(void *& buffer, offile_off_t& length)
111 {
112   consumer_.flushBuffer(buffer, length);
113 }
114 
filled()115 offile_off_t DcmOutputBufferStream::filled()
116 {
117   return consumer_.filled();
118 }
119