1 #ifndef _lz4_lz4_h_
2 #define _lz4_lz4_h_
3 
4 #include <Core/Core.h>
5 
6 #include <Core/lib/lz4.h>
7 
8 namespace Upp {
9 
10 enum {
11 	LZ4F_MAGIC       = 0x184D2204,
12 
13 	LZ4F_VERSIONMASK = 0b11000000,
14 	LZ4F_VERSION     = 0b01000000,
15 	LZ4F_BLOCKINDEPENDENCE = (1 << 5),
16 	LZ4F_BLOCKCHECKSUM     = (1 << 4),
17 	LZ4F_CONTENTSIZE       = (1 << 3),
18 	LZ4F_CONTENTCHECKSUM   = (1 << 2),
19 
20 	LZ4F_MAXSIZEMASK      = 0x70,
21     LZ4F_MAXSIZE_64KB     = 0x40,
22     LZ4F_MAXSIZE_256KB    = 0x50,
23     LZ4F_MAXSIZE_1024KB   = 0x60,
24     LZ4F_MAXSIZE_4096KB   = 0x70,
25 };
26 
27 class LZ4CompressStream : public Stream  {
28 public:
29 	virtual   void  Close();
30 	virtual   bool  IsOpen() const;
31 
32 protected:
33 	virtual   void  _Put(int w);
34 	virtual   void  _Put(const void *data, dword size);
35 
36 	Stream      *out;
37 
38 	Buffer<byte> buffer;
39 	Buffer<byte> outbuf;
40 	Buffer<int>  outsz;
41 
42 	enum { BLOCK_BYTES = 1024 * 1024 };
43 
44 	xxHashStream xxh;
45 
46 	bool          concurrent;
47 
48     void          Alloc();
49 	void          Init();
50 	void          FlushOut();
51 
52 public:
53 	void Co(bool b = true);
54 	void Open(Stream& out_);
55 
56 	LZ4CompressStream();
LZ4CompressStream(Stream & out)57 	LZ4CompressStream(Stream& out) : LZ4CompressStream() { Open(out); }
58 	~LZ4CompressStream();
59 };
60 
61 class LZ4DecompressStream : public Stream {
62 public:
63 	virtual   bool  IsOpen() const;
64 
65 protected:
66 	virtual   int   _Term();
67 	virtual   int   _Get();
68 	virtual   dword _Get(void *data, dword size);
69 
70 private:
71 	Stream        *in;
72 	struct Workblock {
73 		Buffer<char> c, d; // compressed, decompressed data
74 		int   clen = 0, dlen = 0; // compressed, decompressed len
75 
ClearWorkblock76 		void Clear() { c.Clear(); d.Clear(); }
77 	};
78 	Workblock wb[16];
79 	int       count; // count of workblocks fetched
80 	int       ii; // next workblock to be read
81 	int       dlen; // length of current workblock
82 
83 	enum { BLOCK_BYTES = 1024*1024 };
84 
85 	xxHashStream xxh;
86 	int          maxblock;
87 	int          blockchksumsz;
88 	byte         lz4hdr;
89 	bool         eof;
90 
91 	bool         concurrent;
92 
93     void          TryHeader();
94 
95 	void          Init();
96 	bool          Next();
97 	void          Fetch();
Ended()98 	bool          Ended() const { return IsError() || in->IsError() || ptr == rdlim && ii == count && eof; }
99 
100 public:
101 	bool Open(Stream& in);
102 
103 	void Co(bool b = true)                                  { concurrent = b; }
104 
105 	LZ4DecompressStream();
LZ4DecompressStream(Stream & in)106 	LZ4DecompressStream(Stream& in) : LZ4DecompressStream() { Open(in); }
107 	~LZ4DecompressStream();
108 };
109 
110 int64  LZ4Compress(Stream& out, Stream& in, Gate<int64, int64> progress = Null);
111 int64  LZ4Decompress(Stream& out, Stream& in, Gate<int64, int64> progress = Null);
112 String LZ4Compress(Stream& in, Gate<int64, int64> progress = Null);
113 String LZ4Decompress(Stream& in, Gate<int64, int64> progress = Null);
114 String LZ4Compress(const void *data, int64 len, Gate<int64, int64> progress = Null);
115 String LZ4Compress(const String& s, Gate<int64, int64> progress = Null);
116 String LZ4Decompress(const void *data, int64 len, Gate<int64, int64> progress = Null);
117 String LZ4Decompress(const String& s, Gate<int64, int64> progress = Null);
118 
119 int64  CoLZ4Compress(Stream& out, Stream& in, Gate<int64, int64> progress = Null);
120 int64  CoLZ4Decompress(Stream& out, Stream& in, Gate<int64, int64> progress = Null);
121 String CoLZ4Compress(Stream& in, Gate<int64, int64> progress = Null);
122 String CoLZ4Decompress(Stream& in, Gate<int64, int64> progress = Null);
123 String CoLZ4Compress(const void *data, int64 len, Gate<int64, int64> progress = Null);
124 String CoLZ4Compress(const String& s, Gate<int64, int64> progress = Null);
125 String CoLZ4Decompress(const void *data, int64 len, Gate<int64, int64> progress = Null);
126 String CoLZ4Decompress(const String& s, Gate<int64, int64> progress = Null);
127 
128 bool IsLZ4(Stream& s);
129 
130 };
131 
132 #endif
133