1 #ifndef _plugin_zstd_zstd_h_
2 #define _plugin_zstd_zstd_h_
3 
4 #include <Core/Core.h>
5 
6 #define ZSTD_STATIC_LINKING_ONLY
7 #include "lib/zstd.h"
8 
9 namespace Upp {
10 
11 class ZstdCompressStream : public Stream  {
12 public:
13 	virtual   void  Close();
14 	virtual   bool  IsOpen() const;
15 
16 protected:
17 	virtual   void  _Put(int w);
18 	virtual   void  _Put(const void *data, dword size);
19 
20 	Stream      *out;
21 
22 	Buffer<byte> buffer;
23 	Buffer<byte> outbuf;
24 	Buffer<int>  outsz;
25 
26 	enum { BLOCK_BYTES = 1024*1024 };
27 
28 	int           level;
29 
30 	bool          concurrent;
31 
32     void          Alloc();
33 	void          Init();
34 	void          FlushOut();
35 
36 public:
37 	void Co(bool b = true);
38 	void Open(Stream& out, int level = 1);
39 
40 	ZstdCompressStream();
ZstdCompressStream()41 	ZstdCompressStream(Stream& out, int level = 1) : ZstdCompressStream() { Open(out, level); }
42 	~ZstdCompressStream();
43 };
44 
45 class ZstdDecompressStream : public Stream {
46 public:
47 	virtual   bool  IsOpen() const;
48 
49 protected:
50 	virtual   int   _Term();
51 	virtual   int   _Get();
52 	virtual   dword _Get(void *data, dword size);
53 
54 private:
55 	Stream        *in;
56 	struct Workblock {
57 		String       compressed_data; // can contain more frames
58 		int          frame_at, frame_sz; // position and compressed size of frame
59 		int          decompressed_sz;
60 		Buffer<char> decompressed_data; // decompressed data
61 		bool         irregular_d = false; // d reallocated to accomodate bigger result
62 
FramePtrWorkblock63 		const void *FramePtr() { return ~compressed_data + frame_at; }
ClearWorkblock64 		void Clear()           { compressed_data.Clear(); decompressed_data.Clear(); irregular_d = false; }
65 	};
66 
67 	String compressed_data; // buffer to store compressed data
68 	int    compressed_at; // where are we in above buffer
69 
70 	Workblock wb[16];
71 	int       count; // count of workblocks fetched
72 	int       ii; // next workblock to be read
73 	int       dlen; // length of current workblock
74 
75 	enum { BLOCK_BYTES = 1024*1024 }; // expected decompressed size
76 
77 	int          maxblock;
78 	int          blockchksumsz;
79 	byte         lz4hdr;
80 	bool         eof;
81 
82 	bool         concurrent;
83 
84     void          TryHeader();
85 
86 	void          Init();
87 	bool          Next();
88 	void          Fetch();
Ended()89 	bool          Ended() const { return IsError() || in->IsError() || ptr == rdlim && ii == count && eof; }
90 
91 public:
92 	bool Open(Stream& in);
93 	void Co(bool b = true)                                    { concurrent = b; }
94 
95 	ZstdDecompressStream();
ZstdDecompressStream(Stream & in)96 	ZstdDecompressStream(Stream& in) : ZstdDecompressStream() { Open(in); }
97 	~ZstdDecompressStream();
98 };
99 
100 int64 ZstdCompress(Stream& out, Stream& in, Gate<int64, int64> progress = Null);
101 int64 ZstdDecompress(Stream& out, Stream& in, Gate<int64, int64> progress = Null);
102 String ZstdCompress(const void *data, int64 len, Gate<int64, int64> progress = Null);
103 String ZstdCompress(const String& s, Gate<int64, int64> progress = Null);
104 String ZstdDecompress(const void *data, int64 len, Gate<int64, int64> progress = Null);
105 String ZstdDecompress(const String& s, Gate<int64, int64> progress = Null);
106 
107 int64 CoZstdCompress(Stream& out, Stream& in, Gate<int64, int64> progress = Null);
108 int64 CoZstdDecompress(Stream& out, Stream& in, Gate<int64, int64> progress = Null);
109 String CoZstdCompress(const void *data, int64 len, Gate<int64, int64> progress = Null);
110 String CoZstdCompress(const String& s, Gate<int64, int64> progress = Null);
111 String CoZstdDecompress(const void *data, int64 len, Gate<int64, int64> progress = Null);
112 String CoZstdDecompress(const String& s, Gate<int64, int64> progress = Null);
113 
114 bool IsZstd(Stream& s);
115 
116 }
117 
118 #endif
119