summaryrefslogtreecommitdiff
path: root/plugins/Dbx_kyoto/src/kyotocabinet/kccompress.cc
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Dbx_kyoto/src/kyotocabinet/kccompress.cc')
-rw-r--r--plugins/Dbx_kyoto/src/kyotocabinet/kccompress.cc403
1 files changed, 403 insertions, 0 deletions
diff --git a/plugins/Dbx_kyoto/src/kyotocabinet/kccompress.cc b/plugins/Dbx_kyoto/src/kyotocabinet/kccompress.cc
new file mode 100644
index 0000000000..be4533141a
--- /dev/null
+++ b/plugins/Dbx_kyoto/src/kyotocabinet/kccompress.cc
@@ -0,0 +1,403 @@
+/*************************************************************************************************
+ * Data compressor and decompressor
+ * Copyright (C) 2009-2012 FAL Labs
+ * This file is part of Kyoto Cabinet.
+ * This program is free software: you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by the Free Software Foundation, either version
+ * 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License along with this program.
+ * If not, see <http://www.gnu.org/licenses/>.
+ *************************************************************************************************/
+
+
+#include "kccompress.h"
+#include "myconf.h"
+
+#if _KC_ZLIB
+extern "C" {
+#include <zlib.h>
+}
+#endif
+
+#if _KC_LZO
+extern "C" {
+#include <lzo/lzo1x.h>
+}
+#endif
+
+#if _KC_LZMA
+extern "C" {
+#include <lzma.h>
+}
+#endif
+
+namespace kyotocabinet { // common namespace
+
+
+/**
+ * Compress a serial data.
+ */
+char* ZLIB::compress(const void* buf, size_t size, size_t* sp, Mode mode) {
+#if _KC_ZLIB
+ _assert_(buf && size <= MEMMAXSIZ && sp);
+ z_stream zs;
+ zs.zalloc = Z_NULL;
+ zs.zfree = Z_NULL;
+ zs.opaque = Z_NULL;
+ switch (mode) {
+ default: {
+ if (deflateInit2(&zs, 6, Z_DEFLATED, -15, 9, Z_DEFAULT_STRATEGY) != Z_OK) return NULL;
+ break;
+ }
+ case DEFLATE: {
+ if (deflateInit2(&zs, 6, Z_DEFLATED, 15, 9, Z_DEFAULT_STRATEGY) != Z_OK) return NULL;
+ break;
+ }
+ case GZIP: {
+ if (deflateInit2(&zs, 6, Z_DEFLATED, 15 + 16, 9, Z_DEFAULT_STRATEGY) != Z_OK) return NULL;
+ break;
+ }
+ }
+ const char* rp = (const char*)buf;
+ size_t zsiz = size + size / 8 + 32;
+ char* zbuf = new char[zsiz+1];
+ char* wp = zbuf;
+ zs.next_in = (Bytef*)rp;
+ zs.avail_in = size;
+ zs.next_out = (Bytef*)wp;
+ zs.avail_out = zsiz;
+ if (deflate(&zs, Z_FINISH) != Z_STREAM_END) {
+ delete[] zbuf;
+ deflateEnd(&zs);
+ return NULL;
+ }
+ deflateEnd(&zs);
+ zsiz -= zs.avail_out;
+ zbuf[zsiz] = '\0';
+ if (mode == RAW) zsiz++;
+ *sp = zsiz;
+ return zbuf;
+#else
+ _assert_(buf && size <= MEMMAXSIZ && sp);
+ char* zbuf = new char[size+2];
+ char* wp = zbuf;
+ *(wp++) = 'z';
+ *(wp++) = (uint8_t)mode;
+ std::memcpy(wp, buf, size);
+ *sp = size + 2;
+ return zbuf;
+#endif
+}
+
+
+/**
+ * Decompress a serial data.
+ */
+char* ZLIB::decompress(const void* buf, size_t size, size_t* sp, Mode mode) {
+#if _KC_ZLIB
+ _assert_(buf && size <= MEMMAXSIZ && sp);
+ size_t zsiz = size * 8 + 32;
+ while (true) {
+ z_stream zs;
+ zs.zalloc = Z_NULL;
+ zs.zfree = Z_NULL;
+ zs.opaque = Z_NULL;
+ switch (mode) {
+ default: {
+ if (inflateInit2(&zs, -15) != Z_OK) return NULL;
+ break;
+ }
+ case DEFLATE: {
+ if (inflateInit2(&zs, 15) != Z_OK) return NULL;
+ break;
+ }
+ case GZIP: {
+ if (inflateInit2(&zs, 15 + 16) != Z_OK) return NULL;
+ break;
+ }
+ }
+ char* zbuf = new char[zsiz+1];
+ zs.next_in = (Bytef*)buf;
+ zs.avail_in = size;
+ zs.next_out = (Bytef*)zbuf;
+ zs.avail_out = zsiz;
+ int32_t rv = inflate(&zs, Z_FINISH);
+ inflateEnd(&zs);
+ if (rv == Z_STREAM_END) {
+ zsiz -= zs.avail_out;
+ zbuf[zsiz] = '\0';
+ *sp = zsiz;
+ return zbuf;
+ } else if (rv == Z_BUF_ERROR) {
+ delete[] zbuf;
+ zsiz *= 2;
+ } else {
+ delete[] zbuf;
+ break;
+ }
+ }
+ return NULL;
+#else
+ _assert_(buf && size <= MEMMAXSIZ && sp);
+ if (size < 2 || ((char*)buf)[0] != 'z' || ((char*)buf)[1] != (uint8_t)mode) return NULL;
+ buf = (char*)buf + 2;
+ size -= 2;
+ char* zbuf = new char[size+1];
+ std::memcpy(zbuf, buf, size);
+ zbuf[size] = '\0';
+ *sp = size;
+ return zbuf;
+#endif
+}
+
+
+/**
+ * Calculate the CRC32 checksum of a serial data.
+ */
+uint32_t ZLIB::calculate_crc(const void* buf, size_t size, uint32_t seed) {
+#if _KC_ZLIB
+ _assert_(buf && size <= MEMMAXSIZ);
+ return crc32(seed, (unsigned char*)buf, size);
+#else
+ _assert_(buf && size <= MEMMAXSIZ);
+ return 0;
+#endif
+}
+
+
+/**
+ * Hidden resources for LZO.
+ */
+#if _KC_LZO
+static int32_t lzo_init_func() {
+ if (lzo_init() != LZO_E_OK) throw std::runtime_error("lzo_init");
+ return 0;
+}
+int32_t lzo_init_var = lzo_init_func();
+#endif
+
+
+/**
+ * Compress a serial data.
+ */
+char* LZO::compress(const void* buf, size_t size, size_t* sp, Mode mode) {
+#if _KC_LZO
+ _assert_(buf && size <= MEMMAXSIZ && sp);
+ char* zbuf = new char[size+size/16+80];
+ lzo_uint zsiz;
+ char wrkmem[LZO1X_1_MEM_COMPRESS];
+ if (lzo1x_1_compress((lzo_bytep)buf, size, (lzo_bytep)zbuf, &zsiz, wrkmem) != LZO_E_OK) {
+ delete[] zbuf;
+ return NULL;
+ }
+ if (mode == CRC) {
+ uint32_t hash = lzo_crc32(0, (const lzo_bytep)zbuf, zsiz);
+ writefixnum(zbuf + zsiz, hash, sizeof(hash));
+ zsiz += sizeof(hash);
+ }
+ zbuf[zsiz] = '\0';
+ *sp = zsiz;
+ return (char*)zbuf;
+#else
+ _assert_(buf && size <= MEMMAXSIZ && sp);
+ char* zbuf = new char[size+2];
+ char* wp = zbuf;
+ *(wp++) = 'o';
+ *(wp++) = mode;
+ std::memcpy(wp, buf, size);
+ *sp = size + 2;
+ return zbuf;
+#endif
+}
+
+
+/**
+ * Decompress a serial data.
+ */
+char* LZO::decompress(const void* buf, size_t size, size_t* sp, Mode mode) {
+#if _KC_LZO
+ _assert_(buf && size <= MEMMAXSIZ && sp);
+ if (mode == CRC) {
+ if (size < sizeof(uint32_t)) return NULL;
+ uint32_t hash = readfixnum((const char*)buf + size - sizeof(hash), sizeof(hash));
+ size -= sizeof(hash);
+ if (lzo_crc32(0, (const lzo_bytep)buf, size) != hash) return NULL;
+ }
+ char* zbuf;
+ lzo_uint zsiz;
+ int32_t rat = 6;
+ while (true) {
+ zsiz = (size + 256) * rat + 3;
+ zbuf = new char[zsiz+1];
+ int32_t rv;
+ if (mode == RAW) {
+ rv = lzo1x_decompress_safe((lzo_bytep)buf, size, (lzo_bytep)zbuf, &zsiz, NULL);
+ } else {
+ rv = lzo1x_decompress((lzo_bytep)buf, size, (lzo_bytep)zbuf, &zsiz, NULL);
+ }
+ if (rv == LZO_E_OK) {
+ break;
+ } else if (rv == LZO_E_OUTPUT_OVERRUN) {
+ delete[] zbuf;
+ rat *= 2;
+ } else {
+ delete[] zbuf;
+ return NULL;
+ }
+ }
+ zbuf[zsiz] = '\0';
+ if (sp) *sp = zsiz;
+ return (char*)zbuf;
+#else
+ _assert_(buf && size <= MEMMAXSIZ && sp);
+ if (size < 2 || ((char*)buf)[0] != 'o' || ((char*)buf)[1] != mode) return NULL;
+ buf = (char*)buf + 2;
+ size -= 2;
+ char* zbuf = new char[size+1];
+ std::memcpy(zbuf, buf, size);
+ zbuf[size] = '\0';
+ *sp = size;
+ return zbuf;
+#endif
+}
+
+
+/**
+ * Calculate the CRC32 checksum of a serial data.
+ */
+uint32_t LZO::calculate_crc(const void* buf, size_t size, uint32_t seed) {
+#if _KC_LZO
+ _assert_(buf && size <= MEMMAXSIZ);
+ return lzo_crc32(seed, (const lzo_bytep)buf, size);
+#else
+ _assert_(buf && size <= MEMMAXSIZ);
+ return 0;
+#endif
+}
+
+
+/**
+ * Compress a serial data.
+ */
+char* LZMA::compress(const void* buf, size_t size, size_t* sp, Mode mode) {
+#if _KC_LZMA
+ _assert_(buf && size <= MEMMAXSIZ && sp);
+ lzma_stream zs = LZMA_STREAM_INIT;
+ const char* rp = (const char*)buf;
+ size_t zsiz = size + 1024;
+ char* zbuf = new char[zsiz+1];
+ char* wp = zbuf;
+ zs.next_in = (const uint8_t*)rp;
+ zs.avail_in = size;
+ zs.next_out = (uint8_t*)wp;
+ zs.avail_out = zsiz;
+ switch (mode) {
+ default: {
+ if (lzma_easy_encoder(&zs, 6, LZMA_CHECK_NONE) != LZMA_OK) return NULL;
+ break;
+ }
+ case CRC: {
+ if (lzma_easy_encoder(&zs, 6, LZMA_CHECK_CRC32) != LZMA_OK) return NULL;
+ break;
+ }
+ case SHA: {
+ if (lzma_easy_encoder(&zs, 6, LZMA_CHECK_SHA256) != LZMA_OK) return NULL;
+ break;
+ }
+ }
+ if (lzma_code(&zs, LZMA_FINISH) != LZMA_STREAM_END) {
+ delete[] zbuf;
+ lzma_end(&zs);
+ return NULL;
+ }
+ lzma_end(&zs);
+ zsiz -= zs.avail_out;
+ *sp = zsiz;
+ return zbuf;
+#else
+ _assert_(buf && size <= MEMMAXSIZ && sp);
+ char* zbuf = new char[size+2];
+ char* wp = zbuf;
+ *(wp++) = 'x';
+ *(wp++) = mode;
+ std::memcpy(wp, buf, size);
+ *sp = size + 2;
+ return zbuf;
+#endif
+}
+
+
+/**
+ * Decompress a serial data.
+ */
+char* LZMA::decompress(const void* buf, size_t size, size_t* sp, Mode mode) {
+#if _KC_LZMA
+ _assert_(buf && size <= MEMMAXSIZ && sp);
+ size_t zsiz = size * 8 + 32;
+ while (true) {
+ lzma_stream zs = LZMA_STREAM_INIT;
+ const char* rp = (const char*)buf;
+ char* zbuf = new char[zsiz+1];
+ char* wp = zbuf;
+ zs.next_in = (const uint8_t*)rp;
+ zs.avail_in = size;
+ zs.next_out = (uint8_t*)wp;
+ zs.avail_out = zsiz;
+ if (lzma_auto_decoder(&zs, 1ULL << 30, 0) != LZMA_OK) return NULL;
+ int32_t rv = lzma_code(&zs, LZMA_FINISH);
+ lzma_end(&zs);
+ if (rv == LZMA_STREAM_END) {
+ zsiz -= zs.avail_out;
+ zbuf[zsiz] = '\0';
+ *sp = zsiz;
+ return zbuf;
+ } else if (rv == LZMA_OK) {
+ delete[] zbuf;
+ zsiz *= 2;
+ } else {
+ delete[] zbuf;
+ break;
+ }
+ }
+ return NULL;
+#else
+ _assert_(buf && size <= MEMMAXSIZ && sp);
+ if (size < 2 || ((char*)buf)[0] != 'x' || ((char*)buf)[1] != mode) return NULL;
+ buf = (char*)buf + 2;
+ size -= 2;
+ char* zbuf = new char[size+1];
+ std::memcpy(zbuf, buf, size);
+ zbuf[size] = '\0';
+ *sp = size;
+ return zbuf;
+#endif
+}
+
+
+/**
+ * Calculate the CRC32 checksum of a serial data.
+ */
+uint32_t LZMA::calculate_crc(const void* buf, size_t size, uint32_t seed) {
+#if _KC_LZMA
+ _assert_(buf && size <= MEMMAXSIZ);
+ return lzma_crc32((const uint8_t*)buf, size, seed);
+#else
+ _assert_(buf && size <= MEMMAXSIZ);
+ return 0;
+#endif
+}
+
+
+/**
+ * Prepared pointer of the ZLIB raw mode.
+ */
+ZLIBCompressor<ZLIB::RAW> zlibrawfunc;
+ZLIBCompressor<ZLIB::RAW>* const ZLIBRAWCOMP = &zlibrawfunc;
+
+
+} // common namespace
+
+// END OF FILE