C++ Redis mset二进制数据接口封装方案
作者:网络转载 发布时间:[ 2015/2/12 11:46:10 ] 推荐标签:C++ 接口 封装
这种方式可以处理mset多个字符串数据,但对于数据内容为二进制数据的无能为力;
redisCommandArgv接口传递 方案
对于多个参数传递,hiredis提供了以下接口,这个接口中后一个参数是所有的传入数据的内容长度,
是说这个接口是二进制安全的:
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
主要工作是构造一个动态的二维数组char ** argv,其中涉及到char **到const char **的转换,有一定的风险,
关于这一点前一篇文章已经谈到;
void mset1( redisContext *c, const vector<string> &vtKey, const vector<string> & vtVal )
{
if(vtKey.size() != vtVal.size())
{
throw runtime_error( "Redis error" );
}
char ** argv = new char*[vtKey.size() + vtVal.size() + 1 ];
size_t * argvlen = new size_t[vtKey.size() + vtVal.size() + 1 ];
int j = 0;
argv[j] = new char[5];
memcpy(argv[j],"MSET",4);
argvlen[j] = 4;
++j;
for(int i = 0 ; i < vtKey.size();i++)
{
argvlen[j] = vtKey[i].length();
argv[j] = new char[argvlen[j]];
memset((void*)argv[j],0,argvlen[j] );
memcpy((void*)argv[j],vtKey[i].data(),vtKey[i].length());
j++;
argvlen[j] = vtVal[i].length();
argv[j] = new char[argvlen[j]];
memset((void*)argv[j],0,argvlen[j]);
memcpy((void*)argv[j],vtVal[i].data(),vtVal[i].length());
j++;
}
//if not use const_cast<const char**> ,compile error
//for why assign from char** to const char** error, see my blog ...
void *r = redisCommandArgv(c, vtKey.size() + vtVal.size() + 1, const_cast<const char**>(argv), argvlen );
if ( !r )
throw runtime_error( "Redis error" );
freeReplyObject( r );
for(int i = 0;i < vtKey.size();i++)
{
delete [] argv[i];
argv[i] = NULL;
}
delete []argv;
delete []argvlen;
argv = NULL;
}
redisCommandArgv接口传递的Vector方案
还是使用redisCommandArgv接口,使用vector来构造这个const char **,这个方法是从参考资料1中学到的:
void mset2( redisContext *c, const vector<string> &vtKey, const vector<string> & vtVal)
{
if(vtKey.size() != vtVal.size())
{
throw runtime_error( "Redis error" );
}
vector<const char *> argv( vtKey.size() + vtVal.size() + 1 );
vector<size_t> argvlen( vtKey.size() + vtVal.size() + 1 );
int j = 0;
static char msetcmd[] = "MSET";
argv[j] = msetcmd;
argvlen[j] = sizeof(msetcmd)-1;
++j;
for(int i = 0;i< vtKey.size();++i)
{
argvlen[j] = vtKey[i].length();
argv[j] = new char[argvlen[j]];
memset((void*)argv[j],0,argvlen[j] );
memcpy((void*)argv[j],vtKey[i].data(),vtKey[i].length());
j++;
argvlen[j] = vtVal[i].length();
argv[j] = new char[argvlen[j]];
memset((void*)argv[j],0,argvlen[j]);
memcpy((void*)argv[j],vtVal[i].data(),vtVal[i].length());
j++;
}
void *r = redisCommandArgv(c, argv.size(), &(argv[0]), &(argvlen[0]) );
if ( !r )
throw runtime_error( "Redis error" );
freeReplyObject( r );
}
这样,实现二进制数据的传递;
二进制校验
程序执行后,可以用redis-cli来验证:
对于非二进制安全的实现,二进制内容是截断的:
/opt/app/colin$./redis-cli get D
"AB"
而二进制安全的实现接口,二进制数据的0通过转义方式显示:
/opt/app/colin$./redis-cli get D
"ABx00DE"
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南