/*- * Copyright 2005 Guram Dukashvili * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ //--------------------------------------------------------------------------- #include //--------------------------------------------------------------------------- extern "C" { //--------------------------------------------------------------------------- #if (defined(_DEBUG) || defined(DEBUG)) && !defined(NDEBUG) #define LZO_DEBUG 1 #endif #if HAVE_LZO_LZO_ASM_H #include #elif HAVE_LZO_ASM_H #include #endif #if HAVE_LZO_LZO1X_H #include #elif HAVE_LZO1X_H #include #else #if HAVE_CONFIG_H #define LZO_HAVE_CONFIG_H 1 #endif #include //#include "lzo1x_9x.c" //#include "lzo1x_d1.c" //#include "lzo1x_d2.c" //#include "lzo1x_d3.c" //#include "lzo1x_o.c" //#include "lzo_init.c" #endif //--------------------------------------------------------------------------- } //--------------------------------------------------------------------------- namespace ksys { //--------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////// //--------------------------------------------------------------------------- void LZO1X::initialize() { int r = lzo_init(); assert(r == LZO_E_OK); if( r != LZO_E_OK ) newObjectV1C2(EINVAL, __PRETTY_FUNCTION__)->throwSP(); } //--------------------------------------------------------------------------- #if __BCPLUSPLUS__ #pragma option push -w-8013 -w-8004 #endif //--------------------------------------------------------------------------- LZO1X & LZO1X::compress(AutoPtr & buf,uint8_t * & p,int32_t & len) { int r = 0; lzo_uint dst_len = 0; if( level_ > 0 ){ buf.realloc(wBufPos_ + wBufPos_ / 16 + 64 + 3 + sizeof(int32_t) * 2 + (crc_ != CRCNone) * sizeof(uint32_t)); switch( method_ ){ case LZO1X_1 : r = lzo1x_1_compress( (const lzo_bytep) (wBuf_.ptr() + sizeof(int32_t)), wBufPos_, (lzo_bytep) (buf.ptr() + sizeof(int32_t) * 2), &dst_len, (lzo_voidp) wWrkMem_.ptr() ); break; case LZO1X_1_11 : r = lzo1x_1_11_compress( (const lzo_bytep) (wBuf_.ptr() + sizeof(int32_t)), wBufPos_, (lzo_bytep) (buf.ptr() + sizeof(int32_t) * 2), &dst_len, (lzo_voidp) wWrkMem_.ptr() ); break; case LZO1X_1_12 : r = lzo1x_1_11_compress( (const lzo_bytep) (wBuf_.ptr() + sizeof(int32_t)), wBufPos_, (lzo_bytep) (buf.ptr() + sizeof(int32_t) * 2), &dst_len, (lzo_voidp) wWrkMem_.ptr() ); break; case LZO1X_1_15 : r = lzo1x_1_15_compress( (const lzo_bytep) (wBuf_.ptr() + sizeof(int32_t)), wBufPos_, (lzo_bytep) (buf.ptr() + sizeof(int32_t) * 2), &dst_len, (lzo_voidp) wWrkMem_.ptr() ); break; case LZO1X_999 : r = lzo1x_999_compress_level( (const lzo_bytep) (wBuf_.ptr() + sizeof(int32_t)), wBufPos_, (lzo_bytep) (buf.ptr() + sizeof(int32_t) * 2), &dst_len, (lzo_voidp) wWrkMem_.ptr(), NULL, 0, NULL, level_ ); break; default : assert( 0 ); } assert( r == LZO_E_OK ); if( r != LZO_E_OK ) newObjectV1C2(EINVAL,__PRETTY_FUNCTION__)->throwSP(); if( dst_len >= wBufPos_ ) goto l1; if( optimize_ ){ lzo_uint orig_len = wBufPos_; r = lzo1x_optimize( (lzo_bytep) (buf.ptr() + sizeof(int32_t) * 2), dst_len, (lzo_bytep) (wBuf_.ptr() + sizeof(int32_t)), &orig_len, NULL ); assert( r == LZO_E_OK ); } if( crc_ != CRCNone ){ lzo_uint32 checksum = 0; if( crc_ == CRC32 ){ checksum = lzo_crc32(0,NULL,0); checksum = lzo_crc32(checksum,buf.ptr() + sizeof(int32_t) * 2,dst_len); } else if( crc_ == ADLER32 ){ checksum = lzo_adler32(0,NULL,0); checksum = lzo_adler32(checksum,buf.ptr() + sizeof(int32_t) * 2,dst_len); } *(uint32_t *)(buf.ptr() + sizeof(int32_t) * 2 + dst_len) = checksum; } dst_len += sizeof(int32_t) * 2 + (crc_ != CRCNone) * sizeof(uint32_t); ((int32_t *) buf.ptr())[0] = (int32_t) dst_len; ((int32_t *) buf.ptr())[1] = wBufPos_; p = buf; len = (int32_t) dst_len; } else { l1: ((int32_t *) wBuf_.ptr())[0] = -int32_t(wBufPos_); p = wBuf_; len = (int32_t) (wBufPos_ + sizeof(int32_t)); } return *this; } //--------------------------------------------------------------------------- #if __BCPLUSPLUS__ #pragma option pop #endif //--------------------------------------------------------------------------- LZO1X & LZO1X::decompress(AutoPtr & buf) { union { int32_t * i32; uint8_t * i8; }; i8 = buf; int32_t a = (int32_t) (i32[0] - sizeof(int32_t) * 2 - (crc_ != CRCNone) * sizeof(uint32_t)); if( crc_ != CRCNone && a > 0 ){ lzo_uint32 checksum = 0; if( crc_ == CRC32 ){ checksum = lzo_crc32(0,NULL,0); checksum = lzo_crc32(checksum,i8 + sizeof(int32_t) * 2,a); } else if( crc_ == ADLER32 ){ checksum = lzo_adler32(0,NULL,0); checksum = lzo_adler32(checksum,i8 + sizeof(int32_t) * 2,a); } if( *(uint32_t *) (i8 + sizeof(int32_t) * 2 + a) != checksum ) a = -a; } if( a <= 0 || i32[1] <= 0 ) newObjectV1C2(EINVAL,__PRETTY_FUNCTION__)->throwSP(); rBufSize(i32[1]); lzo_uint srcLen = a, dst_len = i32[1]; #if HAVE_LZO1X_DECOMPRESS_ASM_FAST_SAFE int r = lzo1x_decompress_asm_fast_safe( (const lzo_bytep) (i8 + sizeof(int32_t) * 2), srcLen, (lzo_bytep) rBuf_.ptr(), &dst_len, NULL ); #elif HAVE_LZO1X_DECOMPRESS_ASM_SAFE int r = lzo1x_decompress_asm_safe( (const lzo_bytep) (i8 + sizeof(int32_t) * 2), srcLen, (lzo_bytep) rBuf_.ptr(), &dst_len, NULL ); #elif HAVE_LZO1X_DECOMPRESS_SAFE int r = lzo1x_decompress_safe( (const lzo_bytep) (i8 + sizeof(int32_t) * 2), srcLen, (lzo_bytep) rBuf_.ptr(), &dst_len, NULL ); #elif HAVE_LZO1X_DECOMPRESS_ASM_FAST int r = lzo1x_decompress_asm_fast( (const lzo_bytep) (i8 + sizeof(int32_t) * 2), srcLen, (lzo_bytep) rBuf_.ptr(), &dst_len, NULL ); #elif HAVE_LZO1X_DECOMPRESS_ASM int r = lzo1x_decompress_asm( (const lzo_bytep) (i8 + sizeof(int32_t) * 2), srcLen, (lzo_bytep) rBuf_.ptr(), &dst_len, NULL ); //#elif HAVE_LZO1X_DECOMPRESS #else int r = lzo1x_decompress( (const lzo_bytep) (i8 + sizeof(int32_t) * 2), srcLen, (lzo_bytep) rBuf_.ptr(), &dst_len, NULL ); //#else //#error broken lzo library #endif assert( r == LZO_E_OK && dst_len == rBufSize_ ); if( r != LZO_E_OK || dst_len != rBufSize_ ) newObjectV1C2(EINVAL,__PRETTY_FUNCTION__)->throwSP(); return *this; } //--------------------------------------------------------------------------- LZO1X & LZO1X::active(bool active) { if( active ){ rBuf_.free(); wBuf_.realloc(wBufSize_ + sizeof(int32_t)); static const size_t wrksz[] = { LZO1X_1_MEM_COMPRESS, LZO1X_1_11_MEM_COMPRESS, LZO1X_1_12_MEM_COMPRESS, LZO1X_1_15_MEM_COMPRESS, LZO1X_999_MEM_COMPRESS }; wWrkMem_.realloc(wrksz[method_]); } else{ wWrkMem_.free(); wBuf_.free(); rBuf_.free(); } wBufPos_ = 0; rBufPos_ = 0; rBufSize_ = 0; wBufPos_ = 0; active_ = active; return *this; } //--------------------------------------------------------------------------- uint32_t adler32(uint32_t adler,const void * buf, uintptr_t len) { return lzo_adler32(adler,(const lzo_bytep) buf,(lzo_uint) len); } //--------------------------------------------------------------------------- uint32_t crc32(uint32_t c,const void * buf,uintptr_t len) { return lzo_crc32(c,(const lzo_bytep) buf,(lzo_uint) len); } //--------------------------------------------------------------------------- } // namespace ksys //---------------------------------------------------------------------------