1 /*
2  *
3  *  Copyright (C) 1994-2002, OFFIS
4  *
5  *  This software and supporting documentation were developed by
6  *
7  *    Kuratorium OFFIS e.V.
8  *    Healthcare Information and Communication Systems
9  *    Escherweg 2
10  *    D-26121 Oldenburg, Germany
11  *
12  *  THIS SOFTWARE IS MADE AVAILABLE,  AS IS,  AND OFFIS MAKES NO  WARRANTY
13  *  REGARDING  THE  SOFTWARE,  ITS  PERFORMANCE,  ITS  MERCHANTABILITY  OR
14  *  FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES  OR
15  *  ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY AND
16  *  PERFORMANCE OF THE SOFTWARE IS WITH THE USER.
17  *
18  *  Module:  dcmdata
19  *
20  *  Author:  Marco Eichelberg
21  *
22  *  Purpose: DcmInputFileStream and related classes,
23  *    implements streamed input from files.
24  *
25  */
26 
27 #ifndef DCISTRMF_H
28 #define DCISTRMF_H
29 
30 #include "osconfig.h"
31 #include "dcistrma.h"
32 
33 #define INCLUDE_CSTDIO
34 #include "ofstdinc.h"
35 
36 
37 /** producer class that reads data from a plain file.
38  */
39 class DcmFileProducer: public DcmProducer
40 {
41 public:
42   /** constructor
43    *  @param filename name of file to be opened, must not be NULL or empty
44    *  @param offset byte offset to skip from the start of file
45    */
46   DcmFileProducer(const char *filename, Uint32 offset = 0);
47 
48   /// destructor
49   virtual ~DcmFileProducer();
50 
51   /** returns the status of the producer. Unless the status is good,
52    *  the producer will not permit any operation.
53    *  @return status, true if good
54    */
55   virtual OFBool good() const;
56 
57   /** returns the status of the producer as an OFCondition object.
58    *  Unless the status is good, the producer will not permit any operation.
59    *  @return status, EC_Normal if good
60    */
61   virtual OFCondition status() const;
62 
63   /** returns true if the producer is at the end of stream.
64    *  @return true if end of stream, false otherwise
65    */
66   virtual OFBool eos() const;
67 
68   /** returns the minimum number of bytes that can be read with the
69    *  next call to read(). The DcmObject read methods rely on avail
70    *  to return a value > 0 if there is no I/O suspension since certain
71    *  data such as tag and length are only read "en bloc", i.e. all
72    *  or nothing.
73    *  @return minimum of data available in producer
74    */
75   virtual Uint32 avail() const;
76 
77   /** reads as many bytes as possible into the given block.
78    *  @param buf pointer to memory block, must not be NULL
79    *  @param buflen length of memory block
80    *  @return number of bytes actually read.
81    */
82   virtual Uint32 read(void *buf, Uint32 buflen);
83 
84   /** skips over the given number of bytes (or less)
85    *  @param skiplen number of bytes to skip
86    *  @return number of bytes actually skipped.
87    */
88   virtual Uint32 skip(Uint32 skiplen);
89 
90   /** resets the stream to the position by the given number of bytes.
91    *  @param num number of bytes to putback. If the putback operation
92    *    fails, the producer status becomes bad.
93    */
94   virtual void putback(Uint32 num);
95 
96 private:
97 
98   /// private unimplemented copy constructor
99   DcmFileProducer(const DcmFileProducer&);
100 
101   /// private unimplemented copy assignment operator
102   DcmFileProducer& operator=(const DcmFileProducer&);
103 
104   /// the file we're actually reading from
105   FILE *file_;
106 
107   /// status
108   OFCondition status_;
109 
110   /// number of bytes in file
111   Uint32 size_;
112 };
113 
114 
115 /** input stream factory for plain files
116  */
117 class DcmInputFileStreamFactory: public DcmInputStreamFactory
118 {
119 public:
120 
121   /** constructor
122    *  @param filename name of file to be opened, must not be NULL or empty
123    *  @param offset byte offset to skip from the start of file
124    */
125   DcmInputFileStreamFactory(const char *filename, Uint32 offset);
126 
127   /// copy constructor
128   DcmInputFileStreamFactory(const DcmInputFileStreamFactory &arg);
129 
130   /// destructor
131   virtual ~DcmInputFileStreamFactory();
132 
133   /** create a new input stream object
134    *  @return pointer to new input stream object
135    */
136   virtual DcmInputStream *create() const;
137 
138   /** returns a pointer to a copy of this object
139    */
clone()140   virtual DcmInputStreamFactory *clone() const
141   {
142     return new DcmInputFileStreamFactory(*this);
143   }
144 
145 private:
146 
147 
148   /// private unimplemented copy assignment operator
149   DcmInputFileStreamFactory& operator=(const DcmInputFileStreamFactory&);
150 
151   /// filename
152   OFString filename_;
153 
154   /// offset in file
155   Uint32 offset_;
156 
157 };
158 
159 
160 /** input stream that reads from a plain file
161  */
162 class DcmInputFileStream: public DcmInputStream
163 {
164 public:
165   /** constructor
166    *  @param filename name of file to be opened, must not be NULL or empty
167    *  @param offset byte offset to skip from the start of file
168    */
169   DcmInputFileStream(const char *filename, Uint32 offset = 0);
170 
171   /// destructor
172   virtual ~DcmInputFileStream();
173 
174   /** creates a new factory object for the current stream
175    *  and stream position.  When activated, the factory will be
176    *  able to create new DcmInputStream delivering the same
177    *  data as the current stream.  Used to defer loading of
178    *  value fields until accessed.
179    *  If no factory object can be created (e.g. because the
180    *  stream is not seekable), returns NULL.
181    *  @return pointer to new factory object if successful, NULL otherwise.
182    */
183   virtual DcmInputStreamFactory *newFactory() const;
184 
185 private:
186 
187   /// private unimplemented copy constructor
188   DcmInputFileStream(const DcmInputFileStream&);
189 
190   /// private unimplemented copy assignment operator
191   DcmInputFileStream& operator=(const DcmInputFileStream&);
192 
193   /// the final producer of the filter chain
194   DcmFileProducer producer_;
195 
196   /// filename
197   OFString filename_;
198 };
199 
200 
201 #endif
202