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

📄 sdpparser.cpp

📁 跨操作系统的微型中间件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "SdpParser.h"
#include "StrOperation.h"
#include <ctype.h>

#define CSDP_BUFFER_SIZE	10240
void TestSdpParser()
{
	FILE *sdpFile = fopen("e:\\movies\\test01.sdp", "rb");
	if(sdpFile == NULL)
		return;

	int nFileSize = 
		fseek(sdpFile,0,SEEK_END);
	nFileSize = ftell(sdpFile);
	
	char *pBuf = new char[nFileSize];
	memset(pBuf, 0, nFileSize);

	fseek(sdpFile, 0, SEEK_SET);
	fread(pBuf, 1, nFileSize, sdpFile);

	CSdpParser sdpParser;
	sdpParser.SetAndParser(string(pBuf, nFileSize));


	string sdp = sdpParser.GetSdp();

//	printf("\n%s\n", sdp.c_str());

	delete [] pBuf;
	fclose(sdpFile);
}

//////////////////////////////////////////////////////////////////////////
void CSdpLineItem::SetAndParserALine(const string& strALine)
{
	if(strALine.empty())
		return;

	m_strKey = strALine[0];
	if(m_strKey == "a" ||
	   m_strKey == "k")
	{
		m_hasAttribute = TRUE;
	}
	else
	{
		m_hasAttribute = FALSE;
	}

	int nPos = 0;
	if(m_hasAttribute)
	{
		m_strAttribute = CStrOperate::GetKeyValue(strALine, "=", ":", nPos);
		nPos = 0;
		m_strValue = CStrOperate::GetKeyValue(strALine, ":", "\r\n", nPos);
	}
	else
	{
		nPos = 0;
		m_strValue = CStrOperate::GetKeyValue(strALine, "=", "\r\n", nPos);
	}
}

string& CSdpLineItem::GetAndSetKey(const string strKey/*=""*/) 
{
	if(!strKey.empty()) 
		m_strKey = strKey;
	return m_strKey; 
}

string& CSdpLineItem::GetAndSetAttribute(const string strAttr/* ="" */)
{
	if(!strAttr.empty())
	{
		m_hasAttribute = TRUE;
		m_strAttribute = strAttr;
	}
	return m_strAttribute; 
}

string& CSdpLineItem::GetAndSetValue(const string strVal/* ="" */)
{
	if(!strVal.empty()) 
		m_strValue = strVal;
	return m_strValue; 
}

string CSdpLineItem::GetThisLine()
{
	string tmp;
	tmp = m_strKey + "=";
	if(m_hasAttribute)
	{
		tmp += m_strAttribute + ":";
	}
	tmp += m_strValue + "\r\n";

	return tmp;
}

Bool CSdpLineItem::operator == (const CSdpLineItem& other)
{
	if(m_strKey == other.m_strKey)
	{
		if(m_hasAttribute == TRUE && other.m_hasAttribute == TRUE)
		{
			if(m_strAttribute == other.m_strAttribute)
				return TRUE;
		}
		else if(m_hasAttribute == FALSE && other.m_hasAttribute == FALSE)
			return TRUE;
		else
			return FALSE;
	}

	return FALSE;
}

//////////////////////////////////////////////////////////////////////////
CSdpMediaAnnounceItem::~CSdpMediaAnnounceItem()
{
	vector<CSdpLineItem*>::iterator it;
	for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
	{
		delete *it;
		*it = NULL;
	}
}

void CSdpMediaAnnounceItem::AddALine(CSdpLineItem* pLineItem)
{
	if(pLineItem != NULL)
	{
		if( pLineItem->GetAndSetKey() == "m" )
		{
			// GET THE PAYLOAD
			// m=<media> <port> <transport> <fmt list>
			char cBuff1[50]; UInt32  fmt=0xFFFFFFFF;
			memset(cBuff1,0,sizeof(cBuff1));
			const char* pValue = pLineItem->GetAndSetValue().c_str();
			sscanf(pValue,"%s %s %s %u",cBuff1,cBuff1,cBuff1,&fmt);
			m_uiPayload = fmt;
		}
		m_vecLines.push_back(pLineItem);
	}
}

void CSdpMediaAnnounceItem::AddAline(const string& strLine)
{
	CSdpLineItem *pLineItem = new CSdpLineItem;
	pLineItem->SetAndParserALine(strLine);
	AddALine(pLineItem);
}


