崔利伟
哈尔滨工业大学
cui@hellolw.com |
namespace ca {
class CompressAlgs {
public:
virtual void compress(std::istream&, bit::oBaseStream&) = 0;
virtual void expand(bit::iBaseStream&, std::ostream&) = 0;
};
CompressAlgs &Huffman_algs();
CompressAlgs &AdaptiveHuffman_algs();
}
class iBaseStream {
public:
iBaseStream():sum{1 << (SIZE - 2)}, cnt{0}, valid{true} {}
virtual ~iBaseStream(){}
iBaseStream(const iBaseStream &) = delete;
iBaseStream(iBaseStream &&) = delete;
iBaseStream& operator=(const iBaseStream &) = delete;
operator bool() {return valid;}
iBaseStream &read_bit(bool &);
iBaseStream & read_byte(char&);
protected:
virtual void read_buffer() = 0;
bool read_bit();
char read_byte();
std::bitset<SIZE> buffer;
unsigned long sum;
unsigned long cnt;
bool valid;
};
class NetService {
public:
NetService(int cfd = -1):connfd{cfd} {}
NetService(const NetService&) = delete;
NetService &operator=(const NetService&) = delete;
NetService(const std::string &hostname, int port):connfd{-1} {
open_connfd(hostname, port);}
~NetService() {close(connfd);}
ssize_t read_str(std::string &str) {
str.clear(); rio_read(connfd, str); return str.length();}
NetService& write_str(const std::string &str) {rio_write(connfd, str); return *this;}
private:
int connfd;
void open_connfd(const std::string &, int);
void rio_write(int fd, const std::string& usrbuf);
void rio_read(int fd, std::string &usrbuf);
};
template<typename T,
typename Con = std::vector<MobileAtomic<T>>,
typename Cmp = std::less<typename Con::value_type>>
class PriorityQueue {
private:
using read_lock = rbl::read_guard<rbl::RBLock<std::mutex>>;
using write_lock = rbl::write_guard<rbl::RBLock<std::mutex>>;
static const int BEG = 1;
public:
friend void swap(PriorityQueue &first, PriorityQueue &second) {
using std::swap;
// Hope that array and compare have defined their own move constructor
swap(first.array, second.array);
swap(first.compare, second.compare);
}
PriorityQueue(const Cmp& c = Cmp()):array{1}, compare{c} {}
template <typename InputIt>
PriorityQueue(InputIt first, InputIt last, const Cmp& c = Cmp())
:PriorityQueue{c} {
while (first != last) push(*first++);
}
~PriorityQueue() {}
PriorityQueue(const PriorityQueue &other):array{other.array}, compare{other.compare} {}
PriorityQueue(PriorityQueue &&other):PriorityQueue{} {swap(*this, other);}
PriorityQueue& operator=(PriorityQueue other) {swap(*this, other); return *this;}
T top() {read_lock guard(protector); return array[BEG]; }
int size() {read_lock guard(protector); return array.size() - BEG; }
bool empty() {read_lock guard(protector); return !size(); }
void push(const T& data);
void pop();
private:
void up(size_t index);
void down(size_t index);
Con array; Cmp compare;
rbl::RBLock<std::mutex> protector;
};
}
#include "Queue.impl.hpp"
bool compress = true;
bool adaptive = true;
Options options(argv[0], " - command line options");
options.add_options()
("c,compress", "Compress file")
("e,expand", "Expand compressed file")
("s,static", "Use static huffman coding")
("a,adaptive", "Use adaptive huffman coding")
("i,input", "Input file", value<string>())
("o,output", "Output file", value<string>()->default_value("Processed.out"))
("n,hostname", "hostname", value<string>())
("h,help", "Print help")
;
options.parse(argc, argv);
if (options.count("h")) {
cout << options.help({""}) << endl;
exit(0);
}