⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 servicedataqueue.cppbk

📁 基于dialogic语音卡的IVR系统源代码
💻 CPPBK
📖 第 1 页 / 共 3 页
字号:
}

int CServiceDataQueue::AddParamListMember_VoiceList(struct ParamList *pParamList, struct VoiceList *pvoiceList, char *szParamName)
{
/*****************************************************
增加一个VOICELIST参数到参数列表的末尾
和队列本身的成员无关,不用锁
*****************************************************/
int iCount;
int iOffset;

	pParamList->nCount ++;
	iCount = pParamList->nCount;
	iOffset = iCount - 1;
	pParamList->pParam = (struct Param *)realloc(pParamList->pParam, iCount * sizeof(struct Param));
	(pParamList->pParam)[iOffset].iType = PARAMTYPE_VOICELIST;
	if(szParamName == NULL)
	{
		memset((pParamList->pParam)[iOffset].aszParamName, 0, sizeof((pParamList->pParam)[iOffset].aszParamName));
	}
	else
	{
		if(strlen(szParamName) + 1 > sizeof((pParamList->pParam)[iOffset].aszParamName))
			return -1;
		strcpy((pParamList->pParam)[iOffset].aszParamName, szParamName);
	}
	(pParamList->pParam)[iOffset].pParam = pvoiceList;

	return(0);
}

int CServiceDataQueue::AddParamListMember_ResultSet(struct ParamList *pParamList, struct ResultSet *presultSet, char *szParamName)
{
/*****************************************************
增加一个RESULTSET参数到参数列表的末尾
和队列本身的成员无关,不用锁
*****************************************************/
int iCount;
int iOffset;

	pParamList->nCount ++;
	iCount = pParamList->nCount;
	iOffset = iCount - 1;
	pParamList->pParam = (struct Param *)realloc(pParamList->pParam, iCount * sizeof(struct Param));
	(pParamList->pParam)[iOffset].iType = PARAMTYPE_RESULTSET;
	(pParamList->pParam)[iOffset].iSize = sizeof(struct ResultSet *);
	if(szParamName == NULL)
	{
		memset((pParamList->pParam)[iOffset].aszParamName, 0, sizeof((pParamList->pParam)[iOffset].aszParamName));
	}
	else
	{
		if(strlen(szParamName) + 1 > sizeof((pParamList->pParam)[iOffset].aszParamName))
			return -1;
		strcpy((pParamList->pParam)[iOffset].aszParamName, szParamName);
	}
	//因为presultSet指针在下一次被重新赋值时才会被释放(一般发生在下一次CALLSERVICE时),所以使用指针是安全的
	(pParamList->pParam)[iOffset].pParam = presultSet;

	return(0);
}

int CServiceDataQueue::AddParamListMember_Bin(struct ParamList *pParamList, char *pData, int iLen, char *szParamName)
{
/*****************************************************
增加一个BINARY参数到参数列表的末尾
和队列本身的成员无关,不用锁
*****************************************************/
int iCount;
int iOffset;

	pParamList->nCount ++;
	iCount = pParamList->nCount;
	iOffset = iCount - 1;
	pParamList->pParam = (struct Param *)realloc(pParamList->pParam, iCount * sizeof(struct Param));
	(pParamList->pParam)[iOffset].iType = PARAMTYPE_BINARY;
	(pParamList->pParam)[iOffset].iSize = iLen;
	if(szParamName == NULL)
	{
		memset((pParamList->pParam)[iOffset].aszParamName, 0, sizeof((pParamList->pParam)[iOffset].aszParamName));
	}
	else
	{
		if(strlen(szParamName) + 1 > sizeof((pParamList->pParam)[iOffset].aszParamName))
			return -1;
		strcpy((pParamList->pParam)[iOffset].aszParamName, szParamName);
	}
	char *pBinData = (char *)malloc(iLen);
	memcpy(pBinData, pData, iLen);
	(pParamList->pParam)[iOffset].pParam = pBinData;

	return(0);
}