string CSdpMediaAnnounceItem::GetMediaAnnouce()
{
	string tmp;
	vector<CSdpLineItem*>::iterator it;
	CSdpLineItem *pLineItem = NULL;
	for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
	{
		pLineItem = *it;
		tmp += pLineItem->GetThisLine();
	}

	return tmp;
}

void CSdpMediaAnnounceItem::ModifyALine(const string& strLine)
{
	CSdpLineItem *pNewItem = new CSdpLineItem;
	pNewItem->SetAndParserALine(strLine);
	
	CSdpLineItem *pItem = NULL;
	vector<CSdpLineItem*>::iterator it;
	for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
	{
		pItem = *it;
		if(*pItem == *pNewItem)
		{
			pItem->GetAndSetValue(pNewItem->GetAndSetValue());
			delete pNewItem;
			pNewItem = NULL;
			return;
		}
	}

	m_vecLines.push_back(pNewItem);
}

UInt32 CSdpMediaAnnounceItem::GetTrackID()
{
	string tmpStr;
	int nPos = 0;
	CSdpLineItem *pItem = NULL;
	vector<CSdpLineItem*>::iterator it;
	for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
	{
		pItem = *it;
		if(pItem->GetAndSetKey() == "a" && pItem->GetAndSetAttribute() == "control")
		{
			tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "TrackID=", " ", nPos);
			break;
		}
	}
	
	return atol(tmpStr.c_str());
}

string CSdpMediaAnnounceItem::GetMediaType()
{
	string tmpStr;
	int nPos = 0;
	CSdpLineItem *pItem = NULL;
	vector<CSdpLineItem*>::iterator it;
	for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
	{
		pItem = *it;
		if(pItem->GetAndSetKey() == "m")
		{
			tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "", " ", nPos);
			break;
		}
	}

	return tmpStr;
}

UInt32 CSdpMediaAnnounceItem::GetTimeScale()
{
	string tmpStr;
	int nPos = 0;
	CSdpLineItem *pItem = NULL;
	vector<CSdpLineItem*>::iterator it;
	for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
	{
		pItem = *it;
		if(pItem->GetAndSetKey() == "a" && pItem->GetAndSetAttribute() == "rtpmap")
		{
			tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "/", "/", nPos);
			break;
		}
	}
	
	return atol(tmpStr.c_str());
}

UInt16 CSdpMediaAnnounceItem::GetDestPort()
{
	string tmpStr;
	int nPos = 0;
	CSdpLineItem *pItem = NULL;
	vector<CSdpLineItem*>::iterator it;
	for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
	{
		pItem = *it;
		if(pItem->GetAndSetKey() == "m")
		{
			tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), " ", " ", nPos);
			break;
		}
	}
	
	return atol(tmpStr.c_str());
}
// added by samsmith
string CSdpParser::GetGeneralDestIP()
{
	string tmpStr;
	int nPos = 0;
	CSdpLineItem *pItem = NULL;
	ITEM_LIST::iterator it;
	for(it=m_vecGeneralLines.begin(); it!=m_vecGeneralLines.end(); ++it)
	{
		pItem = *it;
		if(pItem->GetAndSetKey() == "c")
		{
			char ip[32];UInt16 ttl;
			memset(ip,0,sizeof(ip));
			ParserConnectData(pItem->GetAndSetValue().c_str(),ip,&ttl);
			tmpStr = ip;
			break;

		}
	}
	
	return tmpStr;
}
string CSdpMediaAnnounceItem::GetDestIP(unsigned short *v_ttl)
{
	string tmpStr;
	int nPos = 0;
	CSdpLineItem *pItem = NULL;
	vector<CSdpLineItem*>::iterator it;
	for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
	{
		pItem = *it;
		if(pItem->GetAndSetKey() == "c")
		{
			char ip[32];UInt16 ttl;
			memset(ip,0,sizeof(ip));
			ParserConnectData(pItem->GetAndSetValue().c_str(),ip,&ttl);
			tmpStr = ip;
			*v_ttl = ttl;
			break;
		}
	}
	
	return tmpStr;
}
bool ParserConnectData(const char* item,char *v_ip,unsigned short *v_ttl)
{	
	char cBuff1[50],cBuff2[50];
	memset(cBuff1,0,sizeof(cBuff1));
	memset(cBuff2,0,sizeof(cBuff2));
	sscanf(item,"%s %s %s",cBuff1,cBuff1,cBuff2);
	
	char *p;
	p=::strchr(cBuff2,'/');
	if( p== NULL) 
	{
		::strcpy(v_ip,cBuff2);
		*v_ttl=0;
	} 
	else {
		::strncpy(v_ip,cBuff2,p-cBuff2);
		v_ip[p-cBuff2]=0;
		unsigned int ttl=0;
		sscanf(p+1,"%u",&ttl);
		*v_ttl = (unsigned short)ttl;
	}
	return TRUE;
}
// end
string CSdpMediaAnnounceItem::GetDestIP()
{
	string tmpStr;
	int nPos = 0;
	CSdpLineItem *pItem = NULL;
	vector<CSdpLineItem*>::iterator it;
	for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
	{
		pItem = *it;
		if(pItem->GetAndSetKey() == "c")
		{
			tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "IN IP4 ", "/", nPos);
			break;
		}
	}
	
	return tmpStr;
}

