-
Notifications
You must be signed in to change notification settings - Fork 3
/
SipHeaderValue.cpp
144 lines (125 loc) · 3.9 KB
/
SipHeaderValue.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include "SipHeaderValue.hpp"
#include <boost/regex.hpp>
#include "SipUtility.hpp"
#include "Via.hpp"
#include <sstream>
namespace Sip {
SipHeaderValue::SipHeaderValue( const string& value, map<string, string> tags) throw()
: m_hasTags( true ), m_tags( tags )
{
//Trim whitespace from value
boost::regex trimWS( "^\\s+|\\s+$" );
m_value = boost::regex_replace( value, trimWS, "" );
}
SipHeaderValue::SipHeaderValue( const string& rawValue ) throw()
: m_hasTags( false ), m_value( rawValue )
{
boost::regex semiURICheck( "^((?:\".*?\")|(?:[^<\"]+))?\\s*<" );
//Used to match with one or more tags
boost::regex tagsAreaMatch( "((?:;[^;\\?]+)*)(?:\\?.*)?$" );
//Ok, check if there is a uri that might so we can ignore inner semicolons
boost::cmatch matches;
string rawTags;
try
{
if ( boost::regex_search( rawValue.c_str(), matches, semiURICheck ) )
{ //Ok, lets weed out the area within the <>
//Find position of >. If not found, throw and exception.
//grab from > to first semicolon or end, that will be 'value'
//if a semicolon is found, everything including and after that will be raw tags.
string::size_type rightBracketPosition = rawValue.find( '>', 0 );
if ( rightBracketPosition == string::npos )
throw 1; //Just set m_value to rawValue...
if ( boost::regex_search( (char * ) (rawValue.c_str() + rightBracketPosition), matches, tagsAreaMatch ) && string( matches[1].first, matches[1].second ) != "" )
{
rawTags = string( matches[1].first, matches[1].second );
m_value = string( rawValue.c_str(), matches[1].first );
}
else
{ //No tags found, whole rawValue is just a value
rawTags = "";
m_value = rawValue;
}
}
else
{ //Should be safe to assume semis only used for tags
if ( boost::regex_search( rawValue.c_str(), matches, tagsAreaMatch ) && string( matches[1].first, matches[1].second ) != "" )
{
rawTags = string( matches[1].first, matches[1].second );
m_value = string( rawValue.c_str(), matches[1].first );
}
else
{
rawTags = "";
m_value = rawValue;
}
}
}
catch (...)
{
m_value = rawValue;
}
//Trim whitespace from value
boost::regex trimWS( "^\\s+|\\s+$" );
m_value = boost::regex_replace( m_value, trimWS, "" );
// At this point, we need thave the value and rawTags seperate and cleaned up
if ( rawTags != "" )
{
Utility::FillTags( rawTags, m_tags );
m_hasTags = true;
}
}
const map<string, string>& SipHeaderValue::Tags() const throw( SipHeaderValueException )
{
if ( !m_hasTags )
throw SipHeaderValueException( string( "No tags available for header value '" ) + m_value + "'" );
return m_tags;
}
const string& SipHeaderValue::GetTagValue( const string& tagName ) const throw( SipHeaderValueException )
{
if ( !m_hasTags )
throw SipHeaderValueException( string( "No tags available for header value '" ) + m_value + "'" );
map<string, string>::const_iterator theValue = m_tags.find( tagName );
if ( theValue == m_tags.end() )
throw SipHeaderValueException( "Tag not found: " + tagName );
else
return theValue->second;
}
const string& SipHeaderValue::Value() const throw()
{
return m_value;
}
void SipHeaderValue::SetValue( const string& newValue ) throw()
{
m_value = newValue;
}
string SipHeaderValue::ToString() const throw()
{
using std::ostringstream;
ostringstream shvAsStringBuilder;
shvAsStringBuilder << Value();
for ( map<string, string>::const_iterator aPair = m_tags.begin();
aPair != m_tags.end();
++aPair )
{
shvAsStringBuilder << ';' << aPair->first << '=' << aPair->second;
}
return shvAsStringBuilder.str();
}
bool SipHeaderValue::HasTags() const throw()
{
return m_hasTags;
}
bool SipHeaderValue::HasTag( const string& tagName ) const throw()
{
if ( m_tags.find( tagName ) == m_tags.end() )
return false;
else
return true;
}
void SipHeaderValue::AddTag( const string& key, const string& value ) throw()
{
m_tags[key] = value;
m_hasTags = true;
}
}; //namespace Sip