int CServiceDataQueue::DumpToBuffer(struct ParamList *pParamList, char **ppBuffer, int *piLength)
{
/*********************************************************
功能:	将结构指针的数据(即ParamList的成员pParam)存放到内存块中
		对于字符串型变量,如果是空字符或长度为0,就在生成的BUFFER中申请一个字节,放0

参数:	
返回:	0	成功
		-1	失败
*********************************************************/
int iTotalLen = 0;
int iLen_RESULTSET;
int i;

	//计算总长度
	////表内容的总长度
	for(i = 0; i < pParamList->nCount; i ++)
	{
		int iParamType = (pParamList->pParam)[i].iType;
		//数据小包头长度
		iTotalLen += sizeof(Header_TableUnit);
		////变量名长度
		iTotalLen += strlen((pParamList->pParam)[i].aszParamName);
		switch(iParamType)
		{
			case PARAMTYPE_INT:
			case PARAMTYPE_FLOAT:
			case PARAMTYPE_STRING:
			case PARAMTYPE_BINARY:
				//变量长度
				iTotalLen += (pParamList->pParam)[i].iSize;
				break;

			case PARAMTYPE_RESULTSET:
				//计算RESULTSET的长度
				iLen_RESULTSET = CResultSet::CalculateSize((struct ResultSet *)(pParamList->pParam)[i].pParam);
				if(iLen_RESULTSET <= 0)
				{
					AfxMessageBox("DumpToBuffer()计算RESULTSET长度出错");
					return -1;
				}
				iTotalLen += iLen_RESULTSET;
				break;

			case PARAMTYPE_VOICELIST:
				AfxMessageBox("DumpToBuffer 不支持VOICELIST类型");
				break;

			default:
				break;
		}//end of switch()
	}//end of for()
	////增加参数表头
	iTotalLen += sizeof(struct Header_Table);	//参见数据表头结构(struct Header_Table)定义

	//产生内存块
	char *pBuffer = (char *)malloc(iTotalLen);
	pBuffer += sizeof(struct Header_Table);	//将指针移到表头后面
	int iOffset = 0;
	for(i = 0; i < pParamList->nCount; i ++)
	{
		int iParamType = (pParamList->pParam)[i].iType;
		struct Header_TableUnit *pheader_TableUnit = (struct Header_TableUnit *)(pBuffer + iOffset);
		//数据类型
		pheader_TableUnit->byteType = (pParamList->pParam)[i].iType;
		//变量名长度
		pheader_TableUnit->uiLength_Name = strlen((pParamList->pParam)[i].aszParamName);
		switch(iParamType)
		{
			case PARAMTYPE_INT:
			case PARAMTYPE_FLOAT:
			case PARAMTYPE_STRING:
			case PARAMTYPE_BINARY:

				pheader_TableUnit->uiLength_Data = (pParamList->pParam)[i].iSize;
				iOffset += sizeof(struct Header_TableUnit);
				
				//变量名内容
				memcpy(pBuffer + iOffset, (pParamList->pParam)[i].aszParamName, strlen((pParamList->pParam)[i].aszParamName));
				iOffset += strlen((pParamList->pParam)[i].aszParamName);
				
				//变量数据内容
				memcpy(pBuffer + iOffset, (pParamList->pParam)[i].pParam, (pParamList->pParam)[i].iSize);
				iOffset += (pParamList->pParam)[i].iSize;
				break;

			case PARAMTYPE_RESULTSET:
				char *pBuffer_ResultSet;
				int iLength_ResultSet;
				CResultSet::DumpToBuffer((struct ResultSet *)(pParamList->pParam)[i].pParam, &pBuffer_ResultSet, &iLength_ResultSet);
				//ResultSet的数据长度
				pheader_TableUnit->uiLength_Data = iLength_ResultSet;
				iOffset += sizeof(struct Header_TableUnit);

				//变量名内容
				memcpy(pBuffer + iOffset, (pParamList->pParam)[i].aszParamName, strlen((pParamList->pParam)[i].aszParamName));
				iOffset += strlen((pParamList->pParam)[i].aszParamName);
				
				//RESULTSET内容
				memcpy(pBuffer + iOffset, pBuffer_ResultSet, iLength_ResultSet);
				free(pBuffer_ResultSet);
				iOffset += iLength_ResultSet;
				break;

			case PARAMTYPE_VOICELIST:
				AfxMessageBox("DumpToBuffer 不支持VOICELIST类型");
				break;

			default:
				break;
		}//end of switch()
	}//end of for()
	pBuffer = pBuffer - sizeof(struct Header_Table);	//再将指针移到表头
	////填写表头
	((struct Header_Table *)pBuffer)->uiCol = pParamList->nCount;
	((struct Header_Table *)pBuffer)->uiRow = 1;
	((struct Header_Table *)pBuffer)->uiLength = iTotalLen - sizeof(struct Header_Table);

	//填写返回参数
	*ppBuffer = pBuffer;
	*piLength = iTotalLen;

	return 0;
}

