File: Lz4Stream.h

package info (click to toggle)
jazz2-native 3.5.0-3
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid
  • size: 16,912 kB
  • sloc: cpp: 172,557; xml: 113; python: 36; makefile: 5; sh: 2
file content (131 lines) | stat: -rw-r--r-- 3,243 bytes parent folder | download
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
#pragma once

#include "../../Common.h"
#include "../Stream.h"

#if defined(WITH_LZ4) || defined(DOXYGEN_GENERATING_OUTPUT)

#include <memory>

#if !defined(CMAKE_BUILD) && defined(__has_include)
#	if __has_include("lz4/lz4frame.h")
#		define __HAS_LOCAL_LZ4
#	endif
#endif
#ifdef __HAS_LOCAL_LZ4
#	include "lz4/lz4frame.h"
#else
#	include <lz4frame.h>
#endif

namespace Death { namespace IO { namespace Compression {
//###==##====#=====--==~--~=~- --- -- -  -  -   -

	/**
		@brief Provides read-only streaming of compressed data using the LZ4 compression algorithm
	*/
	class Lz4Stream : public Stream
	{
	public:
		Lz4Stream();
		Lz4Stream(Stream& inputStream, std::int32_t inputSize = -1);
		~Lz4Stream();

		Lz4Stream(const Lz4Stream&) = delete;
		Lz4Stream(Lz4Stream&& other) noexcept;
		Lz4Stream& operator=(const Lz4Stream&) = delete;
		Lz4Stream& operator=(Lz4Stream&& other) noexcept;

		void Open(Stream& inputStream, std::int32_t inputSize = -1);

		void Dispose() override;
		std::int64_t Seek(std::int64_t offset, SeekOrigin origin) override;
		std::int64_t GetPosition() const override;
		std::int64_t Read(void* destination, std::int64_t bytesToRead) override;
		std::int64_t Write(const void* source, std::int64_t bytesToWrite) override;
		bool Flush() override;
		bool IsValid() override;
		std::int64_t GetSize() const override;
		std::int64_t SetSize(std::int64_t size) override;

		bool CeaseReading();

	private:
		enum class State : std::uint8_t {
			Unknown,
			Created,
			Initialized,
			Finished,
			Failed
		};

		static constexpr std::int32_t ChunkSize = 16384;

		Stream* _inputStream;
		LZ4F_dctx* _ctx;
		std::int64_t _size;
		std::int32_t _inputSize;
		State _state;

		char _inBuffer[ChunkSize];
		std::int32_t _inPos;
		std::int32_t _inLength;

		std::unique_ptr<char[]> _outBuffer;
		std::int32_t _outCapacity;
		std::int32_t _outPos;
		std::int32_t _outPosTotal;
		std::int32_t _outLength;

		void InitializeInternal();
		std::int32_t ReadInternal(void* ptr, std::int32_t size);
	};

	/**
		@brief Provides write-only streaming to compress written data by using the LZ4 compression algorithm
	*/
	class Lz4Writer : public Stream
	{
	public:
		Lz4Writer(Stream& outputStream, std::int32_t compressionLevel = 0);
		~Lz4Writer();

		Lz4Writer(const Lz4Writer&) = delete;
		Lz4Writer& operator=(const Lz4Writer&) = delete;

		void Dispose() override;
		std::int64_t Seek(std::int64_t offset, SeekOrigin origin) override;
		std::int64_t GetPosition() const override;
		std::int64_t Read(void* destination, std::int64_t bytesToRead) override;
		std::int64_t Write(const void* source, std::int64_t bytesToWrite) override;
		bool Flush() override;
		bool IsValid() override;
		std::int64_t GetSize() const override;
		std::int64_t SetSize(std::int64_t size) override;

	private:
		enum class State : std::uint8_t {
			Created,
			Initialized,
			Finished,
			Failed
		};

		static constexpr std::int32_t ChunkSize = 16384;

		Stream* _outputStream;
		LZ4F_cctx* _ctx;
		State _state;

		char _buffer[ChunkSize];

		std::unique_ptr<char[]> _outBuffer;
		std::int32_t _outCapacity;
		std::int32_t _outLength;

		std::int32_t WriteInternal(const void* buffer, std::int32_t bytesToWrite, bool finish);
	};

}}}

#endif