1 #pragma once
2 
3 #include <stdio.h>
4 #include <string.h>
5 #include "lc_math.h"
6 
7 #define LC_FOURCC(ch0, ch1, ch2, ch3) (quint32)((quint32)(quint8)(ch0) | ((quint32)(quint8)(ch1) << 8) | \
8 												((quint32)(quint8)(ch2) << 16) | ((quint32)(quint8)(ch3) << 24 ))
9 
10 class lcFile
11 {
12 public:
lcFile()13 	lcFile()
14 	{
15 	}
16 
~lcFile()17 	virtual ~lcFile()
18 	{
19 	}
20 
21 	lcFile(const lcFile&) = delete;
22 	lcFile(lcFile&&) = delete;
23 	lcFile& operator=(const lcFile&) = delete;
24 	lcFile& operator=(lcFile&&) = delete;
25 
26 	virtual long GetPosition() const = 0;
27 	virtual void Seek(qint64 Offset, int From) = 0;
28 	virtual size_t GetLength() const = 0;
29 
30 	virtual void Close() = 0;
31 
32 	virtual char* ReadLine(char* Buffer, size_t BufferSize) = 0;
WriteLine(const char * Buffer)33 	void WriteLine(const char* Buffer)
34 	{
35 		WriteBuffer(Buffer, strlen(Buffer));
36 	}
37 
38 	virtual size_t ReadBuffer(void* Buffer, size_t Bytes) = 0;
39 	virtual size_t WriteBuffer(const void* Buffer, size_t Bytes) = 0;
40 
ReadU8()41 	quint8 ReadU8()
42 	{
43 		quint8 Value;
44 		Read8(&Value, 1);
45 		return Value;
46 	}
47 
ReadU8(quint8 * Buffer,size_t Count)48 	size_t ReadU8(quint8* Buffer, size_t Count)
49 	{
50 		return Read8(Buffer, Count);
51 	}
52 
ReadS8()53 	qint8 ReadS8()
54 	{
55 		qint8 Value;
56 		Read8(&Value, 1);
57 		return Value;
58 	}
59 
ReadS8(qint8 * Buffer,size_t Count)60 	size_t ReadS8(qint8* Buffer, size_t Count)
61 	{
62 		return Read8(Buffer, Count);
63 	}
64 
ReadU16()65 	quint16 ReadU16()
66 	{
67 		quint16 Value;
68 		Read16(&Value, 1);
69 		return Value;
70 	}
71 
ReadU16(quint16 * Buffer,size_t Count)72 	size_t ReadU16(quint16* Buffer, size_t Count)
73 	{
74 		return Read16(Buffer, Count);
75 	}
76 
ReadS16()77 	qint16 ReadS16()
78 	{
79 		qint16 Value;
80 		Read16(&Value, 1);
81 		return Value;
82 	}
83 
ReadS16(qint16 * Buffer,size_t Count)84 	size_t ReadS16(qint16* Buffer, size_t Count)
85 	{
86 		return Read16(Buffer, Count);
87 	}
88 
ReadU32()89 	quint32 ReadU32()
90 	{
91 		quint32 Value;
92 		Read32(&Value, 1);
93 		return Value;
94 	}
95 
ReadU32(quint32 * Buffer,size_t Count)96 	size_t ReadU32(quint32* Buffer, size_t Count)
97 	{
98 		return Read32(Buffer, Count);
99 	}
100 
ReadS32()101 	qint32 ReadS32()
102 	{
103 		qint32 Value;
104 		Read32(&Value, 1);
105 		return Value;
106 	}
107 
ReadS32(qint32 * Buffer,size_t Count)108 	size_t ReadS32(qint32* Buffer, size_t Count)
109 	{
110 		return Read32(Buffer, Count);
111 	}
112 
ReadU64()113 	quint64 ReadU64()
114 	{
115 		quint64 Value;
116 		Read64(&Value, 1);
117 		return Value;
118 	}
119 
ReadU64(quint64 * Buffer,size_t Count)120 	size_t ReadU64(quint64* Buffer, size_t Count)
121 	{
122 		return Read64(Buffer, Count);
123 	}
124 
ReadS64()125 	qint64 ReadS64()
126 	{
127 		qint64 Value;
128 		Read64(&Value, 1);
129 		return Value;
130 	}
131 
ReadS64(qint64 * Buffer,size_t Count)132 	size_t ReadS64(qint64* Buffer, size_t Count)
133 	{
134 		return Read64(Buffer, Count);
135 	}
136 
ReadFloat()137 	float ReadFloat()
138 	{
139 		float Value;
140 		Read32(&Value, 1);
141 		return Value;
142 	}
143 
ReadFloats(float * Buffer,size_t Count)144 	size_t ReadFloats(float* Buffer, size_t Count)
145 	{
146 		return Read32(Buffer, Count);
147 	}
148 
ReadDouble()149 	double ReadDouble()
150 	{
151 		double Value;
152 		Read64(&Value, 1);
153 		return Value;
154 	}
155 
ReadVector3()156 	lcVector3 ReadVector3()
157 	{
158 		lcVector3 Vector;
159 		ReadFloats(Vector, 3);
160 		return Vector;
161 	}
162 
ReadDoubles(double * Buffer,size_t Count)163 	size_t ReadDoubles(double* Buffer, size_t Count)
164 	{
165 		return Read64(Buffer, Count);
166 	}
167 
ReadQString()168 	QString ReadQString()
169 	{
170 		const quint32 Size = ReadU32();
171 		char* Buffer = new char[Size];
172 		ReadBuffer(Buffer, Size);
173 		QString String = QString::fromUtf8(Buffer, Size);
174 		delete[] Buffer;
175 		return String;
176 	}
177 
WriteU8(const quint8 & Value)178 	void WriteU8(const quint8& Value)
179 	{
180 		Write8(&Value, 1);
181 	}
182 
WriteU8(const quint8 * Buffer,size_t Count)183 	size_t WriteU8(const quint8* Buffer, size_t Count)
184 	{
185 		return Write8(Buffer, Count);
186 	}
187 
WriteS8(const qint8 & Value)188 	void WriteS8(const qint8& Value)
189 	{
190 		Write8(&Value, 1);
191 	}
192 
WriteS8(const qint8 * Buffer,size_t Count)193 	size_t WriteS8(const qint8* Buffer, size_t Count)
194 	{
195 		return Write8(Buffer, Count);
196 	}
197 
WriteU16(const quint16 & Value)198 	void WriteU16(const quint16& Value)
199 	{
200 		Write16(&Value, 1);
201 	}
202 
WriteU16(const quint16 * Buffer,size_t Count)203 	size_t WriteU16(const quint16* Buffer, size_t Count)
204 	{
205 		return Write16(Buffer, Count);
206 	}
207 
WriteS16(const qint16 & Value)208 	void WriteS16(const qint16& Value)
209 	{
210 		Write16(&Value, 1);
211 	}
212 
WriteS16(const qint16 * Buffer,size_t Count)213 	size_t WriteS16(const qint16* Buffer, size_t Count)
214 	{
215 		return Write16(Buffer, Count);
216 	}
217 
WriteU32(const quint32 & Value)218 	void WriteU32(const quint32& Value)
219 	{
220 		Write32(&Value, 1);
221 	}
222 
WriteU32(const quint32 * Buffer,size_t Count)223 	size_t WriteU32(const quint32* Buffer, size_t Count)
224 	{
225 		return Write32(Buffer, Count);
226 	}
227 
WriteS32(const qint32 & Value)228 	void WriteS32(const qint32& Value)
229 	{
230 		Write32(&Value, 1);
231 	}
232 
WriteS32(const qint32 * Buffer,size_t Count)233 	size_t WriteS32(const qint32* Buffer, size_t Count)
234 	{
235 		return Write32(Buffer, Count);
236 	}
237 
WriteU64(const quint64 & Value)238 	void WriteU64(const quint64& Value)
239 	{
240 		Write64(&Value, 1);
241 	}
242 
WriteU64(const quint64 * Buffer,size_t Count)243 	size_t WriteU64(const quint64* Buffer, size_t Count)
244 	{
245 		return Write64(Buffer, Count);
246 	}
247 
WriteS64(const qint64 & Value)248 	void WriteS64(const qint64& Value)
249 	{
250 		Write64(&Value, 1);
251 	}
252 
WriteS64(const qint64 * Buffer,size_t Count)253 	size_t WriteS64(const qint64* Buffer, size_t Count)
254 	{
255 		return Write64(Buffer, Count);
256 	}
257 
WriteFloat(const float & Value)258 	void WriteFloat(const float& Value)
259 	{
260 		Write32(&Value, 1);
261 	}
262 
WriteFloats(const float * Buffer,size_t Count)263 	size_t WriteFloats(const float* Buffer, size_t Count)
264 	{
265 		return Write32(Buffer, Count);
266 	}
267 
WriteDouble(const double & Value)268 	void WriteDouble(const double& Value)
269 	{
270 		Write64(&Value, 1);
271 	}
272 
WriteDoubles(const double * Buffer,size_t Count)273 	size_t WriteDoubles(const double* Buffer, size_t Count)
274 	{
275 		return Write64(Buffer, Count);
276 	}
277 
WriteVector3(const lcVector3 & Vector)278 	void WriteVector3(const lcVector3& Vector)
279 	{
280 		WriteFloats(Vector, 3);
281 	}
282 
WriteQString(const QString & String)283 	void WriteQString(const QString& String)
284 	{
285 		QByteArray Data = String.toUtf8();
286 		WriteU32(Data.size());
287 		WriteBuffer(Data, Data.size());
288 	}
289 
290 protected:
Read8(void * Buffer,size_t Count)291 	size_t Read8(void* Buffer, size_t Count)
292 	{
293 		return ReadBuffer(Buffer, Count);
294 	}
295 
Read16(void * Buffer,size_t Count)296 	size_t Read16(void* Buffer, size_t Count)
297 	{
298 		size_t NumRead;
299 
300 		NumRead = ReadBuffer(Buffer, Count * 2) / 2;
301 
302 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
303 		quint8 Temp[2];
304 		quint8* Bytes = (quint8*)Buffer;
305 
306 		for (size_t Idx = 0; Idx < NumRead; Idx++)
307 		{
308 			Temp[0] = Bytes[0];
309 			Temp[1] = Bytes[1];
310 
311 			*Bytes++ = Temp[1];
312 			*Bytes++ = Temp[0];
313 		}
314 #endif
315 
316 		return NumRead;
317 	}
318 
Read32(void * Buffer,size_t Count)319 	size_t Read32(void* Buffer, size_t Count)
320 	{
321 		size_t NumRead;
322 
323 		NumRead = ReadBuffer(Buffer, Count * 4) / 4;
324 
325 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
326 		quint8 Temp[4];
327 		quint8* Bytes = (quint8*)Buffer;
328 
329 		for (size_t Idx = 0; Idx < NumRead; Idx++)
330 		{
331 			Temp[0] = Bytes[0];
332 			Temp[1] = Bytes[1];
333 			Temp[2] = Bytes[2];
334 			Temp[3] = Bytes[3];
335 
336 			*Bytes++ = Temp[3];
337 			*Bytes++ = Temp[2];
338 			*Bytes++ = Temp[1];
339 			*Bytes++ = Temp[0];
340 		}
341 #endif
342 
343 		return NumRead;
344 	}
345 
Read64(void * Buffer,size_t Count)346 	size_t Read64(void* Buffer, size_t Count)
347 	{
348 		size_t NumRead;
349 
350 		NumRead = ReadBuffer(Buffer, Count * 8) / 8;
351 
352 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
353 		quint8 Temp[8];
354 		quint8* Bytes = (quint8*)Buffer;
355 
356 		for (size_t Idx = 0; Idx < NumRead; Idx++)
357 		{
358 			Temp[0] = Bytes[0];
359 			Temp[1] = Bytes[1];
360 			Temp[2] = Bytes[2];
361 			Temp[3] = Bytes[3];
362 			Temp[4] = Bytes[4];
363 			Temp[5] = Bytes[5];
364 			Temp[6] = Bytes[6];
365 			Temp[7] = Bytes[7];
366 
367 			*Bytes++ = Temp[7];
368 			*Bytes++ = Temp[6];
369 			*Bytes++ = Temp[5];
370 			*Bytes++ = Temp[4];
371 			*Bytes++ = Temp[3];
372 			*Bytes++ = Temp[2];
373 			*Bytes++ = Temp[1];
374 			*Bytes++ = Temp[0];
375 		}
376 #endif
377 
378 		return NumRead;
379 	}
380 
Write8(const void * Buffer,size_t Count)381 	size_t Write8(const void* Buffer, size_t Count)
382 	{
383 		return WriteBuffer(Buffer, Count);
384 	}
385 
Write16(const void * Buffer,size_t Count)386 	size_t Write16(const void* Buffer, size_t Count)
387 	{
388 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
389 		size_t BytesWritten = 0;
390 		quint8 Temp[2];
391 		quint8* Bytes = (quint8*)Buffer;
392 
393 		for (size_t Idx = 0; Idx < Count; Idx++)
394 		{
395 			Temp[1] = *Bytes++;
396 			Temp[0] = *Bytes++;
397 
398 			BytesWritten += WriteBuffer(Temp, 2);
399 		}
400 
401 		return BytesWritten / 2;
402 #else
403 		return WriteBuffer(Buffer, Count * 2) / 2;
404 #endif
405 	}
406 
Write32(const void * Buffer,size_t Count)407 	size_t Write32(const void* Buffer, size_t Count)
408 	{
409 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
410 		size_t BytesWritten = 0;
411 		quint8 Temp[4];
412 		quint8* Bytes = (quint8*)Buffer;
413 
414 		for (size_t Idx = 0; Idx < Count; Idx++)
415 		{
416 			Temp[3] = *Bytes++;
417 			Temp[2] = *Bytes++;
418 			Temp[1] = *Bytes++;
419 			Temp[0] = *Bytes++;
420 
421 			BytesWritten += WriteBuffer(Temp, 4);
422 		}
423 
424 		return BytesWritten / 4;
425 #else
426 		return WriteBuffer(Buffer, Count * 4);
427 #endif
428 	}
429 
Write64(const void * Buffer,size_t Count)430 	size_t Write64(const void* Buffer, size_t Count)
431 	{
432 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
433 		size_t BytesWritten = 0;
434 		quint8 Temp[8];
435 		quint8* Bytes = (quint8*)Buffer;
436 
437 		for (size_t Idx = 0; Idx < Count; Idx++)
438 		{
439 			Temp[7] = *Bytes++;
440 			Temp[6] = *Bytes++;
441 			Temp[5] = *Bytes++;
442 			Temp[4] = *Bytes++;
443 			Temp[3] = *Bytes++;
444 			Temp[2] = *Bytes++;
445 			Temp[1] = *Bytes++;
446 			Temp[0] = *Bytes++;
447 
448 			BytesWritten += WriteBuffer(Temp, 8);
449 		}
450 
451 		return BytesWritten / 8;
452 #else
453 		return WriteBuffer(Buffer, Count * 8);
454 #endif
455 	}
456 };
457 
458 class lcMemFile : public lcFile
459 {
460 public:
461 	lcMemFile();
462 	~lcMemFile();
463 
464 	lcMemFile(const lcMemFile&) = delete;
465 	lcMemFile(lcMemFile&&) = delete;
466 	lcMemFile& operator=(const lcMemFile&) = delete;
467 	lcMemFile& operator=(lcMemFile&&) = delete;
468 
469 	long GetPosition() const override;
470 	void Seek(qint64 Offset, int From) override;
471 	void SetLength(size_t NewLength);
472 	size_t GetLength() const override;
473 
474 	void Close() override;
475 
476 	char* ReadLine(char* Buffer, size_t BufferSize) override;
477 	size_t ReadBuffer(void* Buffer, size_t Bytes) override;
478 	size_t WriteBuffer(const void* Buffer, size_t Bytes) override;
479 
480 	void GrowFile(size_t NewLength);
481 
482 	size_t mGrowBytes;
483 	size_t mPosition;
484 	size_t mBufferSize;
485 	size_t mFileSize;
486 	unsigned char* mBuffer;
487 };
488 
489 class lcDiskFile : public lcFile
490 {
491 public:
lcDiskFile()492 	lcDiskFile()
493 	{
494 	}
495 
lcDiskFile(const QString & FileName)496 	lcDiskFile(const QString& FileName)
497 		: mFile(FileName)
498 	{
499 	}
500 
~lcDiskFile()501 	~lcDiskFile()
502 	{
503 		Close();
504 	}
505 
506 	lcDiskFile(const lcDiskFile&) = delete;
507 	lcDiskFile(lcDiskFile&&) = delete;
508 	lcDiskFile& operator=(const lcDiskFile&) = delete;
509 	lcDiskFile& operator=(lcDiskFile&&) = delete;
510 
SetFileName(const QString & FileName)511 	void SetFileName(const QString& FileName)
512 	{
513 		mFile.setFileName(FileName);
514 	}
515 
GetPosition()516 	long GetPosition() const override
517 	{
518 		return mFile.pos();
519 	}
520 
Seek(qint64 Offset,int From)521 	void Seek(qint64 Offset, int From) override
522 	{
523 		switch (From)
524 		{
525 		case SEEK_CUR:
526 			Offset += mFile.pos();
527 			break;
528 		case SEEK_END:
529 			Offset += mFile.size();
530 			break;
531 		}
532 
533 		mFile.seek(Offset);
534 	}
535 
GetLength()536 	size_t GetLength() const override
537 	{
538 		return mFile.size();
539 	}
540 
Close()541 	void Close() override
542 	{
543 		mFile.close();
544 	}
545 
ReadLine(char * Buffer,size_t BufferSize)546 	char* ReadLine(char* Buffer, size_t BufferSize) override
547 	{
548 		const qint64 LineLength = mFile.readLine(Buffer, BufferSize);
549 		return LineLength != -1 ? Buffer : nullptr;
550 	}
551 
ReadBuffer(void * Buffer,size_t Bytes)552 	size_t ReadBuffer(void* Buffer, size_t Bytes) override
553 	{
554 		return mFile.read((char*)Buffer, Bytes);
555 	}
556 
WriteBuffer(const void * Buffer,size_t Bytes)557 	size_t WriteBuffer(const void* Buffer, size_t Bytes) override
558 	{
559 		return mFile.write((const char*)Buffer, Bytes);
560 	}
561 
Open(QIODevice::OpenMode Flags)562 	bool Open(QIODevice::OpenMode Flags)
563 	{
564 		return mFile.open(Flags);
565 	}
566 
567 protected:
568 	QFile mFile;
569 };
570 
571