PoDoFo 1.2.0
Loading...
Searching...
No Matches
StreamDevice.h
1// SPDX-FileCopyrightText: 2006 Dominik Seichter <domseichter@web.de>
2// SPDX-FileCopyrightText: 2020 Francesco Pretto <ceztko@gmail.com>
3// SPDX-License-Identifier: LGPL-2.0-or-later OR MPL-2.0
4
5#ifndef AUX_STREAM_DEVICE_H
6#define AUX_STREAM_DEVICE_H
7
8#include <cstring>
9#include <ostream>
10#include <fstream>
11#include <cstdio>
12#include <vector>
13
14#include "basetypes.h"
15
16#include "InputDevice.h"
17#include "OutputDevice.h"
18
19namespace PoDoFo {
20
28class PODOFO_API StreamDevice : public InputStreamDevice, public OutputStreamDevice
29{
30protected:
31 StreamDevice(DeviceAccess access);
32
33protected:
34 static size_t SeekPosition(size_t curpos, size_t devlen, ssize_t offset, SeekDirection direction);
35};
36
37class PODOFO_API StandardStreamDevice : public StreamDevice
38{
39public:
44 StandardStreamDevice(std::ostream& stream);
45
46 StandardStreamDevice(std::istream& stream);
47
52 StandardStreamDevice(std::iostream& stream);
53
54 ~StandardStreamDevice();
55
56public:
57 size_t GetLength() const override;
58
59 size_t GetPosition() const override;
60
61 bool CanSeek() const override;
62
63 bool Eof() const override;
64
65protected:
66 StandardStreamDevice(DeviceAccess access, std::ios& stream, bool streamOwned);
67 void writeBuffer(const char* buffer, size_t size) override;
68 void flush() override;
69 size_t readBuffer(char* buffer, size_t size, bool& eof) override;
70 bool readChar(char& ch) override;
71 bool peek(char& ch) const override;
72 void seek(ssize_t offset, SeekDirection direction) override;
73 void truncate() override;
74
75 inline std::ios& GetStream() { return *m_Stream; }
76
77private:
78 StandardStreamDevice(DeviceAccess access, std::ios* stream, std::istream* istream, std::ostream* ostream, bool streamOwned);
79
80private:
81 std::ios* m_Stream;
82 std::istream* m_istream;
83 std::ostream* m_ostream;
84 bool m_StreamOwned;
85};
86
87// These are the .NET System.IO file opening modes
88// https://docs.microsoft.com/en-us/dotnet/api/system.io.filemode?view=net-6.0
89enum class FileMode : uint8_t
90{
91 CreateNew = 1,
92 Create,
93 Open,
95 Truncate,
96 Append,
97};
98
99class PODOFO_API FileStreamDevice : public StreamDevice
100{
101public:
104 FileStreamDevice(const std::string_view & filepath);
105
108 FileStreamDevice(const std::string_view & filepath, FileMode mode);
109
112 FileStreamDevice(const std::string_view& filepath, FileMode mode,
113 DeviceAccess access);
114
115 ~FileStreamDevice();
116
117public:
118 const std::string& GetFilepath() const { return m_Filepath; }
119
120 size_t GetLength() const override;
121
122 size_t GetPosition() const override;
123
124 bool CanSeek() const override;
125
126 bool Eof() const override;
127
128protected:
129 void writeBuffer(const char* buffer, size_t size) override;
130 void flush() override;
131 size_t readBuffer(char* buffer, size_t size, bool& eof) override;
132 bool readChar(char& ch) override;
133 bool peek(char& ch) const override;
134 void seek(ssize_t offset, SeekDirection direction) override;
135 void close() override;
136 void truncate() override;
137
138private:
139 FILE* m_file;
140 std::string m_Filepath;
141};
142
143template <typename TContainer>
144class ContainerStreamDevice : public StreamDevice
145{
146public:
147 ContainerStreamDevice(TContainer& container,
148 DeviceAccess access, bool ate) :
149 StreamDevice(access),
150 m_container(&container),
151 m_Position(ate ? container.size() : 0) { }
152
156 ContainerStreamDevice(const TContainer& container) :
157 ContainerStreamDevice(const_cast<TContainer&>(container), DeviceAccess::Read, false) { }
158
162 ContainerStreamDevice(TContainer& container) :
163 ContainerStreamDevice(container, DeviceAccess::ReadWrite, true) { }
164
165public:
166 size_t GetLength() const override { return m_container->size(); }
167
168 size_t GetPosition() const override { return m_Position; }
169
170 bool CanSeek() const override { return true; }
171
172 bool Eof() const override { return m_Position == m_container->size(); }
173
174protected:
175 void writeBuffer(const char* buffer, size_t size) override
176 {
177 if (m_Position + size > m_container->size())
178 m_container->resize(m_Position + size);
179
180 std::memcpy(m_container->data() + m_Position, buffer, size);
181 m_Position += size;
182 }
183
184 size_t readBuffer(char* buffer, size_t size, bool& eof) override
185 {
186 size_t readCount = std::min(size, m_container->size() - m_Position);
187 std::memcpy(buffer, m_container->data() + m_Position, readCount);
188 m_Position += readCount;
189 eof = m_Position == m_container->size();
190 return readCount;
191 }
192
193 bool readChar(char& ch) override
194 {
195 if (m_Position == m_container->size())
196 {
197 ch = '\0';
198 return false;
199 }
200
201 ch = m_container->data()[m_Position];
202 m_Position++;
203 return true;
204 }
205
206 bool peek(char& ch) const override
207 {
208 if (m_Position == m_container->size())
209 {
210 ch = '\0';
211 return false;
212 }
213
214 ch = m_container->data()[m_Position];
215 return true;
216 }
217
218 void seek(ssize_t offset, SeekDirection direction) override
219 {
220 m_Position = SeekPosition(m_Position, m_container->size(), offset, direction);
221 }
222
223 void truncate() override
224 {
225 m_container->resize(m_Position);
226 }
227
228private:
229 TContainer* m_container;
230 size_t m_Position;
231};
232
233class PODOFO_API SpanStreamDevice : public StreamDevice
234{
235public:
239 SpanStreamDevice(const char* buffer, size_t size);
240 SpanStreamDevice(const bufferview& buffer);
241 SpanStreamDevice(const std::string_view& view);
242 SpanStreamDevice(const std::string& str);
243 SpanStreamDevice(std::string& str,
244 DeviceAccess access = DeviceAccess::ReadWrite);
245 SpanStreamDevice(const char* str);
246 SpanStreamDevice(char* buffer, size_t size,
247 DeviceAccess access = DeviceAccess::ReadWrite);
248 SpanStreamDevice(const bufferspan& span,
249 DeviceAccess access = DeviceAccess::ReadWrite);
250
251public:
252 size_t GetLength() const override;
253
254 size_t GetPosition() const override;
255
256 bool Eof() const override;
257
258 bool CanSeek() const override;
259
260protected:
261 void writeBuffer(const char* buffer, size_t size) override;
262 size_t readBuffer(char* buffer, size_t size, bool& eof) override;
263 bool readChar(char& ch) override;
264 bool peek(char& ch) const override;
265 void seek(ssize_t offset, SeekDirection direction) override;
266 void truncate() override;
267
268private:
269 SpanStreamDevice(std::nullptr_t) = delete;
270
271private:
272 char* m_buffer;
273 size_t m_Length;
274 size_t m_Position;
275};
276
280class PODOFO_API NullStreamDevice final : public StreamDevice
281{
282public:
284
285public:
286 size_t GetLength() const override;
287
288 size_t GetPosition() const override;
289
290 bool Eof() const override;
291
292protected:
293 void writeBuffer(const char* buffer, size_t size) override;
294 size_t readBuffer(char* buffer, size_t size, bool& eof) override;
295 bool readChar(char& ch) override;
296 bool peek(char& ch) const override;
297 void seek(ssize_t offset, SeekDirection direction) override;
298 void truncate() override;
299
300private:
301 size_t m_Length;
302 size_t m_Position;
303};
304
308
309}
310
311#endif // AUX_STREAM_DEVICE_H
This class represents an input device It optionally supports peeking.
Definition InputDevice.h:20
void Read(char *buffer, size_t size)
Read data from the device.
Definition InputStream.cpp:19
An StreamDevice device that does nothing.
Definition StreamDevice.h:281
This class provides an output device which operates either on a file or on a buffer in memory.
Definition StreamDevice.h:29
Convenient type for char array storage and/or buffer with std::string compatibility.
Definition basetypes.h:35
All classes, functions, types and enums of PoDoFo are members of these namespace.
Definition basetypes.h:13
FileMode
Definition StreamDevice.h:90
@ CreateNew
Create a new file (throw if existing) for writing/reading.
@ OpenOrCreate
Open an existing file or create a new one for writing/reading.
@ Append
Open an existing file and seek to the end for writing.
@ Create
Create a new file or truncate existing one for writing/reading.
@ Truncate
Truncate an existing file for writing/reading.
@ Open
Open an existing file for reading and/or writing.