📄 parsercategory.cxx
字号:
#if defined(HAVE_CONFIG_H)#include "resip/stack/config.hxx"#endif#include "resip/stack/HeaderFieldValue.hxx"#include "resip/stack/ParserCategory.hxx"#include "rutil/ParseBuffer.hxx"#include "resip/stack/SipMessage.hxx"#include "rutil/DataStream.hxx"#include "rutil/ParseBuffer.hxx"#include "rutil/compat.hxx"#include "resip/stack/UnknownParameter.hxx"#include "resip/stack/ExtensionParameter.hxx"#include <iostream>#include <cassert>#include "rutil/Logger.hxx"#define RESIPROCATE_SUBSYSTEM Subsystem::SIP#include "rutil/WinLeakCheck.hxx"using namespace resip;using namespace std;const ParserCategory::ParameterTypeSet ParserCategory::EmptyParameterTypeSet; ParserCategory::ParserCategory(HeaderFieldValue* headerFieldValue, Headers::Type headerType) : LazyParser(headerFieldValue), mParameters(), mUnknownParameters(), mHeaderType(headerType){}ParserCategory::ParserCategory() : LazyParser(), mHeaderType(Headers::NONE){}ParserCategory::ParserCategory(const ParserCategory& rhs) : LazyParser(rhs), mHeaderType(rhs.mHeaderType){ if (isParsed()) { copyParametersFrom(rhs); }}ParserCategory&ParserCategory::operator=(const ParserCategory& rhs){ if (this != &rhs) { clear(); mHeaderType = rhs.mHeaderType; LazyParser::operator=(rhs); if (rhs.isParsed()) { copyParametersFrom(rhs); } } return *this;}voidParserCategory::clear(){ //DebugLog(<<"ParserCategory::clear"); LazyParser::clear(); for (ParameterList::iterator it = mParameters.begin(); it != mParameters.end(); it++) { delete *it; } mParameters.clear(); for (ParameterList::iterator it = mUnknownParameters.begin(); it != mUnknownParameters.end(); it++) { delete *it; } mUnknownParameters.clear();}void ParserCategory::copyParametersFrom(const ParserCategory& other){ for (ParameterList::iterator it = other.mParameters.begin(); it != other.mParameters.end(); it++) { mParameters.push_back((*it)->clone()); } for (ParameterList::iterator it = other.mUnknownParameters.begin(); it != other.mUnknownParameters.end(); it++) { mUnknownParameters.push_back((*it)->clone()); }}ParserCategory::~ParserCategory(){ clear();}const Data&ParserCategory::param(const ExtensionParameter& param) const{ checkParsed(); Parameter* p = getParameterByData(param.getName()); if (!p) { InfoLog(<< "Referenced an unknown parameter " << param.getName()); throw Exception("Missing unknown parameter", __FILE__, __LINE__); } return static_cast<UnknownParameter*>(p)->value();}Data&ParserCategory::param(const ExtensionParameter& param){ checkParsed(); Parameter* p = getParameterByData(param.getName()); if (!p) { p = new UnknownParameter(param.getName()); mUnknownParameters.push_back(p); } return static_cast<UnknownParameter*>(p)->value();}boolParserCategory::exists(const ParamBase& paramType) const{ checkParsed(); bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL; return ret;}// removing non-present parameter is allowed voidParserCategory::remove(const ParamBase& paramType){ checkParsed(); removeParameterByEnum(paramType.getTypeNum());}void ParserCategory::remove(const ExtensionParameter& param){ checkParsed(); removeParameterByData(param.getName());}bool ParserCategory::exists(const ExtensionParameter& param) const{ checkParsed(); return getParameterByData(param.getName()) != NULL;}void ParserCategory::removeParametersExcept(const ParameterTypeSet& set){ checkParsed(); for (ParameterList::iterator it = mParameters.begin(); it != mParameters.end();) { if (set.find((*it)->getType()) == set.end()) { delete *it; it = mParameters.erase(it); } else { ++it; } }}voidParserCategory::parseParameters(ParseBuffer& pb){ while (!pb.eof() ) { const char* start = pb.position(); pb.skipWhitespace(); if ( (!pb.eof() && *pb.position() == Symbols::SEMI_COLON[0]) ) { // extract the key pb.skipChar(); const char* keyStart = pb.skipWhitespace(); const char* keyEnd = pb.skipToOneOf(" \t\r\n;=?>"); //!dlb! @ here? if((int)(keyEnd-keyStart) != 0) { ParameterTypes::Type type = ParameterTypes::getType(keyStart, (keyEnd - keyStart)); if (type == ParameterTypes::UNKNOWN) { mUnknownParameters.push_back(new UnknownParameter(keyStart, int((keyEnd - keyStart)), pb, " \t\r\n;?>")); } else { // invoke the particular factory mParameters.push_back(ParameterTypes::ParameterFactories[type](type, pb, " \t\r\n;?>")); } } } else { pb.reset(start); return; } }} static Data up_Msgr("msgr");ostream&ParserCategory::encodeParameters(ostream& str) const{ for (ParameterList::iterator it = mParameters.begin(); it != mParameters.end(); it++) {#if 0 // !cj! - may be wrong just hacking // The goal of all this is not to add a tag if the tag is empty ParameterTypes::Type type = (*it)->getType(); if ( type == ParameterTypes::tag ) { Parameter* p = (*it); DataParameter* d = dynamic_cast<DataParameter*>(p); Data& data = d->value(); if ( !data.empty() ) { str << Symbols::SEMI_COLON; // !ah! this is a TOTAL hack to work around an MSN bug that // !ah! requires a SPACE after the SEMI following the MIME type. if (it == mParameters.begin() && getParameterByData(up_Msgr)) { str << Symbols::SPACE; } (*it)->encode(str); } } else { str << Symbols::SEMI_COLON; // !ah! this is a TOTAL hack to work around an MSN bug that // !ah! requires a SPACE after the SEMI following the MIME type. if (it == mParameters.begin() && getParameterByData(up_Msgr)) { str << Symbols::SPACE; } (*it)->encode(str); } #else str << Symbols::SEMI_COLON; // !ah! this is a TOTAL hack to work around an MSN bug that // !ah! requires a SPACE after the SEMI following the MIME type. if (it == mParameters.begin() && getParameterByData(up_Msgr)) { str << Symbols::SPACE; } (*it)->encode(str);#endif } for (ParameterList::iterator it = mUnknownParameters.begin(); it != mUnknownParameters.end(); it++) { str << Symbols::SEMI_COLON; (*it)->encode(str); } return str;}ostream&resip::operator<<(ostream& stream, const ParserCategory& category){ category.checkParsed(); return category.encode(stream);}Parameter* ParserCategory::getParameterByEnum(ParameterTypes::Type type) const{ for (ParameterList::iterator it = mParameters.begin(); it != mParameters.end(); it++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -