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