openssl未实现具体压缩算法,但是他构建了一个压缩框架,具体算法只要套入这个框架,进行适当的适配,就可以使用通用的接口进行编程
zlib就是一个列子。
定义在comp目录下的comp_local.h中
struct comp_method_st {
int type; /* NID for compression library */
const char *name; /* A text string to identify the library */
int (*init) (COMP_CTX *ctx);
void (*finish) (COMP_CTX *ctx);
int (*compress) (COMP_CTX *ctx,
unsigned char *out, unsigned int olen,
unsigned char *in, unsigned int ilen);
int (*expand) (COMP_CTX *ctx,
unsigned char *out, unsigned int olen,
unsigned char *in, unsigned int ilen);
};
struct comp_ctx_st {
struct comp_method_st *meth;
unsigned long compress_in;
unsigned long compress_out;
unsigned long expand_in;
unsigned long expand_out;
void* data;
};
方法实现在comp_lib.c中,
COMP_CTX *COMP_CTX_new(COMP_METHOD *meth);
const COMP_METHOD *COMP_CTX_get_method(const COMP_CTX *ctx);
int COMP_CTX_get_type(const COMP_CTX* comp);
int COMP_get_type(const COMP_METHOD *meth);
const char *COMP_get_name(const COMP_METHOD *meth);
void COMP_CTX_free(COMP_CTX *ctx);
int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
unsigned char *in, int ilen);
int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
unsigned char *in, int ilen);
COMP_METHOD *COMP_zlib(void);
COMP_METHOD *COMP_zlib(void)
此方法是入口方法,在此方法中动态加载zlib库,并找到对应的方法绑定到comp_method_st 中,并返回
很简单,自己看了
COMP_METHOD *COMP_zlib(void)
{
COMP_METHOD *meth = &zlib_method_nozlib;
#ifdef ZLIB_SHARED
/* LIBZ may be externally defined, and we should respect that value */
# ifndef LIBZ
# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
# define LIBZ "ZLIB1"
# elif defined(OPENSSL_SYS_VMS)
# define LIBZ "LIBZ"
# else
# define LIBZ "z"
# endif
# endif
if (!zlib_loaded) {
zlib_dso = DSO_load(NULL, LIBZ, NULL, 0);//加载zlib库
if (zlib_dso != NULL) {
p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress");//找到指定的方法绑定到openssl的压缩框架
p_inflateEnd
= (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd");
p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate");
p_inflateInit_
= (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_");
p_deflateEnd
= (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd");
p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate");
p_deflateInit_
= (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_");
p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError");
if (p_compress && p_inflateEnd && p_inflate
&& p_inflateInit_ && p_deflateEnd
&& p_deflate && p_deflateInit_ && p_zError)
zlib_loaded++;
if (!OPENSSL_init_crypto(OPENSSL_INIT_ZLIB, NULL)) {
comp_zlib_cleanup_int();
return meth;
}
if (zlib_loaded)
meth = &zlib_stateful_method;
}
}
#endif
#if defined(ZLIB)
meth = &zlib_stateful_method;
#endif
return meth;
}
注意如果没有找到zlib库,执行是不成功的。
#include
#include
#include
int main(){
COMP_METHOD * cm= COMP_zlib();
COMP_CTX *ctx=COMP_CTX_new(cm);
unsigned char data[]="fskfjdslfjslfjsdflaafdb";
unsigned char buf[1024]={0};
int ret=COMP_compress_block(ctx,buf,1024,data,strlen(data));
if(ret>0){
//返回的应该是压缩后数据的长度
unsigned char expandbuf[1024]={0};
COMP_expand_block(ctx,expandbuf,1024,buf,ret);
printf("%s\n",expandbuf);
}
COMP_CTX_free(ctx);
return 0;
}