//////////////////////////////////////////////////////////////////////////
void CSdpParser::Reset()
{
	ITEM_LIST::iterator it;
	for(it=m_vecGeneralLines.begin(); it!=m_vecGeneralLines.end(); ++it)
	{
		// for test modify by samsmith
		CSdpLineItem* pItem = *it;
		delete pItem;
		*it = NULL;
	}
//		m_mtxSdpParser.Lock();
	m_vecGeneralLines.clear();
	//	m_mtxSdpParser.Unlock();

	vector<CSdpMediaAnnounceItem*>::iterator it2;
	for(it2=m_vecMediaAnnounces.begin(); it2!=m_vecMediaAnnounces.end(); ++it2)
	{
		delete *it2;
		*it2 = NULL;
	}
	m_vecMediaAnnounces.clear();
	
}
CSdpParser::~CSdpParser()
{
	Reset();
}

Bool CSdpParser::SetAndParserFromFile(const string& strFileName)
{
	
	if(CStrOperate::GetExtName(strFileName) != "sdp")
		return FALSE;

	FILE *File=fopen(strFileName.c_str(),"rb");
	//Assert( File > 0 );
	if(File == NULL)
	{
		return FALSE;
	}
	
	//char cBuff[CSDP_BUFFER_SIZE];
	char *pBuff = new char [CSDP_BUFFER_SIZE];
	if(!pBuff) 
	{
		fclose(File);
		return FALSE;
	}
	memset(pBuff, 0, CSDP_BUFFER_SIZE);
	
	UInt32 iLen=fread(pBuff,CSDP_BUFFER_SIZE,1,File);
	if(iLen ==0) iLen=ftell(File);
	fclose(File);
	
	// add by samsmith
	//SetAndParser(pBuff);
	std::string  strConvert( pBuff );
	CStrOperate::ConvertUnixToDos(strConvert);
	delete[] pBuff;
	SetAndParser(strConvert);
	// end

	return TRUE;
}

void CSdpParser::SetAndParser(const string& strSdp)
{
	
	
	if(strSdp.empty())
		return;
	
	list<CSdpLineItem*> lstSdpLines;

	CSdpLineItem *pLineItem = NULL;
	string strLine;
	int nBeginPos = 0;
	string strLineEndMark = "\r\n";
	do
	{
		strLine = CStrOperate::GetKeyValue(strSdp, "", strLineEndMark, nBeginPos);
		nBeginPos += strLineEndMark.size();
		if(!strLine.empty())
		{
			pLineItem = new CSdpLineItem;
			if(pLineItem == NULL)
				break;
			pLineItem->SetAndParserALine(strLine);
			lstSdpLines.push_back(pLineItem);
		}
	}while (!strLine.empty());

	list<CSdpLineItem*>::iterator lstIt = lstSdpLines.begin();
	while(lstIt != lstSdpLines.end())
	{
		pLineItem = *lstIt;
		if(pLineItem->GetAndSetKey() != "m")
		{
//				m_mtxSdpParser.Lock();
			m_vecGeneralLines.push_back(pLineItem);
			//		m_mtxSdpParser.Unlock();
			lstSdpLines.pop_front();
//			printf("G:%s\n", pLineItem->GetAndSetValue().c_str());
		}
		else
		{
			break;
		}

		lstIt = lstSdpLines.begin();
	}

	CSdpMediaAnnounceItem *pMediaItem = NULL;
	
	while(!lstSdpLines.empty())
	{
		lstIt = lstSdpLines.begin();

⌨️ 快捷键说明

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