// #ZHB# int64 CppSQLite3Table::getInt64Field(int nField, int64 nNullValue/*=0*/) { if (fieldIsNull(nField)) { return nNullValue; } else { return atoint64(fieldValue(nField)); } }
int64 CppSQLite3Table::getInt64Field(const char* szField, int64 nNullValue/*=0*/) { if (fieldIsNull(szField)) { return nNullValue; } else { return atoint64(fieldValue(szField)); } }
/* 流式的处理特定CLinkerPipe接收到的信息,此函数对于理解本类非常重要, s为接收到的字节,或多或少 */ void CLinkerPipe::CompileMsg(const char* s, int32 size) { if(m_RecoType == LINKER_BAN)return; CLinkerPipe::RevContextInfo* Info = NULL; if( m_ContextStack.size() > 0 ){ Info = m_ContextStack.front(); //取出之前数据的处理信息 } else{ Info = new CLinkerPipe::RevContextInfo(&m_CurRevMsg); m_ContextStack.push_front(Info); } assert(Info != NULL); bool bCompleteOneData = FALSE; int i=0; while(i<size) { char ch = s[i++]; Info->InfoLen++; //在错误状态下将只关心是否有空管道出现 //在检测到空管道之前,根据要求,即使是出错的数据也将可能被保存起来,以便分析错误原因 if(m_bRevError) { if (Info->Buffer.size() < m_ErrorSaveLen) { Info->Buffer += ch; } if (ch == '@') { Info->DataLen ++; if (Info->DataLen ==ERROR_RESUME_LENGTH) { EndErrorState(Info); } }else{ Info->DataLen =0; } continue; } //正常状态 switch(Info->State){ case TYPE_PART: { Info->HeaderStr += ch; if( IsDataType(ch) && Info->DataType == -1){ Info->DataType = CHAR_TO_TYPE(ch); if(Info->DataType == TYPE_PIPELINE){ Info->Data = new ePipeline(); Info->ParentPipe->Push_Directly(Info->Data); } //不是PIPELINE但是第一个数据则报错,因为信息的第一个数据类型肯定是TYPE_PIPELINE else if(Info->ParentPipe == this ){ BeginErrorState(Info,ERROR_TYPE_PART); } else{ //其他类型则预先生成一个空数据 Info->Data = CreateEmptyData(Info->DataType); Info->ParentPipe->Push_Directly(Info->Data); } } //确定类型后,改变数据处理状态 else if(ch == '@' && Info->DataType != -1) { Info->State = (Info->DataType == TYPE_PIPELINE)?ID_PART : LENGTH_PART; Info->Buffer=""; Info->DataLen = NUMBER_LENGTH_LIMIT; } else{ BeginErrorState(Info,ERROR_TYPE_PART); } } break; case LENGTH_PART: { Info->HeaderStr += ch; // ch ->[0-9] 并且 单个数据长度不能超过10位整数 if(isdigit(ch) && Info->Buffer.size() < Info->DataLen) { Info->Buffer += ch; } else if(ch == '@' && Info->Buffer.size() >0) { Info->DataLen = atol(Info->Buffer.c_str()); Info->Buffer = ""; //初步检查长度的合理性 if(Info->DataType == TYPE_PIPELINE) { if (Info->ParentPipe == this) { } if(Info->DataLen == 0){ bCompleteOneData = TRUE; }else{ ePipeline NotifData; NotifData.PushInt(Info->DataLen); //总长度 NotifData.PushInt(0); //相对于Parent的完成进度,0则表示本Pipe刚开始 NotifData.Push_Directly(Info->Data->Clone()); m_Parent->NotifyLinkerState(this,LINKER_RECEIVE_STEP,NotifData); //对于管道,得到长度以后即压入堆栈,因为它的数据其实是其它数据的集合 Info->HeaderStr=""; ePipeline* Parent = (ePipeline*)Info->Data; assert(Parent); RevContextInfo* NewInfo = new RevContextInfo(Parent); m_ContextStack.push_front(NewInfo); Info = NewInfo; } break; }else if(Info->DataType == TYPE_NULL) { if(Info->DataLen != 0){ BeginErrorState(Info,ERROR_LENGTH_PART); }else{ bCompleteOneData = TRUE; } } else if(Info->DataLen ==0 ) { if(Info->DataType == TYPE_STRING){ //允许为0 bCompleteOneData = TRUE; } else{// 其他数据不能为0 error BeginErrorState(Info,ERROR_LENGTH_PART); } }else if ((Info->DataType==TYPE_INT || Info->DataType==TYPE_FLOAT) && Info->DataLen>20) { BeginErrorState(Info,ERROR_LENGTH_PART); } else{ Info->State = DATA_PART; //一切OK,准备开始处理数据本身 } } else{ BeginErrorState(Info,ERROR_LENGTH_PART); } } break; case DATA_PART: { Info->Buffer += ch; if( Info->Buffer.size() == Info->DataLen ){ Info->HeaderStr+=Info->Buffer; int32 n = Info->Data->FromString(Info->HeaderStr,0); assert(n!=0); bCompleteOneData = TRUE; } } break; case ID_PART: { // Info->HeaderStr += ch; // ch ->[0-9] 并且数据ID不能超过20位整数 if(isdigit(ch) && Info->Buffer.size() < Info->DataLen) { Info->Buffer += ch; } else if(ch == '@' && Info->Buffer.size() >0) { int64 ID = atoint64(Info->Buffer.c_str()); assert(Info->DataType == TYPE_PIPELINE); ePipeline* Data = (ePipeline*)Info->Data; Data->SetID(ID); Info->State = NAMELEN_PART; Info->Buffer = ""; Info->DataLen = DATA_LENGTH_LIMIT; } else{ BeginErrorState(Info,ERROR_ID_PART); } } break; case NAMELEN_PART: { // Info->HeaderStr += ch; // ch ->[0-9] 并且 不能超过10位整数 if(isdigit(ch) && Info->Buffer.size() < Info->DataLen) { Info->Buffer += ch; } else if(ch == '@' && Info->Buffer.size() >0) { uint32 len = atol(Info->Buffer.c_str()); Info->DataLen = len; Info->Buffer = ""; assert(Info->Buffer.size()==0); Info->State = NAME_PART; } else{ BeginErrorState(Info,ERROR_NAMELEN_PART); } } break; case NAME_PART: { // Info->HeaderStr += ch; // ch ->[0-9] 并且 不能超过约定位数 if(Info->Buffer.size() < Info->DataLen) { Info->Buffer += ch; } else if(ch == '@'){ eSTRING s; s.FromString(Info->Buffer,0); tstring Name = s; assert(Info->DataType == TYPE_PIPELINE); ePipeline* Data = (ePipeline*)Info->Data; Data->SetLabel(Name.c_str()); Info->Buffer = ""; Info->State = LENGTH_PART; Info->DataLen = DATA_LENGTH_LIMIT; } else{ BeginErrorState(Info,ERROR_NAME_PART); } } break; default: assert(0); break; } if(bCompleteOneData){ bCompleteOneData = FALSE; //处理得到的实际数据 while(m_ContextStack.size()){ //Info->ParentPipe->Push_Directly(Info->Data); int32 Len = Info->InfoLen; Energy* Data = Info->Data; if (m_ContextStack.size()>1) { RevContextInfo* PreInfo = m_ContextStack[1]; PreInfo->InfoLen += Len; PreInfo->DataLen -= Len; if (PreInfo->DataLen == 0) //已经完成一个嵌套Pipe,重复上述步骤 { ePipeline NotifData; NotifData.PushInt(Len); //总长度 NotifData.PushInt(PreInfo->InfoLen); //Parent Pipe已经完成的 NotifData.Push_Directly(Data->Clone()); m_Parent->NotifyLinkerState(this,LINKER_RECEIVE_STEP,NotifData); delete Info; m_ContextStack.pop_front(); Info = m_ContextStack.front(); assert(PreInfo == Info); }else if (PreInfo->DataLen > 0) //继续接收下一个数据 { Info->Reset(); break; }else{ //错误 BeginErrorState(Info,ERROR_OTHER_PARNT); Info->Reset(); } }else{ //已经完成一个完整信息的组装 assert(m_ContextStack.size()==1); assert(m_CurRevMsg.Size()==1); eElectron E; m_CurRevMsg.Pop(&E); RevOneMsg(E); assert(Info->ParentPipe == &m_CurRevMsg); Info->Reset(); break; } }//while } }//while }