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