[reSIProcate] multiple instances of the same parameter in a header
I am running into this situation in a SIP header:
FooHeader: value1;faz-param=45;faz-param=67;faz-param=89;faz-param=123;
And in the current code I have no way of walking through those separate
instances of the faz-param. Just calling
msg->header(h_FooHeader).param(p_faz_param) gives me the very first one,
with no way of getting to the others. So here is what I've done.
in ParserCategory, I gave an optional inst parameter to
getParameterByEnum and getParameterByData:
Parameter* getParameterByEnum(ParameterTypes::Type type, int inst = 0)
const;
Parameter* getParameterByData(const Data& data, int inst = 0) const;
I do the same for exists() and param() in ParserCategory and Token,
modifying the defineParam definition in Token accordingly. That is:
bool exists(const Param<Token>& paramType, int inst = 0) const;
const Data& param(const ExtensionParameter& param, int inst = 0) const;
This way, all the normal code stays the same, and you can call
msg->header(h_FooHeader).exists(p_faz_param) as always, but you can also
call msg->header(h_FooHeader).exists(p_faz_param, 3). Interestingly,
under the hood the multiple parameters were all stored just fine, there
was just no user-visible way to see them.
I only did the Token derived class, if anyone wants the other classes
derived from ParserCategory, it should be obvious how to do it (cut and
paste).
Four diff files attached from resip/stack, version 1.9.6.
-John Gregg
Index: ParserCategory.cxx
===================================================================
--- ParserCategory.cxx (revision 27855)
+++ ParserCategory.cxx (working copy)
@@ -131,10 +131,10 @@
}
const Data&
-ParserCategory::param(const ExtensionParameter& param) const
+ParserCategory::param(const ExtensionParameter& param, int inst) const
{
checkParsed();
- Parameter* p = getParameterByData(param.getName());
+ Parameter* p = getParameterByData(param.getName(), inst);
if (!p)
{
InfoLog(<< "Referenced an unknown parameter " << param.getName());
@@ -144,10 +144,10 @@
}
Data&
-ParserCategory::param(const ExtensionParameter& param)
+ParserCategory::param(const ExtensionParameter& param, int inst)
{
checkParsed();
- Parameter* p = getParameterByData(param.getName());
+ Parameter* p = getParameterByData(param.getName(), inst);
if (!p)
{
p = new UnknownParameter(param.getName());
@@ -172,10 +172,10 @@
}
bool
-ParserCategory::exists(const ExtensionParameter& param) const
+ParserCategory::exists(const ExtensionParameter& param, int inst) const
{
checkParsed();
- return getParameterByData(param.getName()) != NULL;
+ return getParameterByData(param.getName(), inst) != NULL;
}
void
@@ -332,14 +332,22 @@
}
Parameter*
-ParserCategory::getParameterByEnum(ParameterTypes::Type type) const
+ParserCategory::getParameterByEnum(ParameterTypes::Type type, int inst) const
{
+ int curr = 0;
for (ParameterList::const_iterator it = mParameters.begin();
it != mParameters.end(); it++)
{
if ((*it)->getType() == type)
{
- return *it;
+ if (curr == inst)
+ {
+ return *it;
+ }
+ else
+ {
+ curr++;
+ }
}
}
return 0;
@@ -387,14 +395,22 @@
}
Parameter*
-ParserCategory::getParameterByData(const Data& data) const
+ParserCategory::getParameterByData(const Data& data, int inst) const
{
+ int curr = 0;
for (ParameterList::const_iterator it = mUnknownParameters.begin();
it != mUnknownParameters.end(); it++)
{
if (isEqualNoCase((*it)->getName(), data))
{
- return *it;
+ if (curr == inst)
+ {
+ return *it;
+ }
+ else
+ {
+ curr++;
+ }
}
}
return 0;
Index: ParserCategory.hxx
===================================================================
--- ParserCategory.hxx (revision 27855)
+++ ParserCategory.hxx (working copy)
@@ -142,10 +142,10 @@
@param paramType The accessor token for the parameter.
@return true iff the parameter is present.
*/
- inline bool exists(const ParamBase& paramType) const
+ inline bool exists(const ParamBase& paramType, int inst = 0) const
{
checkParsed();
- return (getParameterByEnum(paramType.getTypeNum()) != NULL);
+ return (getParameterByEnum(paramType.getTypeNum(), inst) != NULL);
}
/**
@@ -162,7 +162,7 @@
@param param The runtime constructed parameter accessor.
@return The parameter, as a raw Data.
*/
- const Data& param(const ExtensionParameter& param) const;
+ const Data& param(const ExtensionParameter& param, int inst = 0) const;
/**
@brief Accessor for non-natively-supported parameter types.
@@ -170,7 +170,7 @@
@param param The runtime constructed parameter accessor.
@return The parameter, as a raw Data.
*/
- Data& param(const ExtensionParameter& param);
+ Data& param(const ExtensionParameter& param, int inst = 0);
/**
@brief Removes a non-natively-supported parameter, if the parameter is
@@ -184,7 +184,7 @@
@param param The runtime constructed accessor token.
@return true iff the parameter is present.
*/
- bool exists(const ExtensionParameter& param) const;
+ bool exists(const ExtensionParameter& param, int inst = 0) const;
typedef std::set<ParameterTypes::Type> ParameterTypeSet;
@@ -238,7 +238,7 @@
@internal
@brief Typeless parameter get interface.
*/
- Parameter* getParameterByEnum(ParameterTypes::Type type) const;
+ Parameter* getParameterByEnum(ParameterTypes::Type type, int inst = 0) const;
/**
@internal
@@ -266,7 +266,7 @@
protected:
ParserCategory(PoolBase* pool=0);
- Parameter* getParameterByData(const Data& data) const;
+ Parameter* getParameterByData(const Data& data, int inst = 0) const;
void removeParameterByData(const Data& data);
inline PoolBase* getPool()
{
Index: Token.cxx
===================================================================
--- Token.cxx (revision 27855)
+++ Token.cxx (working copy)
@@ -136,10 +136,10 @@
}
bool
-Token::exists(const Param<Token>& paramType) const
+Token::exists(const Param<Token>& paramType, int inst) const
{
checkParsed();
- bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL;
+ bool ret = getParameterByEnum(paramType.getTypeNum(), inst) != NULL;
return ret;
}
@@ -152,11 +152,11 @@
#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \
_enum##_Param::DType& \
-Token::param(const _enum##_Param& paramType) \
+Token::param(const _enum##_Param& paramType, int inst) \
{ \
checkParsed(); \
_enum##_Param::Type* p = \
- static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \
+ static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum(), inst)); \
if (!p) \
{ \
p = new _enum##_Param::Type(paramType.getTypeNum()); \
@@ -166,11 +166,11 @@
} \
\
const _enum##_Param::DType& \
-Token::param(const _enum##_Param& paramType) const \
+Token::param(const _enum##_Param& paramType, int inst) const \
{ \
checkParsed(); \
_enum##_Param::Type* p = \
- static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \
+ static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum(), inst)); \
if (!p) \
{ \
InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \
Index: Token.hxx
===================================================================
--- Token.hxx (revision 27855)
+++ Token.hxx (working copy)
@@ -52,12 +52,12 @@
using ParserCategory::param;
virtual Parameter* createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool);
- bool exists(const Param<Token>& paramType) const;
+ bool exists(const Param<Token>& paramType, int inst = 0) const;
void remove(const Param<Token>& paramType);
#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \
- const _enum##_Param::DType& param(const _enum##_Param& paramType) const; \
- _enum##_Param::DType& param(const _enum##_Param& paramType); \
+ const _enum##_Param::DType& param(const _enum##_Param& paramType, int inst = 0) const; \
+ _enum##_Param::DType& param(const _enum##_Param& paramType, int inst = 0); \
friend class _enum##_Param
defineParam(text, "text", ExistsOrDataParameter, "RFC 3840");