Tuxedo缓冲区的封装代码,成就你打造通用的tuxedo客户端(五)
//下面呢,我们来分析一下,怎么接收返回的数据,以及如何分析返回的数据
int TuxPost::BufferStringRec()
{
gview.Clear();
m+=" ||开始解析tuxedo返回的数据";
if( s_RecBuff==NULL) {
m_status=-1;
m+=" || tuxedo返回数据为空,请检查原因 ||";
return -1;
}
gview.instr.clear();
gview.outstr.clear();
memcpy(Buffer,s_RecBuff,strlen(s_RecBuff));
Buffer[strlen(Buffer)]=0;
map<string,VeiwType>::iterator
it=gview.theView.begin();
string temp;
while(it!=gview.theView.end()) {//这里注意判断是否出参设置
if(Param(it->second.name.c_str())==OUT || Param(it->second.name.c_str())==INOUT) {
temp=Buffer;
if(trim(temp)=="")
return -1;
gview.outstr=it->second.name+"="+temp;
size_t sp=gview.outstr.find_last_of(";");
//以成员名称+值的方式返回,比如:recv=876432;
if(static_cast<int>(sp)!=-1) {
gview.outstr.erase(sp);
}
break;
}
++it;
}
memset(Buffer,0,BUFFLEN*sizeof(char));
memcpy(Buffer,gview.outstr.c_str(),gview.outstr.size());
m+=" || 分析tuxedo返回的string类型数据成功";
gview.outstr.clear();
return 0;
}
//VIEW32缓冲区方式的返回
int TuxPost::BufferViewRec()//解析view32类型,从tuxedo返回的结果的缓冲区,解析数据
{
map<string,VeiwType>::iterator
it=gview.theView.begin();
gview.Vinbufmap.clear();
char log[255]="";
int i=0;
int tmp1=0;
double tmp2=0.0;
float tmp3=0.0;
char tmp4[255]="";
long tmp5=0;
string stemp;
if((char*)v_RecBuff==NULL)
{
m+=" || tuxedo返回数据为空,请检查原因 || ";
return -1;
}
while(it!=gview.theView.end())
{
if(it!=gview.theView.end() &&
(Param(it->second.name.c_str())==OUT ||Param(it->second.name.c_str())==INOUT)) {
long outoffset=it->second.begin;
if((it->second).tmp=="INT") {
tmp1=*(int *)(v_RecBuff+outoffset);
stemp=it->second.name+"=="+IntToString(tmp1)+";";
}
//如果业务数据成员是double类型,,下面的同理,一直赋值到50
if((it->second).tmp=="DOUBLE") {
tmp2=*(double *)(v_RecBuff+outoffset);//做相应的解析
stemp=it->second.name+"=="+DoubleToString(tmp2)+";";//然后转化为string赋值给v50
}
//如果业务数据成员是float类型,,下面的同理,一直赋值到50
if((it->second).tmp=="FLOAT") {
tmp3=*(float *)(v_RecBuff+outoffset);//做相应的解析
stemp=it->second.name+"=="+FloatToString(tmp3)+";";//然后转化为string赋值给v40
}
//如果业务数据成员是char类型,,下面的同理,一直赋值到50
if((it->second).tmp=="CHAR") {
int i=atoi(it->second.orivalue.c_str());//做相应的解析
memcpy(tmp4,v_RecBuff+outoffset,i);
tmp4[i]=0;
stemp=it-->second.name+"=="+stemp.assign(tmp4)+";";//然后转化为string赋值给v50
}
//如果业务数据成员是long类型,
if((it->second).tmp=="LONG") {
tmp5=*(long *)(v_RecBuff+outoffset);//做相应的解析
stemp=it->second.name+"=="+LongToString(tmp5)+";";//然后转化为string赋值给.v4
}
gview.Voutbuf.push_back(stemp);//将每一个返回的string对象stemp插入gview.Voutbuf,这是一个vector,声明为:vector<string>
Voutbuf;
stemp.clear();
}
++it;
}
return 0;
}
int TuxPost::OutViewBuffer()
{
if(BufferViewRec()==-1) {
m+=" ||分析tuxedo返回view缓冲区数据失败,请检查返回缓冲区";
return -1;
}
vector<string>::iterator it=gview.Voutbuf.begin();
string s;
while(it!=gview.Voutbuf.end()) {
s+= (*(it));
++it;
}
memset(Buffer,0,BUFFLEN*sizeof(char));
size_t sp=s.find_last_of(";");
if(static_cast<int>(sp)!=-1) {
s.erase(sp);
}
memcpy(Buffer,s.c_str(),s.size());
gview.Voutbuf.clear();
return 0;
}//我们可以看到VIEW的返回时从这个gview.Voutbuf
//VECTOR里面返回来的。。。。。
int TuxPost::BufferFmlRec()//组装fml返回缓冲区的数据,输出给isalt对应的格式 {
char sTmp[255]="";
char s[255]="";
int i=0;
int j=0;
int maxoc=0;
//初始化最大field的个数
if( f_RecBuff==NULL)
{
m+=" || tuxedo返回数据为空,请检查原因 || ";
return -1;
}
memset(Buffer,0,BUFFLEN*sizeof(char));//初始化输出的缓冲区
for(map<string,VeiwType>::iterator
it=gview.theView.begin();it!=gview.theView.end();++it)
{//循环thevIEW
memset(sTmp,0,sizeof(sTmp)) ;
memset(s,0,sizeof(s));
strcpy(sTmp,it->second.name.c_str());//找到业务的成员,并转化为char*
j=Foccur32((FBFR32 *)f_RecBuff,Fldid32(sTmp)) ; //这个函数是返回fleild在Buffer里面的最大个数
if(j>maxoc)//如果它>maxoc
{
maxoc=j;
//那么把他赋值给maxoc,这个值决定了循环的次数 }
}
for(;i<maxoc;) {
for(map<string,VeiwType>::iterator
it1=gview.theView.begin();it1!=gview.theView.end();++it1) {
memset(sTmp,0,sizeof(sTmp));
memset(s,0,sizeof(s));
strcpy(sTmp,it1 second.name.c_str());
Fgets32((FBFR32*)f_RecBuff,Fldid32(sTmp), i, s);
AllTrim(s);
if(strcm p(s,"")==0)
return -1;
if((Param(sTmp)==OUT || Param(sTmp)==INOUT) && strcmp(s,"")!=0) {
strcat(sTmp,"==");
strcat(sTmp,s);
strcat(sTmp,";");
strcat(Buffer,sTmp);
continue;
} else {
memset(s,0,sizeof(s));
sprintf(s," || 当前业务数据%s不允许输出请查看iSALT.def",sTmp);
m+=s;
}
}
++i;
}
m+=" || 解析tuxedo返回的FML数据成功";
string s1(Buffer);
memset(Buffer,0,BUFFLEN*sizeof(char));//初始化输出的缓冲区
size_t sp=s1.find_last_of(";");
if(static_cast<int>(sp)!=-1) {
s1.erase(sp);
}
memcpy(Buffer,s1.c_str(),s1.size());
m+=Buffer;
return 0;
}
// 好了,解析和返回就做完了���。。。好累。。
void
TuxPost::DelMem()
{
这里是清理工作。。。。。。。
if(f_SendBuff) {
memset(f_SendBuff,0,sizeof(f_SendBuff));
tpfree(f_SendBuff);
f_SendBuff=NULL;
}
if(f_RecBuff) {
memset(f_RecBuff,0,sizeof(f_RecBuff));
tpfree(f_RecBuff);
f_RecBuff=NULL;
}
if(v_SendBuff) {
memset(v_SendBuff,0,sizeof(v_SendBuff));
tpfree(v_SendBuff);
v_SendBuff=NULL;
}
if(v_RecBuff) {
memset(v_RecBuff,0,sizeof(v_RecBuff));
tpfree(v_RecBuff);
v_RecBuff=NULL;
}
if(s_SendBuff) {
memset(s_SendBuff,0,sizeof(s_SendBuff));
tpfree(s_SendBuff);
s_SendBuff=NULL;
}
if(s_RecBuff) {
memset(s_RecBuff,0,sizeof(s_RecBuff));
tpfree(s_RecBuff);
s_RecBuff=NULL;
}
if(gview.theVector.size()==0) {//注意这里。。。。取出来的东西,全部放入gview.theVector,注意和gview.theMap以及和gview.vinoutbuf,gview.voutbuf,等区别...
string temp(m_CurServiceName);
gview.theVector.push_back(temp);
temp=gview.wsnaddr;
gview.theVector.push_back(temp);
temp=Stype;
gview.theVector.push_back(temp);
if(strncmp(Stype,"FML",3)==0) {
temp=g_FIELDTBLS32;
gview.theVector.push_back(temp);
temp=g_FLDTBLDIR32;
gview.theVector.push_back(temp);
}
if(strncmp(Stype,"FML",3)!=0) {
temp="not need fml tbs ";
gview.theVector.push_back(temp);
gview.theVector.push_back(temp);
}
map<string,VeiwType>::iterator it=gview.theView.begin();
string
stemp;
while(it!=gview.theView.end()) {
stemp+=(it->first)+"||"+(it
>second).name+"||"+(it->second).value+"||"+(it->second).tmp+"||";
++it;
}
gview.theVector.push_back(stemp);
//保存本次请求的信息,也就是保存请求名称,缓冲区类型,域表头文件和本次请求
tuxedo服务的数据成员名称,大小,以及类型等信息。。。 makeTrie();
}
gview.Clear();
gview.theView.clear();
}
int TuxPost::makeTrie()//产生一个Trie的对象。。。。
{
if(gview.theVector.size()==6)
{
vector<string> ::iterator
it=gview.theVector.begin();
string temp1=(*it);
++it;
string temp2=(*it);
++it;
string temp3=(*it);
++it;
string temp4=(*it);
++it;
string temp5=(*it);
++it;
string
temp6=(*it);
++it;
Trie
trie(temp1,temp2,temp3,temp4,temp5,temp6);
trie.RedotheView=gview.theView;
pair<map<string,Trie>::iterator,bool>
ret=themap.insert(map<string,Trie>::value_type(temp1,trie));
gview.theVector.clear();
}
return
0;
}
并且将这个对象插入到themap这个容器里面,用于判断本次请求是不是请求过。。。
记得我们刚开始讲的时候,说过有一个很大的容器,如果你请求一次,那么以后就不用
再做类型成员的分析了。。等等。。。。就是这个容��themap
//这里,判断是不是请求过的服务,如果是Redoflag=1
然后将一些必要的信息取出来。。。
像Stype,wsnaddr,业务成员信息,以及和一些域表信息。。
这个容器对于提高性能,很有帮助,特别是对于CPU的使用和内存的利用。。
int TuxPost::RedoSvc(string
svcname)
{
map<string,Trie>::iterator
it;
it=themap.find(svcname);
if(it!=themap.end()) {
Redoflag=1;
(*it).second.flag+=1;
memset(Stype,0,sizeof(Stype));
strncpy(Stype,(*it).second.servtype.c_str(),(*it).second.servtype.size());
memset(m_CurWSNADDR,0,sizeof(m_CurWSNADDR));
strncpy(m_CurWSNADDR,(*it).second.wsnaddr.c_str(),(*it).second.wsnaddr.size())
;
if(strcmp(m_CurWSNADDR,g_WSNADDR)!=0) {
memset(g_WSNADDR,0,sizeof(g_WSNADDR));
strcpy(g_WSNADDR,m_CurWSNADDR);
tuxputenv(m_CurWSNADDR);
}
if(strcmp(Stype,"FML")==0) {
memset(FIELDTBLS32,0,sizeof(FIELDTBLS32));
strcpy(FIELDTBLS32,(*it).second.fieldtbs.c_str());
memset(FLDTBLDIR32,0,sizeof(FLDTBLDIR32));
strcpy(FLDTBLDIR32,(*it).second.fldtbldir.c_str());
if(strncmp(g_FLDTBLDIR32,FLDTBLDIR32,strlen(FLDTBLDIR32))!=0) {
strcpy(g_FLDTBLDIR32,FLDTBLDIR32);
g_FLDTBLDIR32[strlen(FLDTBLDIR32)]='0';
tuxputenv(FLDTBLDIR32);
}
if(strncmp(g_FIELDTBLS32,FIELDTBLS32,strlen(FIELDTBLS32))!=0) {
strcpy(g_FIELDTBLS32,FIELDTBLS32);
g_FIELDTBLS32[strlen(FIELDTBLS32)]='0';
tuxputenv(FIELDTBLS32);
}
}
RedoStr=(*it).second.members;
RedotheView.clear();
RedotheView=(*it).second.RedotheView;
gview.theView=RedotheView;
return 0;
}
Redoflag=-1;
return -1;
}