int CServiceDataQueue::BirthFromBuffer(char *pBuffer, int iLength, struct ParamList **ppParamList)
{
/*********************************************************
功能:	将内存块中的数据转换为结构指针
		对于字符串型变量,如果是空字符或长度为0,就在生成的PARAMLIST中申请一个字节,放0
参数:	
返回:	0	成功
		-1	失败
*********************************************************/
struct ParamList *pParamList = NULL;
struct Header_Table *pheader_Table = (struct Header_Table *)pBuffer;
struct Header_TableUnit *pheader_TableUnit;
int iOffset = 0/*处理完当前TABLEUNIT之后指针的偏移量*/, 
	iOffset_Predict/*处理当前TABLEUNIT之前预先计算出在处理之后的指针的偏移量*/ = 0, 
	i = 0;
int iType, iParamCount;

	if(iLength != pheader_Table->uiLength + sizeof(struct Header_Table))
	{//包错误
		goto ERROROUT;
	}
	CreateParamList(&pParamList, 0, 0, 0, 0);
	iParamCount = pheader_Table->uiCol;
	struct ResultSet *presultSet;
	iOffset = sizeof(struct Header_Table);
	iOffset_Predict = iOffset;
	char *pData;
	
	for(i = 0; i < iParamCount; i ++)
	{
		//检查将要处理的HEADER_TABLEUNIT的的数据长度的合法性
		if(iOffset + sizeof(struct Header_TableUnit) > iLength)
		{//包错误
			goto ERROROUT;
		}
		pheader_TableUnit = (struct Header_TableUnit *)(pBuffer + iOffset);
		iType = pheader_TableUnit->byteType;
		pData = pBuffer + iOffset + sizeof(struct Header_TableUnit) + pheader_TableUnit->uiLength_Name;
		iOffset_Predict = iOffset + sizeof(struct Header_TableUnit) + pheader_TableUnit->uiLength_Name + pheader_TableUnit->uiLength_Data;
		//检查将要处理的TABLEUNIT的的数据长度的合法性
		if(iOffset_Predict > iLength)
		{//包错误
			goto ERROROUT;
		}
		switch(iType)
		{
		case PARAMTYPE_INT:
			if(pheader_TableUnit->uiLength_Data != sizeof(int))
				goto ERROROUT;
			if(AddParamListMember_Integer(pParamList, *(int *)pData) != 0)
				goto ERROROUT;
			break;

		case PARAMTYPE_FLOAT:
			if(pheader_TableUnit->uiLength_Data != sizeof(float))
				goto ERROROUT;
			if(AddParamListMember_Float(pParamList, *(float *)pData) != 0)
				goto ERROROUT;
			break;

		case PARAMTYPE_STRING:
			if(AddParamListMember_String2(pParamList, (char *)pData, pheader_TableUnit->uiLength_Data) != 0)
				goto ERROROUT;
			break;
			
		case PARAMTYPE_BINARY:
			if(AddParamListMember_Bin(pParamList, (char *)pData, pheader_TableUnit->uiLength_Data) != 0)
				goto ERROROUT;
			break;
			
		case PARAMTYPE_RESULTSET:
			if(CResultSet::BirthFromBuffer(pData, pheader_TableUnit->uiLength_Data, &presultSet) != 0)
				goto ERROROUT;
			if(AddParamListMember_ResultSet(pParamList, presultSet) != 0)
				goto ERROROUT;
			break;

		default:
			goto ERROROUT;
			break;
			
		}//end of switch()

		iOffset = iOffset_Predict;
	}//end of for()
	if(iOffset != pheader_Table->uiLength + sizeof(struct Header_Table))
	{//包错误
		goto ERROROUT;
	}

	//填写返回参数
	*ppParamList = pParamList;

	return 0;

ERROROUT:
	if(pParamList != NULL)
	{
		FreeParamList(pParamList);
	}
	return -1;
}

int CServiceDataQueue::SaveRequestInfo(struct ParamList *pParamList, char *szPacketID, UINT uiTimerID)
{
/*******************************************************
功能:	保存请求参数(不包括其中的pParam)和请求包ID的对照表
返回:	0	成功
		-1	失败
*******************************************************/
	if( m_Lock.Lock() != 0 )
	{//上锁
		AfxMessageBox("SaveRequest() can't lock");
		return(-2);
	}

	struct RequestInfo *prequestInfo = (struct RequestInfo *)malloc(sizeof(struct RequestInfo));

	prequestInfo->ParamList.bIsIVR = pParamList->bIsIVR;
	prequestInfo->ParamList.iChannelNo = pParamList->iChannelNo;
	prequestInfo->ParamList.iServiceNo = pParamList->iServiceNo;
	prequestInfo->ParamList.iServiceType = pParamList->iServiceType;
	prequestInfo->ParamList.ISN = pParamList->ISN;
	prequestInfo->ParamList.nCount = pParamList->nCount;

	prequestInfo->uiTimerID = uiTimerID;

	memcpy(prequestInfo->aszPacketID, szPacketID, sizeof(prequestInfo->aszPacketID));

	m_ptrListRequestInfo.AddTail(prequestInfo);

	if( m_Lock.Unlock() != 0 )
	{//解锁
		AfxMessageBox("SaveRequest() can't unlock");
		return(-1);
	}

	return 0;
}

