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
27class PODOFO_API StreamDevice : public InputStreamDevice, public OutputStreamDevice
28{
29protected:
30 StreamDevice(DeviceAccess access);
31
32protected:
33 static size_t SeekPosition(size_t curpos, size_t devlen, ssize_t offset, SeekDirection direction);
34};
35
36class PODOFO_API StandardStreamDevice : public StreamDevice
37{
38public:
42 StandardStreamDevice(std::ostream& stream);
43
44 StandardStreamDevice(std::istream& stream);
45
49 StandardStreamDevice(std::iostream& stream);
50
51 ~StandardStreamDevice();
52
53public:
54 size_t GetLength() const override;
55
56 size_t GetPosition() const override;
57
58 bool CanSeek() const override;
59
60 bool Eof() const override;
61
62protected:
63 StandardStreamDevice(DeviceAccess access, std::ios& stream, bool streamOwned);
64 void writeBuffer(const char* buffer, size_t size) override;
65 void flush() override;
66 size_t readBuffer(char* buffer, size_t size, bool& eof) override;
67 bool readChar(char& ch) override;
68 bool peek(char& ch) const override;
69 void seek(ssize_t offset, SeekDirection direction) override;
70 void truncate() override;
71
72 inline std::ios& GetStream() { return *m_Stream; }
73
74private:
75 StandardStreamDevice(DeviceAccess access, std::ios* stream, std::istream* istream, std::ostream* ostream, bool streamOwned);
76
77private:
78 std::ios* m_Stream;
79 std::istream* m_istream;
80 std::ostream* m_ostream;
81 bool m_StreamOwned;
82};
83
84// These are the .NET System.IO file opening modes
85// https://docs.microsoft.com/en-us/dotnet/api/system.io.filemode?view=net-6.0
86enum class FileMode : uint8_t
87{
88 CreateNew = 1,
89 Create,
90 Open,
92 Truncate,
93 Append,
94};
95
96class PODOFO_API FileStreamDevice : public StreamDevice
97{
98public:
100 FileStreamDevice(const std::string_view & filepath);
101
103 FileStreamDevice(const std::string_view & filepath, FileMode mode);
104
106 FileStreamDevice(const std::string_view& filepath, FileMode mode,
107 DeviceAccess access);
108
109 ~FileStreamDevice();
110
111public:
112 const std::string& GetFilepath() const { return m_Filepath; }
113
114 size_t GetLength() const override;
115
116 size_t GetPosition() const override;
117
118 bool CanSeek() const override;
119
120 bool Eof() const override;
121
122protected:
123 void writeBuffer(const char* buffer, size_t size) override;
124 void flush() override;
125 size_t readBuffer(char* buffer, size_t size, bool& eof) override;
126 bool readChar(char& ch) override;
127 bool peek(char& ch) const override;
128 void seek(ssize_t offset, SeekDirection direction) override;
129 void close() override;
130 void truncate() override;
131
132private:
133 FILE* m_file;
134 std::string m_Filepath;
135};
136
137template <typename TContainer>
138class ContainerStreamDevice : public StreamDevice
139{
140public:
141 ContainerStreamDevice(TContainer& container,
142 DeviceAccess access, bool ate) :
143 StreamDevice(access),
144 m_container(&container),
145 m_Position(ate ? container.size() : 0) { }
146
148 ContainerStreamDevice(const TContainer& container) :
149 ContainerStreamDevice(const_cast<TContainer&>(container), DeviceAccess::Read, false) { }
150
152 ContainerStreamDevice(TContainer& container) :
153 ContainerStreamDevice(container, DeviceAccess::ReadWrite, true) { }
154
155public:
156 size_t GetLength() const override { return m_container->size(); }
157
158 size_t GetPosition() const override { return m_Position; }
159
160 bool CanSeek() const override { return true; }
161
162 bool Eof() const override { return m_Position == m_container->size(); }
163
164protected:
165 void writeBuffer(const char* buffer, size_t size) override
166 {
167 if (m_Position + size > m_container->size())
168 m_container->resize(m_Position + size);
169
170 std::memcpy(m_container->data() + m_Position, buffer, size);
171 m_Position += size;
172 }
173
174 size_t readBuffer(char* buffer, size_t size, bool& eof) override
175 {
176 size_t readCount = std::min(size, m_container->size() - m_Position);
177 std::memcpy(buffer, m_container->data() + m_Position, readCount);
178 m_Position += readCount;
179 eof = m_Position == m_container->size();
180 return readCount;
181 }
182
183 bool readChar(char& ch) override
184 {
185 if (m_Position == m_container->size())
186 {
187 ch = '\0';
188 return false;
189 }
190
191 ch = m_container->data()[m_Position];
192 m_Position++;
193 return true;
194 }
195
196 bool peek(char& ch) const override
197 {
198 if (m_Position == m_container->size())
199 {
200 ch = '\0';
201 return false;
202 }
203
204 ch = m_container->data()[m_Position];
205 return true;
206 }
207
208 void seek(ssize_t offset, SeekDirection direction) override
209 {
210 m_Position = SeekPosition(m_Position, m_container->size(), offset, direction);
211 }
212
213 void truncate() override
214 {
215 m_container->resize(m_Position);
216 }
217
218private:
219 TContainer* m_container;
220 size_t m_Position;
221};
222
223class PODOFO_API SpanStreamDevice : public StreamDevice
224{
225public:
228 SpanStreamDevice(const char* buffer, size_t size);
229 SpanStreamDevice(const bufferview& buffer);
230 SpanStreamDevice(const std::string_view& view);
231 SpanStreamDevice(const std::string& str);
232 SpanStreamDevice(std::string& str,
233 DeviceAccess access = DeviceAccess::ReadWrite);
234 SpanStreamDevice(const char* str);
235 SpanStreamDevice(char* buffer, size_t size,
236 DeviceAccess access = DeviceAccess::ReadWrite);
237 SpanStreamDevice(const bufferspan& span,
238 DeviceAccess access = DeviceAccess::ReadWrite);
239
240public:
241 size_t GetLength() const override;
242
243 size_t GetPosition() const override;
244
245 bool Eof() const override;
246
247 bool CanSeek() const override;
248
249protected:
250 void writeBuffer(const char* buffer, size_t size) override;
251 size_t readBuffer(char* buffer, size_t size, bool& eof) override;
252 bool readChar(char& ch) override;
253 bool peek(char& ch) const override;
254 void seek(ssize_t offset, SeekDirection direction) override;
255 void truncate() override;
256
257private:
258 SpanStreamDevice(std::nullptr_t) = delete;
259
260private:
261 char* m_buffer;
262 size_t m_Length;
263 size_t m_Position;
264};
265
267class PODOFO_API NullStreamDevice final : public StreamDevice
268{
269public:
271
272public:
273 size_t GetLength() const override;
274
275 size_t GetPosition() const override;
276
277 bool Eof() const override;
278
279protected:
280 void writeBuffer(const char* buffer, size_t size) override;
281 size_t readBuffer(char* buffer, size_t size, bool& eof) override;
282 bool readChar(char& ch) override;
283 bool peek(char& ch) const override;
284 void seek(ssize_t offset, SeekDirection direction) override;
285 void truncate() override;
286
287private:
288 size_t m_Length;
289 size_t m_Position;
290};
291
295
296}
297
298#endif // AUX_STREAM_DEVICE_H
This class represents an input device It optionally supports peeking.
Definition InputDevice.h:19
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:268
This class provides an output device which operates either on a file or on a buffer in memory.
Definition StreamDevice.h:28
Convenient type for char array storage and/or buffer with std::string compatibility.
Definition basetypes.h:30
All classes, functions, types and enums of PoDoFo are members of these namespace.
Definition basetypes.h:13
FileMode
Definition StreamDevice.h:87
@ 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.