PoDoFo 1.0.0-dev
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
76 inline std::ios& GetStream() { return *m_Stream; }
77
78private:
79 StandardStreamDevice(DeviceAccess access, std::ios* stream, std::istream* istream, std::ostream* ostream, bool streamOwned);
80
81private:
82 std::ios* m_Stream;
83 std::istream* m_istream;
84 std::ostream* m_ostream;
85 bool m_StreamOwned;
86};
87
88// These are the .NET System.IO file opening modes
89// https://docs.microsoft.com/en-us/dotnet/api/system.io.filemode?view=net-6.0
90enum class FileMode : uint8_t
91{
92 CreateNew = 1,
93 Create,
94 Open,
96 Truncate,
97 Append,
98};
99
100class PODOFO_API FileStreamDevice : public StreamDevice
101{
102public:
105 FileStreamDevice(const std::string_view & filepath);
106
109 FileStreamDevice(const std::string_view & filepath, FileMode mode);
110
113 FileStreamDevice(const std::string_view& filepath, FileMode mode,
114 DeviceAccess access);
115
116 ~FileStreamDevice();
117
118public:
119 const std::string& GetFilepath() const { return m_Filepath; }
120
121 size_t GetLength() const override;
122
123 size_t GetPosition() const override;
124
125 bool CanSeek() const override;
126
127 bool Eof() const override;
128
129protected:
130 void writeBuffer(const char* buffer, size_t size) override;
131 void flush() override;
132 size_t readBuffer(char* buffer, size_t size, bool& eof) override;
133 bool readChar(char& ch) override;
134 bool peek(char& ch) const override;
135 void seek(ssize_t offset, SeekDirection direction) override;
136 void close() 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
223private:
224 TContainer* m_container;
225 size_t m_Position;
226};
227
228class PODOFO_API SpanStreamDevice : public StreamDevice
229{
230public:
234 SpanStreamDevice(const char* buffer, size_t size);
235 SpanStreamDevice(const bufferview& buffer);
236 SpanStreamDevice(const std::string_view& view);
237 SpanStreamDevice(const std::string& str);
238 SpanStreamDevice(std::string& str,
239 DeviceAccess access = DeviceAccess::ReadWrite);
240 SpanStreamDevice(const char* str);
241 SpanStreamDevice(char* buffer, size_t size,
242 DeviceAccess access = DeviceAccess::ReadWrite);
243 SpanStreamDevice(const bufferspan& span,
244 DeviceAccess access = DeviceAccess::ReadWrite);
245
246public:
247 size_t GetLength() const override;
248
249 size_t GetPosition() const override;
250
251 bool Eof() const override;
252
253 bool CanSeek() const override;
254
255protected:
256 void writeBuffer(const char* buffer, size_t size) override;
257 size_t readBuffer(char* buffer, size_t size, bool& eof) override;
258 bool readChar(char& ch) override;
259 bool peek(char& ch) const override;
260 void seek(ssize_t offset, SeekDirection direction) override;
261
262private:
263 SpanStreamDevice(std::nullptr_t) = delete;
264
265private:
266 char* m_buffer;
267 size_t m_Length;
268 size_t m_Position;
269};
270
274class PODOFO_API NullStreamDevice final : public StreamDevice
275{
276public:
278
279public:
280 size_t GetLength() const override;
281
282 size_t GetPosition() const override;
283
284 bool Eof() const override;
285
286protected:
287 void writeBuffer(const char* buffer, size_t size) override;
288 size_t readBuffer(char* buffer, size_t size, bool& eof) override;
289 bool readChar(char& ch) override;
290 bool peek(char& ch) const override;
291 void seek(ssize_t offset, SeekDirection direction) override;
292
293private:
294 size_t m_Length;
295 size_t m_Position;
296};
297
301
302}
303
304#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:275
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:91
@ 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.