Lua: Fix type confusion between signed and unsigned
[lsnes.git] / include / library / streamcompress.hpp
blob90c7525a0c4e3b944ac5382f2261aa0193441fc1
1 #ifndef _library__streamcompress__hpp__included__
2 #define _library__streamcompress__hpp__included__
4 #include <iosfwd>
5 #include <boost/iostreams/categories.hpp>
6 #include <boost/iostreams/operations.hpp>
7 #include <string>
8 #include <set>
9 #include <map>
10 #include <functional>
11 #include "minmax.hpp"
12 #include <cstring>
14 namespace streamcompress
16 std::map<std::string, std::string> parse_attributes(const std::string& val);
18 class base
20 public:
21 virtual ~base();
22 /**
23 * Compress data.
25 * Parameter in: Input stream pointer. Updated.
26 * Parameter insize: Input stream available. Updated.
27 * Parameter out: Output stream pointer. Updated.
28 * Parameter outsize: Output stream available. Updated.
29 * Parameter final: True if input stream ends after currently available data, false otherwise.
30 * Returns: True if EOS has been seen and all data is emitted, otherwise false.
32 virtual bool process(uint8_t*& in, size_t& insize, uint8_t*& out, size_t& outsize, bool final) = 0;
34 static std::set<std::string> get_compressors();
35 static base* create_compressor(const std::string& name, const std::string& args);
36 static void do_register(const std::string& name,
37 std::function<base*(const std::string&)> ctor);
38 static void do_unregister(const std::string& name);
41 class iostream
43 public:
44 typedef char char_type;
45 struct category : boost::iostreams::input_filter_tag, boost::iostreams::multichar_tag {};
46 /**
47 * Createa a new compressing stream.
49 iostream(base* _compressor)
51 compressor = _compressor;
52 inbuf_use = 0;
53 outbuf_use = 0;
54 ieof_flag = false;
55 oeof_flag = false;
56 emitted = 0;
58 //Other methods.
59 template<typename Source>
60 std::streamsize read(Source& src, char* s, std::streamsize n)
62 size_t flushed = 0;
63 while(n > 0) {
64 if(oeof_flag && outbuf_use == 0) {
65 if(flushed) return flushed;
66 return -1;
68 if(outbuf_use > 0) {
69 size_t tocopy = min(outbuf_use, (size_t)n);
70 size_t left = outbuf_use - tocopy;
71 memcpy(s, outbuffer, tocopy);
72 s += tocopy;
73 n -= tocopy;
74 flushed += tocopy;
75 outbuf_use -= tocopy;
76 memmove(outbuffer, outbuffer + tocopy, left);
77 emitted += tocopy;
79 while(!ieof_flag && inbuf_use < sizeof(inbuffer)) {
80 std::streamsize r = boost::iostreams::read(src, (char*)inbuffer + inbuf_use,
81 sizeof(inbuffer) - inbuf_use);
82 if(r == -1) {
83 ieof_flag = true;
84 break;
86 inbuf_use += r;
88 if(!oeof_flag) {
89 uint8_t* in = inbuffer;
90 size_t insize = inbuf_use;
91 uint8_t* out = outbuffer + outbuf_use;
92 size_t outsize = sizeof(outbuffer) - outbuf_use;
93 oeof_flag = compressor->process(in, insize, out, outsize, ieof_flag);
94 outbuf_use = sizeof(outbuffer) - outsize;
95 size_t in_r = inbuf_use - insize;
96 memmove(inbuffer, inbuffer + in_r, insize);
97 inbuf_use = insize;
100 return flushed;
102 template<typename Source>
103 void close(Source& src)
106 private:
107 base* compressor;
108 uint8_t inbuffer[4096];
109 uint8_t outbuffer[4096];
110 size_t inbuf_use;
111 size_t outbuf_use;
112 bool ieof_flag;
113 bool oeof_flag;
114 size_t emitted;
118 #endif