-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathstream.h
314 lines (287 loc) · 10.4 KB
/
stream.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
#ifndef _STREAM_H_
#define _STREAM_H_
#include <string>
#include <inttypes.h>
#include <vector>
#ifdef _WIN32
#include <windows.h>
typedef HANDLE fileHandle;
#define PATH_DELIMITER '\\'
#define PATH_DELIMITER_STR "\\"
#elif defined __unix__
#include <sys/types.h>
#include <malloc.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
typedef int fileHandle;
#define PATH_DELIMITER '/'
#define PATH_DELIMITER_STR "/"
#define INVALID_HANDLE_VALUE -1
#endif
#define SIZE_KB ((uint32_t)1024)
#define SIZE_MB (SIZE_KB*1024)
#define SIZE_GB (SIZE_MB*1024)
class Stream;
#ifdef WIN32
#define FILE_OPEN_READ 0x80000000
#define FILE_OPEN_WRITE 0x40000000
#define FILE_OPEN_READWRITE 0xC0000000
#define FILE_SHARE_EXCLUSIVE 0x00
#define FILE_SHARE_DENY_WRITE 0x01
#define FILE_SHARE_DENY_READ 0x02
#define FILE_SHARE_DENY_NONE 0x03
#define FILE_CREATE_NEW 0x100
#define FILE_CREATE_ALWAYS 0x200
#define FILE_OPEN_EXISTING 0x300
#define FILE_OPEN_ALWAYS 0x400
#define FILE_TRUNCATE_EXISTING 0x500
#elif defined __unix__
#define FILE_OPEN_READ O_RDONLY
#define FILE_OPEN_WRITE O_WRONLY
#define FILE_OPEN_READWRITE O_RDWR
#define FILE_SHARE_EXCLUSIVE 0x10
#define FILE_SHARE_DENY_WRITE 0x20
#define FILE_SHARE_DENY_READ 0 // not supported
#define FILE_SHARE_DENY_NONE 0x30
#define FILE_CREATE_NEW O_CREAT | O_TRUNC
#define FILE_CREATE_ALWAYS O_CREAT
#define FILE_OPEN_EXISTING 0 // not supported
#define FILE_OPEN_ALWAYS O_CREAT
#define FILE_TRUNCATE_EXISTING O_TRUNC
#endif
#define FILE_OPEN_READ_ST FILE_OPEN_READ | FILE_SHARE_DENY_WRITE | FILE_OPEN_EXISTING
#define FILE_OPEN_WRITE_ST FILE_OPEN_WRITE | FILE_SHARE_DENY_NONE | FILE_CREATE_ALWAYS
#define FILE_OPEN_READWRITE_ST FILE_OPEN_READWRITE | FILE_SHARE_DENY_NONE | FILE_OPEN_EXISTING
/**
* @brief Тип для работы с размером потока, 64 бита
*/
typedef int64_t StreamSize;
/**
* @brief Перечисление типов изменения позиции в потоке
*/
enum ESeekMethod
{
spBegin,
spCurrent,
spEnd
};
/**
* @brief Структура для хранения сведения о файловом потоке
*/
struct StreamData
{
/** @brief Флаг наличия изменений в потоке */
bool isChange;
/** @brief Флаг расположения данных потока в памяти */
bool isExMem;
/** @brief Идентификатор файла, связанного с потоком */
fileHandle handle;
/** @brief Текущий размер потока */
StreamSize size;
/** @brief Текущая позиция в потоке */
StreamSize position;
/** @brief Смещение потока в контейнере */
StreamSize offset;
/** @brief Указатель на родительский объект-контейнер */
void* package;
/** @brief Указатель на экземпляр потока */
Stream* stream;
};
/**
* @brief Базовый класс с методами файлового потока
*
* Содержит виртуальные методы, которые следует перегружать у всех потомков
*/
class StreamMethods
{
public:
/**
* @brief Изменение текущей позиции в файле
* @param stream Экземпляр потока
* @param moveTo Целевая позиция в файле
* @param method Тип изменения позиции (абсолютный, относительный, от конца файла)
* @return Текущая позиция в файле после её изменения
*/
virtual StreamSize seek(Stream* stream, StreamSize moveTo, ESeekMethod method) = 0;
/**
* @brief Получение размера потока
* @param stream Экземпляр потока
*/
virtual StreamSize getSize(Stream* stream) = 0;
/**
* @brief Установить размер потока
* @param stream Экземпляр потока
* @param newSize Новый размер потока
*/
virtual void setSize(Stream* stream, StreamSize newSize) = 0;
/**
* @brief Чтение данных из потока
* @param stream Экземпляр потока
* @param buf Буффер для данных
* @param count Размер считываемых данных
* @return Количество прочитанных байт
*/
virtual StreamSize read(Stream* stream, char* buf, StreamSize count) = 0;
/**
* @brief Запись данных в поток
* @param stream Экземпляр потока
* @param buf Буффер с данными
* @param count Размер записываемых данных
* @return Количество записанных байт
*/
virtual StreamSize write(Stream* stream, const void* buf, StreamSize count) = 0;
/**
* @brief Закрытие потока
* @param stream Экземпляр потока
*/
virtual void close(Stream* stream) = 0;
};
/**
* @brief Класс файлового потока
*/
class Stream
{
public:
/**
* @brief Указатель на структуру с методами для работы с потоком
*/
StreamMethods *m_methods;
/**
* @brief Указатель память с данными потока
*/
uint8_t* m_memory;
public:
/**
* @brief Создание "потока-в-потоке"
* @param methods Указатель на методы работы с поток родительского потока
*/
Stream(StreamMethods* methods);
/**
* @brief Создание файлового потока
* @param fileName Имя файла
* @param mode Режим открытия файла
*/
Stream(std::string fileName, const uint32_t mode);
/**
* @brief Создание потока в памяти
*/
Stream();
/**
* @brief Создание потока в памяти заданного начального размера
* @param streamSize Размер потока
*/
Stream(StreamSize streamSize);
/**
* @brief Создание потока в памяти на основе имеющейся области памяти
* @param data Указатель на область памяти с данными потока
* @param size Размер области с данными
*/
Stream(void* data, StreamSize size);
virtual ~Stream();
bool init() { return true; }
public:
/**
* @brief Структура с данными о потоке
*/
StreamData m_data;
public:
/**
* @brief Получение идентификатора файлового потока.
*/
fileHandle getFileStreamHandle();
/**
* @brief Получение указателя на область памяти с данными потока
*/
void* getMemory();
/**
* @brief Получение методов работы с текущим файловым потоком
*/
StreamMethods* getMethods();
/**
* @brief Чтение буффера из потока
* @param buf Указатель на буффер
* @param count Размер считываемых данных
* @return Количество прочитанных данных
*/
StreamSize read(void* buf, StreamSize count);
/**
* @brief Чтение NULL-терминантной строки из потока
*/
std::string readStrZ();
/**
* @brief Чтение строки заданной длины из потока
*/
std::string readStrLen(int32_t len);
/**
* @brief Чтение Wide-NULL-терминантной строки из потока
*/
std::wstring readWideStrZ();
/**
* @brief Чтение Wide-строки заданной длины из потока
*/
std::wstring readWideStrLen(int32_t len);
/**
* @brief Запись данных в поток
* @param buf Указатель на буффер с данными
* @param count Размер записываемых данных
* @return Количество записанных данных
*/
StreamSize write(const void* buf, StreamSize count);
/**
* @brief Запись строки в поток
*/
StreamSize writeStr(std::string str);
/**
* @brief Запись Wide-строки в поток
*/
StreamSize writeWideStr(std::wstring str);
/**
* @brief Изменение позиции в потоке
* @param moveTo Размер изменения
* @param moveMethod Тип перемещения (абсолютный, относительный, от конца)
* @return Текущая позиция после смены позиции
*/
StreamSize seek(StreamSize moveTo, ESeekMethod moveMethod);
/**
* @brief Получение текущего размера потока
*/
StreamSize getSize();
/**
* @brief Изменение размера потока
*/
void setSize(StreamSize newSize);
/**
* @brief Получение текущей позиции в потоке
*/
StreamSize getPosition();
/**
* @brief Установка текущей позиции в потоке
*/
void setPosition(StreamSize newPosition);
/**
* @brief Проверка достижения конца потока
*/
bool atEnd();
/**
* @brief Проверка успешности открытия потока
*/
bool opened() { return getFileStreamHandle() != INVALID_HANDLE_VALUE; }
/**
* @brief Чтение одной строки из файла
*/
std::string readLine();
/**
* @brief Чтение одной Wide-строки из файла
*/
std::wstring readWideLine();
};
/**
* @brief Метод переноса данных из "потока-в-памяти" в другой поток
*/
void StreamMem2Stream(Stream *src, Stream *dst);
/**
* @brief Метод переноса данных из одного потока в другой
*/
void Stream2Stream(Stream *src, Stream *dst);
#endif