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