int CServiceDataQueue::FindRequestInfo(char *szPacketID, struct ParamList &ParamList, UINT &uiTimerID)
{
/*******************************************************
功能:	通过请求包ID来查找保存的请求参数(不包括其中的pParam)
		并删除这条记录
返回:	0	找到
		-1	没找到
*******************************************************/
int iReturnCode = 0;

	if( m_Lock.Lock() != 0 )
	{//上锁
		AfxMessageBox("FindRequestInfo() can't lock");
		return(-2);
	}

	int iCount = m_ptrListRequestInfo.GetCount();
	for(int i = 0; i < iCount; i ++)
	{
		struct RequestInfo *prequestInfo = (struct RequestInfo *)m_ptrListRequestInfo.GetAt(m_ptrListRequestInfo.FindIndex(i));
		if(memcmp(prequestInfo->aszPacketID, szPacketID, LEN_STRUCT_HEADER_ROUTE_PACKETID) == 0)
		{
			ParamList.bIsIVR = prequestInfo->ParamList.bIsIVR;
			ParamList.iChannelNo = prequestInfo->ParamList.iChannelNo;
			ParamList.iServiceNo = prequestInfo->ParamList.iServiceNo;
			ParamList.iServiceType = prequestInfo->ParamList.iServiceType;
			ParamList.ISN = prequestInfo->ParamList.ISN;
			ParamList.nCount = prequestInfo->ParamList.nCount;

			uiTimerID = prequestInfo->uiTimerID;

			//删除这条记录
			free(m_ptrListRequestInfo.GetAt(m_ptrListRequestInfo.FindIndex(i)));
			m_ptrListRequestInfo.RemoveAt(m_ptrListRequestInfo.FindIndex(i));

			break;
		}
	}

	if(i < iCount)
		iReturnCode = 0;
	else
		iReturnCode = -1;

	if( m_Lock.Unlock() != 0 )
	{//解锁
		AfxMessageBox("FindRequestInfo() can't unlock");
		return(-1);
	}

	return iReturnCode;
}

int CServiceDataQueue::FindRequestInfo_ByTimerID(UINT uiTimerID, struct ParamList &ParamList)
{
/*******************************************************
功能:	通过TIMERID来查找保存的请求参数(不包括其中的pParam)
		并删除这条记录
返回:	0	找到
		-1	没找到
*******************************************************/
int iReturnCode = 0;

	if( m_Lock.Lock() != 0 )
	{//上锁
		AfxMessageBox("FindRequestInfo() can't lock");
		return(-2);
	}

	int iCount = m_ptrListRequestInfo.GetCount();
	for(int i = 0; i < iCount; i ++)
	{
		struct RequestInfo *prequestInfo = (struct RequestInfo *)m_ptrListRequestInfo.GetAt(m_ptrListRequestInfo.FindIndex(i));
		if(prequestInfo->uiTimerID == uiTimerID)
		{
			ParamList.bIsIVR = prequestInfo->ParamList.bIsIVR;
			ParamList.iChannelNo = prequestInfo->ParamList.iChannelNo;
			ParamList.iServiceNo = prequestInfo->ParamList.iServiceNo;
			ParamList.iServiceType = prequestInfo->ParamList.iServiceType;
			ParamList.ISN = prequestInfo->ParamList.ISN;
			ParamList.nCount = prequestInfo->ParamList.nCount;

			//删除这条记录
			free(m_ptrListRequestInfo.GetAt(m_ptrListRequestInfo.FindIndex(i)));
			m_ptrListRequestInfo.RemoveAt(m_ptrListRequestInfo.FindIndex(i));

			break;
		}
	}

	if(i < iCount)
		iReturnCode = 0;
	else
		iReturnCode = -1;

	if( m_Lock.Unlock() != 0 )
	{//解锁
		AfxMessageBox("FindRequestInfo() can't unlock");
		return(-1);
	}

	return iReturnCode;
}

int CServiceDataQueue::FindRequestInfo_ByChannelNo(int iChannelNo, struct ParamList &ParamList)
{
/*******************************************************
功能:	通过请求包ID来查找保存的请求参数(不包括其中的pParam)
		并删除这条记录

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -