From 4c1bca98f15ebc2be67e9bb112b4bcb2ae54fa72 Mon Sep 17 00:00:00 2001 From: Stefan Sayer Date: Fri, 4 Mar 2011 17:30:41 +0100 Subject: [PATCH] add addOptionTag/removeOptionTag functions --- core/AmSipHeaders.h | 1 + core/AmSipMsg.cpp | 61 ++++++++++++++++++++++++++++++++++++- core/AmSipMsg.h | 7 +++++ core/tests/test_headers.cpp | 43 ++++++++++++++++++++++++++ 4 files changed, 111 insertions(+), 1 deletion(-) diff --git a/core/AmSipHeaders.h b/core/AmSipHeaders.h index 6845d26c..28ac91a0 100644 --- a/core/AmSipHeaders.h +++ b/core/AmSipHeaders.h @@ -37,6 +37,7 @@ #define SIP_HDR_COL(_hdr) _hdr ":" #define SIP_HDR_COLSP(_hdr) SIP_HDR_COL(_hdr) " " +#define COLSP ": " #define CRLF "\r\n" #define SIP_HDR_LEN(_hdr) (sizeof(_hdr) - /*0-term*/1) diff --git a/core/AmSipMsg.cpp b/core/AmSipMsg.cpp index c097efec..1626e373 100644 --- a/core/AmSipMsg.cpp +++ b/core/AmSipMsg.cpp @@ -2,7 +2,7 @@ #include #include "AmUtils.h" #include "AmSipMsg.h" - +#include "AmSipHeaders.h" string getHeader(const string& hdrs,const string& hdr_name, bool single) { @@ -125,6 +125,65 @@ bool removeHeader(string& hdrs, const string& hdr_name) { return found; } +void addOptionTag(string& hdrs, const string& hdr_name, const string& tag) { + // see if option tag already exists + string options = getHeader(hdrs, hdr_name); + if (options.size()) { + std::vector option_entries = explode(options, ","); + for (std::vector::iterator it=option_entries.begin(); + it != option_entries.end(); it++) { + if (trim(*it," ") == tag) + // found - no need to add again + return; + } + // tag not found - add our tag to the (first) hdr_name header + size_t pos1; size_t pos2; size_t hdr_start; + if (!findHeader(hdrs, hdr_name, 0, pos1, pos2, hdr_start)) { + ERROR("internal error: header '%s' disappeared in-between (hdrs = '%s'!\n", + hdr_name.c_str(), hdrs.c_str()); + hdrs += hdr_name + COLSP + tag + CRLF; + return; + } + + hdrs.insert(pos1, tag+", "); + + } else { + // hdr does not exist - add it + hdrs += hdr_name + COLSP + tag + CRLF; + } +} + +void removeOptionTag(string& hdrs, const string& hdr_name, const string& tag) { + string options = getHeader(hdrs, hdr_name); + + // does hdr hdr_name exist? + if (options.empty()) + return; + + // todo: optimize by doing inplace + std::vector options_v = explode(options, ","); + string o_hdr; + bool found = false; + for (std::vector::iterator it=options_v.begin(); + it != options_v.end(); it++) { + if (trim(*it, " ")==tag) { + found = true; + continue; + } + if (it != options_v.begin()) + o_hdr = ", "; + o_hdr+=*it; + } + if (!found) + return; + + removeHeader(hdrs, hdr_name); + if (o_hdr.empty()) + return; + hdrs += hdr_name + COLSP + o_hdr + CRLF; +} + + /* Print Member */ #define _PM(member, name) \ do { \ diff --git a/core/AmSipMsg.h b/core/AmSipMsg.h index 73163996..48de2960 100644 --- a/core/AmSipMsg.h +++ b/core/AmSipMsg.h @@ -94,6 +94,13 @@ bool findHeader(const string& hdrs,const string& hdr_name, const size_t skip, size_t& hdr_start); bool removeHeader(string& hdrs, const string& hdr_name); + +/** add an option tag @param tag to list @param hdr_name */ +void addOptionTag(string& hdrs, const string& hdr_name, const string& tag); + +/** remove an option tag @param tag from list @param hdr_name */ +void removeOptionTag(string& hdrs, const string& hdr_name, const string& tag); + #endif /* __AMSIPMSG_H__ */ diff --git a/core/tests/test_headers.cpp b/core/tests/test_headers.cpp index aaf7345c..5805534a 100644 --- a/core/tests/test_headers.cpp +++ b/core/tests/test_headers.cpp @@ -59,4 +59,47 @@ FCTMF_SUITE_BGN(test_headers) { fct_chk(get_header_keyvalue("u=sayer;d=iptel.org;p=abcdef", "d") == "iptel.org"); } FCT_TEST_END(); + FCT_TEST_BGN(addOptionTag) { + string hdrs = + "Supported: timer" CRLF + "Session-Expires: 110;refresher=uas" CRLF + "Supported: timer" CRLF; + + string hdrs1; + addOptionTag(hdrs1, "Supported", "blub"); + // DBG("hdrs1 '%s'\n", hdrs1.c_str()); + fct_chk(hdrs1.find("Supported: blub") != string::npos); + + hdrs1 = hdrs; + addOptionTag(hdrs1, "Supported", "something"); + // DBG("hdrs1 '%s'\n", hdrs1.c_str()); + fct_chk(hdrs1.find("something") != string::npos); + + hdrs1 = hdrs; + addOptionTag(hdrs1, "Supported", "timer"); + // DBG("hdrs1 '%s'\n", hdrs1.c_str()); + fct_chk(hdrs1 == hdrs); + + } FCT_TEST_END(); + + FCT_TEST_BGN(removeOptionTag) { + string hdrs = + "Supported: timer" CRLF; + + string hdrs1 = hdrs; + removeOptionTag(hdrs1, "Supported", "notexisting"); + // DBG("hdrs1 = '%s'\n", hdrs1.c_str()); + fct_chk(hdrs1 == hdrs); // dont touch + + hdrs1 = hdrs; + removeOptionTag(hdrs1, "Supported", "timer"); + // DBG("hdrs1 = '%s'\n", hdrs1.c_str()); + fct_chk(hdrs1.empty() == true); // last one + + hdrs1 = hdrs + "Supported: timer" CRLF; + removeOptionTag(hdrs1, "Supported", "timer"); + // DBG("hdrs1 = '%s'\n", hdrs1.c_str()); + fct_chk(hdrs1.empty()== true); // last one + + } FCT_TEST_END(); } FCTMF_SUITE_END();