diff options
author | bju <bju@maxi.fritz.box> | 2013-03-24 04:14:45 +0100 |
---|---|---|
committer | bju <bju@maxi.fritz.box> | 2013-03-24 23:44:04 +0100 |
commit | 3cc7911fedcbea2337237a04658495b369c73d35 (patch) | |
tree | b2671551f65d6b2c02cad2ee0bb072fac45f0ff4 /vdr-vdrmanager/compressor.cpp | |
parent | dbf28d356eb97b3075229bbc42a8a3ccf1c94ec0 (diff) | |
download | vdr-manager-compression.tar.gz vdr-manager-compression.tar.bz2 |
the answer traffic is now compressed if enabled on the server using zip or gzipcompression
Diffstat (limited to 'vdr-vdrmanager/compressor.cpp')
-rw-r--r-- | vdr-vdrmanager/compressor.cpp | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/vdr-vdrmanager/compressor.cpp b/vdr-vdrmanager/compressor.cpp new file mode 100644 index 0000000..6a479f3 --- /dev/null +++ b/vdr-vdrmanager/compressor.cpp @@ -0,0 +1,164 @@ +/* + * compressor.cpp + * + * Created on: 23.03.2013 + * Author: bju + */ + +#include "compressor.h" + +#include <zlib.h> +#include <malloc.h> +#include <string.h> +#include <stdlib.h> + +#define CHUNK 16384 + +cCompressor::cCompressor() { + size = 0; + data = NULL; +} + +cCompressor::~cCompressor() { + +} + +bool cCompressor::CompressGzip(string text) { + + int in_fd[2]; + if (pipe(in_fd) < 0) { + return false; + } + + int out_fd[2]; + if (pipe(out_fd) < 0) { + return false; + } + + int pid = fork(); + if (pid < 0) { + return false; + } + + if (pid == 0) { + // child + close(in_fd[1]); + close(out_fd[0]); + dup2(in_fd[0], 0); + dup2(out_fd[1], 1); + + execlp("gzip", "gzip", "-c", "-9", NULL); + + exit(-1); + + } else { + // parent + close(in_fd[0]); + close(out_fd[1]); + + write(in_fd[1], text.c_str(), text.length()); + close(in_fd[1]); + + char buf[32*1024]; + + for(;;) { + int count = read(out_fd[0], buf, sizeof(buf)); + if (count < 0) { + close(out_fd[0]); + return false; + } + if (count == 0) + break; + + char * newdata = (char *)malloc(size + count); + if (data != NULL) { + memcpy(newdata, data, size); + } + memcpy(newdata + size, buf, count); + if (data != NULL) { + free(data); + } + data = newdata; + size += count; + } + + close(out_fd[0]); + } + + return true; +} + +bool cCompressor::CompressZlib(string text) { + + int ret, flush; + unsigned have; + z_stream strm; + unsigned char in[CHUNK]; + unsigned char out[CHUNK]; + int level = 9; + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = deflateInit(&strm, level); + if (ret != Z_OK) + return false; + + string input = text; + uInt len; + + do { + len = input.length(); + if (len > CHUNK) { + len = CHUNK; + } + flush = len > 0 ? Z_NO_FLUSH : Z_FINISH; + + strm.avail_in = len; + strm.next_in = (unsigned char *)input.c_str(); + + do { + strm.avail_out = CHUNK; + strm.next_out = out; + + ret = deflate(&strm, flush); + if (ret < 0) { + if (data != NULL) { + free(data); + } + return false; + } + + have = CHUNK - strm.avail_out; + + char * newdata = (char *)malloc(size + have); + if (data != NULL) { + memcpy(newdata, data, size); + } + memcpy(newdata + size, out, have); + if (data != NULL) { + free(data); + } + data = newdata; + size += have; + + } while (strm.avail_out == 0); + + input = input.substr(len); + + } while (flush != Z_FINISH); + + // clean up and return + (void)deflateEnd(&strm); + + return true; +} + +char * cCompressor::GetData() { + return data; +} + +size_t cCompressor::getDataSize() { + return size; +} + |