1 //
2 // PartialStream.h
3 //
4 // Library: Zip
5 // Package: Zip
6 // Module: PartialStream
7 //
8 // Definition of the PartialStream class.
9 //
10 // Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
11 // and Contributors.
12 //
13 // SPDX-License-Identifier: BSL-1.0
14 //
15
16
17 #ifndef Zip_PartialStream_INCLUDED
18 #define Zip_PartialStream_INCLUDED
19
20
21 #include "Poco/Zip/Zip.h"
22 #include "Poco/BufferedStreamBuf.h"
23 #include "Poco/Buffer.h"
24 #include <istream>
25 #include <ostream>
26
27
28 namespace Poco {
29 namespace Zip {
30
31
32 class Zip_API PartialStreamBuf: public Poco::BufferedStreamBuf
33 /// A PartialStreamBuf is a class that limits one view on an inputstream to a selected view range
34 {
35 public:
36 PartialStreamBuf(std::istream& in, std::ios::pos_type start, std::ios::pos_type end, const std::string& prefix, const std::string& postfix, bool initStream);
37 /// Creates the PartialStream.
38 /// If initStream is true the status of the stream will be cleared on the first access, and the stream will be repositioned
39 /// to position start
40
41 PartialStreamBuf(std::ostream& out, std::size_t start, std::size_t end, bool initStream);
42 /// Creates the PartialStream.
43 /// If initStream is true the status of the stream will be cleared on the first access.
44 /// start and end acts as offset values for the written content. A start value greater than zero,
45 /// means that the first bytes are not written but discarded instead,
46 /// an end value not equal to zero means that the last end bytes are not written!
47 /// Examples:
48 /// start = 3; end = 1
49 /// write("hello", 5) -> "l"
50
51 ~PartialStreamBuf();
52 /// Destroys the PartialStream.
53
54 void close();
55 /// Flushes a writing streambuf
56
57 Poco::UInt64 bytesWritten() const;
58
59 protected:
60 int readFromDevice(char* buffer, std::streamsize length);
61
62 int writeToDevice(const char* buffer, std::streamsize length);
63
64 private:
65 enum
66 {
67 STREAM_BUFFER_SIZE = 1024
68 };
69
70 bool _initialized;
71 std::ios::pos_type _start;
72 Poco::UInt64 _numBytes;
73 Poco::UInt64 _bytesWritten;
74 std::istream* _pIstr;
75 std::ostream* _pOstr;
76 std::string _prefix;
77 std::string _postfix;
78 std::size_t _ignoreStart;
79 Poco::Buffer<char> _buffer;
80 Poco::UInt32 _bufferOffset;
81 };
82
83
bytesWritten()84 inline Poco::UInt64 PartialStreamBuf::bytesWritten() const
85 {
86 return _bytesWritten;
87 }
88
89
90 class Zip_API PartialIOS: public virtual std::ios
91 /// The base class for PartialInputStream and PartialOutputStream.
92 ///
93 /// This class is needed to ensure the correct initialization
94 /// order of the stream buffer and base classes.
95 {
96 public:
97 PartialIOS(std::istream& istr, std::ios::pos_type start, std::ios::pos_type end, const std::string& prefix, const std::string& postfix, bool initStream);
98 /// Creates the basic stream and connects it
99 /// to the given input stream.
100 /// If initStream is true the status of the stream will be cleared on the first access, and the stream will be repositioned
101 /// to position start
102
103 PartialIOS(std::ostream& ostr, std::size_t start, std::size_t end, bool initStream);
104 /// Creates the basic stream and connects it
105 /// to the given output stream.
106 /// If initStream is true the status of the stream will be cleared on the first access.
107 /// start and end acts as offset values for the written content. A start value greater than zero,
108 /// means that the first bytes are not written but discarded instead,
109 /// an end value not equal to zero means that the last end bytes are not written!
110 /// Examples:
111 /// start = 3; end = 1
112 /// write("hello", 5) -> "l"
113
114 ~PartialIOS();
115 /// Destroys the stream.
116
117 PartialStreamBuf* rdbuf();
118 /// Returns a pointer to the underlying streambuf.
119
120 protected:
121 PartialStreamBuf _buf;
122 };
123
124
125 class Zip_API PartialInputStream: public PartialIOS, public std::istream
126 /// This stream copies all characters read through it
127 /// to one or multiple output streams.
128 {
129 public:
130 PartialInputStream(std::istream& istr, std::ios::pos_type start, std::ios::pos_type end, bool initStream = true, const std::string& prefix = std::string(), const std::string& postfix = std::string());
131 /// Creates the PartialInputStream and connects it
132 /// to the given input stream. Bytes read are guaranteed to be in the range [start, end-1]
133 /// If initStream is true the status of the stream will be cleared on the first access, and the stream will be repositioned
134 /// to position start
135
136 ~PartialInputStream();
137 /// Destroys the PartialInputStream.
138 };
139
140
141 class Zip_API PartialOutputStream: public PartialIOS, public std::ostream
142 /// This stream copies all characters written to it
143 /// to one or multiple output streams.
144 {
145 public:
146 PartialOutputStream(std::ostream& ostr, std::size_t start, std::size_t end, bool initStream = true);
147 /// Creates the PartialOutputStream and connects it
148 /// to the given output stream. Bytes written are guaranteed to be in the range [start, realEnd - end].
149 /// If initStream is true the status of the stream will be cleared on the first access.
150 /// start and end acts as offset values for the written content. A start value greater than zero,
151 /// means that the first bytes are not written but discarded instead,
152 /// an end value not equal to zero means that the last end bytes are not written!
153 /// Examples:
154 /// start = 3; end = 1
155 /// write("hello", 5) -> "l"
156 ///
157 /// start = 3; end = 0
158 /// write("hello", 5) -> "lo"
159
160 ~PartialOutputStream();
161 /// Destroys the PartialOutputStream.
162
163 void close();
164 /// must be called for the stream to properly terminate it
165
166 Poco::UInt64 bytesWritten() const;
167 /// Returns the number of bytes actually forwarded to the inner ostream
168 };
169
170
close()171 inline void PartialOutputStream::close()
172 {
173 flush();
174 _buf.close();
175 }
176
177
bytesWritten()178 inline Poco::UInt64 PartialOutputStream::bytesWritten() const
179 {
180 return _buf.bytesWritten();
181 }
182
183
184 } } // namespace Poco::Zip
185
186
187 #endif // Zip_PartialStream_INCLUDED
188