Moved header classes and some utilities from SIP to MIME. Updated SIP module and library to reflect the changes.
git-svn-id: http://yate.null.ro/svn/yate/trunk@1599 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
e4f067a1eb
commit
dabd23216d
269
engine/Mime.cpp
269
engine/Mime.cpp
|
@ -30,10 +30,277 @@ static bool isContinuationBlank(char c)
|
|||
return ((c == ' ') || (c == '\t'));
|
||||
}
|
||||
|
||||
/**
|
||||
* MimeHeaderLine
|
||||
*/
|
||||
MimeHeaderLine::MimeHeaderLine(const char* name, const String& value, char sep)
|
||||
: NamedString(name), m_separator(sep ? sep : ';')
|
||||
{
|
||||
if (value.null())
|
||||
return;
|
||||
XDebug(DebugAll,"MimeHeaderLine::MimeHeaderLine('%s','%s') [%p]",name,value.c_str(),this);
|
||||
int sp = findSep(value,m_separator);
|
||||
if (sp < 0) {
|
||||
assign(value);
|
||||
return;
|
||||
}
|
||||
assign(value,sp);
|
||||
trimBlanks();
|
||||
while (sp < (int)value.length()) {
|
||||
int ep = findSep(value,m_separator,sp+1);
|
||||
if (ep <= sp)
|
||||
ep = value.length();
|
||||
int eq = value.find('=',sp+1);
|
||||
if ((eq > 0) && (eq < ep)) {
|
||||
String pname(value.substr(sp+1,eq-sp-1));
|
||||
String pvalue(value.substr(eq+1,ep-eq-1));
|
||||
pname.trimBlanks();
|
||||
pvalue.trimBlanks();
|
||||
if (!pname.null()) {
|
||||
XDebug(DebugAll,"hdr param name='%s' value='%s'",pname.c_str(),pvalue.c_str());
|
||||
m_params.append(new NamedString(pname,pvalue));
|
||||
}
|
||||
}
|
||||
else {
|
||||
String pname(value.substr(sp+1,ep-sp-1));
|
||||
pname.trimBlanks();
|
||||
if (!pname.null()) {
|
||||
XDebug(DebugAll,"hdr param name='%s' (no value)",pname.c_str());
|
||||
m_params.append(new NamedString(pname));
|
||||
}
|
||||
}
|
||||
sp = ep;
|
||||
}
|
||||
}
|
||||
|
||||
MimeHeaderLine::MimeHeaderLine(const MimeHeaderLine& original, const char* newName)
|
||||
: NamedString(newName ? newName : original.name().c_str(),original),
|
||||
m_separator(original.separator())
|
||||
{
|
||||
XDebug(DebugAll,"MimeHeaderLine::MimeHeaderLine(%p '%s') [%p]",&original,name().c_str(),this);
|
||||
const ObjList* l = &original.params();
|
||||
for (; l; l = l->next()) {
|
||||
const NamedString* t = static_cast<const NamedString*>(l->get());
|
||||
if (t)
|
||||
m_params.append(new NamedString(t->name(),*t));
|
||||
}
|
||||
}
|
||||
|
||||
MimeHeaderLine::~MimeHeaderLine()
|
||||
{
|
||||
XDebug(DebugAll,"MimeHeaderLine::~MimeHeaderLine() [%p]",this);
|
||||
}
|
||||
|
||||
void* MimeHeaderLine::getObject(const String& name) const
|
||||
{
|
||||
if (name == "MimeHeaderLine")
|
||||
return const_cast<MimeHeaderLine*>(this);
|
||||
return NamedString::getObject(name);
|
||||
}
|
||||
|
||||
MimeHeaderLine* MimeHeaderLine::clone(const char* newName) const
|
||||
{
|
||||
return new MimeHeaderLine(*this,newName);
|
||||
}
|
||||
|
||||
void MimeHeaderLine::buildLine(String& line) const
|
||||
{
|
||||
line << name() << ": " << *this;
|
||||
const ObjList* p = &m_params;
|
||||
for (; p; p = p->next()) {
|
||||
NamedString* s = static_cast<NamedString*>(p->get());
|
||||
if (s) {
|
||||
line << separator() << s->name();
|
||||
if (!s->null())
|
||||
line << "=" << *s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const NamedString* MimeHeaderLine::getParam(const char* name) const
|
||||
{
|
||||
if (!(name && *name))
|
||||
return 0;
|
||||
const ObjList* l = &m_params;
|
||||
for (; l; l = l->next()) {
|
||||
const NamedString* t = static_cast<const NamedString*>(l->get());
|
||||
if (t && (t->name() &= name))
|
||||
return t;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MimeHeaderLine::setParam(const char* name, const char* value)
|
||||
{
|
||||
ObjList* p = m_params.find(name);
|
||||
if (p)
|
||||
*static_cast<NamedString*>(p->get()) = value;
|
||||
else
|
||||
m_params.append(new NamedString(name,value));
|
||||
}
|
||||
|
||||
void MimeHeaderLine::delParam(const char* name)
|
||||
{
|
||||
ObjList* p = m_params.find(name);
|
||||
if (p)
|
||||
p->remove();
|
||||
}
|
||||
|
||||
// Utility function, puts quotes around a string
|
||||
void MimeHeaderLine::addQuotes(String& str)
|
||||
{
|
||||
str.trimBlanks();
|
||||
int l = str.length();
|
||||
if ((l < 2) || (str[0] != '"') || (str[l-1] != '"'))
|
||||
str = "\"" + str + "\"";
|
||||
}
|
||||
|
||||
// Utility function, removes quotes around a string
|
||||
void MimeHeaderLine::delQuotes(String& str)
|
||||
{
|
||||
str.trimBlanks();
|
||||
int l = str.length();
|
||||
if ((l >= 2) && (str[0] == '"') && (str[l-1] == '"')) {
|
||||
str = str.substr(1,l-2);
|
||||
str.trimBlanks();
|
||||
}
|
||||
}
|
||||
|
||||
// Utility function, puts quotes around a string
|
||||
String MimeHeaderLine::quote(const String& str)
|
||||
{
|
||||
String tmp(str);
|
||||
addQuotes(tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Utility function to find a separator not in "quotes" or inside <uri>
|
||||
int MimeHeaderLine::findSep(const char* str, char sep, int offs)
|
||||
{
|
||||
if (!(str && sep))
|
||||
return -1;
|
||||
str += offs;
|
||||
bool inQ = false;
|
||||
bool inU = false;
|
||||
char c;
|
||||
for (; (c = *str++) ; offs++) {
|
||||
if (inQ) {
|
||||
if (c == '"')
|
||||
inQ = false;
|
||||
continue;
|
||||
}
|
||||
if (inU) {
|
||||
if (c == '>')
|
||||
inU = false;
|
||||
continue;
|
||||
}
|
||||
if (c == sep)
|
||||
return offs;
|
||||
switch (c) {
|
||||
case '"':
|
||||
inQ = true;
|
||||
break;
|
||||
case '<':
|
||||
inU = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MimeAuthLine
|
||||
*/
|
||||
MimeAuthLine::MimeAuthLine(const char* name, const String& value)
|
||||
: MimeHeaderLine(name,String::empty(),',')
|
||||
{
|
||||
XDebug(DebugAll,"MimeAuthLine::MimeAuthLine('%s','%s') [%p]",name,value.c_str(),this);
|
||||
if (value.null())
|
||||
return;
|
||||
int sp = value.find(' ');
|
||||
if (sp < 0) {
|
||||
assign(value);
|
||||
return;
|
||||
}
|
||||
assign(value,sp);
|
||||
trimBlanks();
|
||||
while (sp < (int)value.length()) {
|
||||
int ep = value.find(m_separator,sp+1);
|
||||
int quot = value.find('"',sp+1);
|
||||
if ((quot > sp) && (quot < ep)) {
|
||||
quot = value.find('"',quot+1);
|
||||
if (quot > sp)
|
||||
ep = value.find(m_separator,quot+1);
|
||||
}
|
||||
if (ep <= sp)
|
||||
ep = value.length();
|
||||
int eq = value.find('=',sp+1);
|
||||
if ((eq > 0) && (eq < ep)) {
|
||||
String pname(value.substr(sp+1,eq-sp-1));
|
||||
String pvalue(value.substr(eq+1,ep-eq-1));
|
||||
pname.trimBlanks();
|
||||
pvalue.trimBlanks();
|
||||
if (!pname.null()) {
|
||||
XDebug(DebugAll,"auth param name='%s' value='%s'",pname.c_str(),pvalue.c_str());
|
||||
m_params.append(new NamedString(pname,pvalue));
|
||||
}
|
||||
}
|
||||
else {
|
||||
String pname(value.substr(sp+1,ep-sp-1));
|
||||
pname.trimBlanks();
|
||||
if (!pname.null()) {
|
||||
XDebug(DebugAll,"auth param name='%s' (no value)",pname.c_str());
|
||||
m_params.append(new NamedString(pname));
|
||||
}
|
||||
}
|
||||
sp = ep;
|
||||
}
|
||||
}
|
||||
|
||||
MimeAuthLine::MimeAuthLine(const MimeAuthLine& original, const char* newName)
|
||||
: MimeHeaderLine(original,newName)
|
||||
{
|
||||
}
|
||||
|
||||
void* MimeAuthLine::getObject(const String& name) const
|
||||
{
|
||||
if (name == "MimeAuthLine")
|
||||
return const_cast<MimeAuthLine*>(this);
|
||||
return MimeHeaderLine::getObject(name);
|
||||
}
|
||||
|
||||
MimeHeaderLine* MimeAuthLine::clone(const char* newName) const
|
||||
{
|
||||
return new MimeAuthLine(*this,newName);
|
||||
}
|
||||
|
||||
void MimeAuthLine::buildLine(String& line) const
|
||||
{
|
||||
line << name() << ": " << *this;
|
||||
const ObjList* p = &m_params;
|
||||
for (bool first = true; p; p = p->next()) {
|
||||
NamedString* s = static_cast<NamedString*>(p->get());
|
||||
if (s) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
line << separator();
|
||||
line << " " << s->name();
|
||||
if (!s->null())
|
||||
line << "=" << *s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MimeBody
|
||||
*/
|
||||
YCLASSIMP(MimeBody,GenObject)
|
||||
|
||||
MimeBody::MimeBody(const String& type)
|
||||
: m_type(type)
|
||||
: m_type("Content-Type",type)
|
||||
{
|
||||
DDebug(DebugAll,"MimeBody::MimeBody('%s') [%p]",m_type.c_str(),this);
|
||||
}
|
||||
|
|
|
@ -192,7 +192,7 @@ SIPTransaction* SIPEngine::addMessage(SIPMessage* message)
|
|||
if (message->isOutgoing())
|
||||
message->complete(this);
|
||||
// locate the branch parameter of last Via header - added by the UA
|
||||
const SIPHeaderLine* hl = message->getLastHeader("Via");
|
||||
const MimeHeaderLine* hl = message->getLastHeader("Via");
|
||||
if (!hl)
|
||||
#ifdef SIP_STRICT
|
||||
return 0;
|
||||
|
@ -465,10 +465,10 @@ int SIPEngine::authUser(const SIPMessage* message, String& user, bool proxy, Gen
|
|||
const ObjList* l = &message->header;
|
||||
for (; l; l = l->next()) {
|
||||
const GenObject* o = l->get();
|
||||
const SIPHeaderLine* t = o ? static_cast<const SIPHeaderLine*>(o->getObject("SIPHeaderLine")) : 0;
|
||||
const MimeHeaderLine* t = o ? static_cast<const MimeHeaderLine*>(o->getObject("MimeHeaderLine")) : 0;
|
||||
if (t && (t->name() &= hdr) && (*t &= "Digest")) {
|
||||
String usr(t->getParam("username"));
|
||||
delQuotes(usr);
|
||||
MimeHeaderLine::delQuotes(usr);
|
||||
if (usr.null())
|
||||
continue;
|
||||
XDebug(this,DebugAll,"authUser found user '%s'",usr.c_str());
|
||||
|
@ -476,7 +476,7 @@ int SIPEngine::authUser(const SIPMessage* message, String& user, bool proxy, Gen
|
|||
if (user && (usr != user))
|
||||
continue;
|
||||
String nonce(t->getParam("nonce"));
|
||||
delQuotes(nonce);
|
||||
MimeHeaderLine::delQuotes(nonce);
|
||||
// TODO: implement a nonce cache for the stupid clients that don't send it back
|
||||
if (nonce.null())
|
||||
continue;
|
||||
|
@ -487,15 +487,15 @@ int SIPEngine::authUser(const SIPMessage* message, String& user, bool proxy, Gen
|
|||
noUser = false;
|
||||
XDebug(this,DebugAll,"authUser nonce age is %ld",age);
|
||||
String res(t->getParam("response"));
|
||||
delQuotes(res);
|
||||
MimeHeaderLine::delQuotes(res);
|
||||
if (res.null())
|
||||
continue;
|
||||
String uri(t->getParam("uri"));
|
||||
delQuotes(uri);
|
||||
MimeHeaderLine::delQuotes(uri);
|
||||
if (uri.null())
|
||||
uri = message->uri;
|
||||
String realm(t->getParam("realm"));
|
||||
delQuotes(realm);
|
||||
MimeHeaderLine::delQuotes(realm);
|
||||
|
||||
if (!checkUser(usr,realm,nonce,message->method,uri,res,message,userData))
|
||||
continue;
|
||||
|
|
|
@ -30,200 +30,6 @@
|
|||
|
||||
using namespace TelEngine;
|
||||
|
||||
SIPHeaderLine::SIPHeaderLine(const char* name, const String& value, char sep)
|
||||
: NamedString(name), m_separator(sep ? sep : ';')
|
||||
{
|
||||
if (value.null())
|
||||
return;
|
||||
XDebug(DebugAll,"SIPHeaderLine::SIPHeaderLine('%s','%s') [%p]",name,value.c_str(),this);
|
||||
int sp = findSep(value,m_separator);
|
||||
if (sp < 0) {
|
||||
assign(value);
|
||||
return;
|
||||
}
|
||||
assign(value,sp);
|
||||
trimBlanks();
|
||||
while (sp < (int)value.length()) {
|
||||
int ep = findSep(value,m_separator,sp+1);
|
||||
if (ep <= sp)
|
||||
ep = value.length();
|
||||
int eq = value.find('=',sp+1);
|
||||
if ((eq > 0) && (eq < ep)) {
|
||||
String pname(value.substr(sp+1,eq-sp-1));
|
||||
String pvalue(value.substr(eq+1,ep-eq-1));
|
||||
pname.trimBlanks();
|
||||
pvalue.trimBlanks();
|
||||
if (!pname.null()) {
|
||||
XDebug(DebugAll,"hdr param name='%s' value='%s'",pname.c_str(),pvalue.c_str());
|
||||
m_params.append(new NamedString(pname,pvalue));
|
||||
}
|
||||
}
|
||||
else {
|
||||
String pname(value.substr(sp+1,ep-sp-1));
|
||||
pname.trimBlanks();
|
||||
if (!pname.null()) {
|
||||
XDebug(DebugAll,"hdr param name='%s' (no value)",pname.c_str());
|
||||
m_params.append(new NamedString(pname));
|
||||
}
|
||||
}
|
||||
sp = ep;
|
||||
}
|
||||
}
|
||||
|
||||
SIPHeaderLine::SIPHeaderLine(const SIPHeaderLine& original, const char* newName)
|
||||
: NamedString(newName ? newName : original.name().c_str(),original),
|
||||
m_separator(original.separator())
|
||||
{
|
||||
XDebug(DebugAll,"SIPHeaderLine::SIPHeaderLine(%p '%s') [%p]",&original,name().c_str(),this);
|
||||
const ObjList* l = &original.params();
|
||||
for (; l; l = l->next()) {
|
||||
const NamedString* t = static_cast<const NamedString*>(l->get());
|
||||
if (t)
|
||||
m_params.append(new NamedString(t->name(),*t));
|
||||
}
|
||||
}
|
||||
|
||||
SIPHeaderLine::~SIPHeaderLine()
|
||||
{
|
||||
XDebug(DebugAll,"SIPHeaderLine::~SIPHeaderLine() [%p]",this);
|
||||
}
|
||||
|
||||
void* SIPHeaderLine::getObject(const String& name) const
|
||||
{
|
||||
if (name == "SIPHeaderLine")
|
||||
return const_cast<SIPHeaderLine*>(this);
|
||||
return NamedString::getObject(name);
|
||||
}
|
||||
|
||||
SIPHeaderLine* SIPHeaderLine::clone(const char* newName) const
|
||||
{
|
||||
return new SIPHeaderLine(*this,newName);
|
||||
}
|
||||
|
||||
void SIPHeaderLine::buildLine(String& line) const
|
||||
{
|
||||
line << name() << ": " << *this;
|
||||
const ObjList* p = &m_params;
|
||||
for (; p; p = p->next()) {
|
||||
NamedString* s = static_cast<NamedString*>(p->get());
|
||||
if (s) {
|
||||
line << separator() << s->name();
|
||||
if (!s->null())
|
||||
line << "=" << *s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const NamedString* SIPHeaderLine::getParam(const char* name) const
|
||||
{
|
||||
if (!(name && *name))
|
||||
return 0;
|
||||
const ObjList* l = &m_params;
|
||||
for (; l; l = l->next()) {
|
||||
const NamedString* t = static_cast<const NamedString*>(l->get());
|
||||
if (t && (t->name() &= name))
|
||||
return t;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SIPHeaderLine::setParam(const char* name, const char* value)
|
||||
{
|
||||
ObjList* p = m_params.find(name);
|
||||
if (p)
|
||||
*static_cast<NamedString*>(p->get()) = value;
|
||||
else
|
||||
m_params.append(new NamedString(name,value));
|
||||
}
|
||||
|
||||
void SIPHeaderLine::delParam(const char* name)
|
||||
{
|
||||
ObjList* p = m_params.find(name);
|
||||
if (p)
|
||||
p->remove();
|
||||
}
|
||||
|
||||
SIPAuthLine::SIPAuthLine(const char* name, const String& value)
|
||||
: SIPHeaderLine(name,String::empty(),',')
|
||||
{
|
||||
XDebug(DebugAll,"SIPAuthLine::SIPAuthLine('%s','%s') [%p]",name,value.c_str(),this);
|
||||
if (value.null())
|
||||
return;
|
||||
int sp = value.find(' ');
|
||||
if (sp < 0) {
|
||||
assign(value);
|
||||
return;
|
||||
}
|
||||
assign(value,sp);
|
||||
trimBlanks();
|
||||
while (sp < (int)value.length()) {
|
||||
int ep = value.find(m_separator,sp+1);
|
||||
int quot = value.find('"',sp+1);
|
||||
if ((quot > sp) && (quot < ep)) {
|
||||
quot = value.find('"',quot+1);
|
||||
if (quot > sp)
|
||||
ep = value.find(m_separator,quot+1);
|
||||
}
|
||||
if (ep <= sp)
|
||||
ep = value.length();
|
||||
int eq = value.find('=',sp+1);
|
||||
if ((eq > 0) && (eq < ep)) {
|
||||
String pname(value.substr(sp+1,eq-sp-1));
|
||||
String pvalue(value.substr(eq+1,ep-eq-1));
|
||||
pname.trimBlanks();
|
||||
pvalue.trimBlanks();
|
||||
if (!pname.null()) {
|
||||
XDebug(DebugAll,"auth param name='%s' value='%s'",pname.c_str(),pvalue.c_str());
|
||||
m_params.append(new NamedString(pname,pvalue));
|
||||
}
|
||||
}
|
||||
else {
|
||||
String pname(value.substr(sp+1,ep-sp-1));
|
||||
pname.trimBlanks();
|
||||
if (!pname.null()) {
|
||||
XDebug(DebugAll,"auth param name='%s' (no value)",pname.c_str());
|
||||
m_params.append(new NamedString(pname));
|
||||
}
|
||||
}
|
||||
sp = ep;
|
||||
}
|
||||
}
|
||||
|
||||
SIPAuthLine::SIPAuthLine(const SIPAuthLine& original, const char* newName)
|
||||
: SIPHeaderLine(original,newName)
|
||||
{
|
||||
}
|
||||
|
||||
void* SIPAuthLine::getObject(const String& name) const
|
||||
{
|
||||
if (name == "SIPAuthLine")
|
||||
return const_cast<SIPAuthLine*>(this);
|
||||
return SIPHeaderLine::getObject(name);
|
||||
}
|
||||
|
||||
SIPHeaderLine* SIPAuthLine::clone(const char* newName) const
|
||||
{
|
||||
return new SIPAuthLine(*this,newName);
|
||||
}
|
||||
|
||||
void SIPAuthLine::buildLine(String& line) const
|
||||
{
|
||||
line << name() << ": " << *this;
|
||||
const ObjList* p = &m_params;
|
||||
for (bool first = true; p; p = p->next()) {
|
||||
NamedString* s = static_cast<NamedString*>(p->get());
|
||||
if (s) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
line << separator();
|
||||
line << " " << s->name();
|
||||
if (!s->null())
|
||||
line << "=" << *s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SIPMessage::SIPMessage(const SIPMessage& original)
|
||||
: version(original.version), method(original.method), uri(original.uri),
|
||||
code(original.code), reason(original.reason),
|
||||
|
@ -240,13 +46,13 @@ SIPMessage::SIPMessage(const SIPMessage& original)
|
|||
bool via1 = true;
|
||||
const ObjList* l = &original.header;
|
||||
for (; l; l = l->next()) {
|
||||
const SIPHeaderLine* hl = static_cast<SIPHeaderLine*>(l->get());
|
||||
const MimeHeaderLine* hl = static_cast<MimeHeaderLine*>(l->get());
|
||||
if (!hl)
|
||||
continue;
|
||||
// CSeq must not be copied, a new one will be built by complete()
|
||||
if (hl->name() &= "CSeq")
|
||||
continue;
|
||||
SIPHeaderLine* nl = hl->clone();
|
||||
MimeHeaderLine* nl = hl->clone();
|
||||
// this is a new transaction so let complete() add randomness
|
||||
if (via1 && (nl->name() &= "Via")) {
|
||||
via1 = false;
|
||||
|
@ -323,19 +129,19 @@ SIPMessage::SIPMessage(const SIPMessage* original, const SIPMessage* answer)
|
|||
version = original->version;
|
||||
uri = original->uri;
|
||||
copyAllHeaders(original,"Via");
|
||||
SIPHeaderLine* hl = const_cast<SIPHeaderLine*>(getHeader("Via"));
|
||||
MimeHeaderLine* hl = const_cast<MimeHeaderLine*>(getHeader("Via"));
|
||||
if (!hl) {
|
||||
String tmp;
|
||||
tmp << version << "/" << getParty()->getProtoName();
|
||||
tmp << " " << getParty()->getLocalAddr() << ":" << getParty()->getLocalPort();
|
||||
hl = new SIPHeaderLine("Via",tmp);
|
||||
hl = new MimeHeaderLine("Via",tmp);
|
||||
header.append(hl);
|
||||
}
|
||||
if (answer && (answer->code == 200) && (original->method &= "INVITE")) {
|
||||
String tmp("z9hG4bK");
|
||||
tmp << (int)::random();
|
||||
hl->setParam("branch",tmp);
|
||||
const SIPHeaderLine* co = answer->getHeader("Contact");
|
||||
const MimeHeaderLine* co = answer->getHeader("Contact");
|
||||
if (co) {
|
||||
uri = *co;
|
||||
Regexp r("^[^<]*<\\([^>]*\\)>.*$");
|
||||
|
@ -397,7 +203,7 @@ void SIPMessage::complete(SIPEngine* engine, const char* user, const char* domai
|
|||
|
||||
// only set the dialog tag on ACK
|
||||
if (isACK()) {
|
||||
SIPHeaderLine* hl = const_cast<SIPHeaderLine*>(getHeader("To"));
|
||||
MimeHeaderLine* hl = const_cast<MimeHeaderLine*>(getHeader("To"));
|
||||
if (dlgTag && hl && !hl->getParam("tag"))
|
||||
hl->setParam("tag",dlgTag);
|
||||
return;
|
||||
|
@ -406,12 +212,12 @@ void SIPMessage::complete(SIPEngine* engine, const char* user, const char* domai
|
|||
if (!domain)
|
||||
domain = getParty()->getLocalAddr();
|
||||
|
||||
SIPHeaderLine* hl = const_cast<SIPHeaderLine*>(getHeader("Via"));
|
||||
MimeHeaderLine* hl = const_cast<MimeHeaderLine*>(getHeader("Via"));
|
||||
if (!hl) {
|
||||
String tmp;
|
||||
tmp << version << "/" << getParty()->getProtoName();
|
||||
tmp << " " << getParty()->getLocalAddr() << ":" << getParty()->getLocalPort();
|
||||
hl = new SIPHeaderLine("Via",tmp);
|
||||
hl = new MimeHeaderLine("Via",tmp);
|
||||
if (!(isAnswer() || isACK()))
|
||||
hl->setParam("rport");
|
||||
header.append(hl);
|
||||
|
@ -427,24 +233,24 @@ void SIPMessage::complete(SIPEngine* engine, const char* user, const char* domai
|
|||
}
|
||||
|
||||
if (!isAnswer()) {
|
||||
hl = const_cast<SIPHeaderLine*>(getHeader("From"));
|
||||
hl = const_cast<MimeHeaderLine*>(getHeader("From"));
|
||||
if (!hl) {
|
||||
String tmp = "<sip:";
|
||||
if (user)
|
||||
tmp << user << "@";
|
||||
tmp << domain << ">";
|
||||
hl = new SIPHeaderLine("From",tmp);
|
||||
hl = new MimeHeaderLine("From",tmp);
|
||||
header.append(hl);
|
||||
}
|
||||
if (!hl->getParam("tag"))
|
||||
hl->setParam("tag",String((int)::random()));
|
||||
}
|
||||
|
||||
hl = const_cast<SIPHeaderLine*>(getHeader("To"));
|
||||
hl = const_cast<MimeHeaderLine*>(getHeader("To"));
|
||||
if (!(isAnswer() || hl)) {
|
||||
String tmp;
|
||||
tmp << "<" << uri << ">";
|
||||
hl = new SIPHeaderLine("To",tmp);
|
||||
hl = new MimeHeaderLine("To",tmp);
|
||||
header.append(hl);
|
||||
}
|
||||
if (hl && dlgTag && !hl->getParam("tag"))
|
||||
|
@ -499,7 +305,7 @@ void SIPMessage::complete(SIPEngine* engine, const char* user, const char* domai
|
|||
|
||||
bool SIPMessage::copyHeader(const SIPMessage* message, const char* name, const char* newName)
|
||||
{
|
||||
const SIPHeaderLine* hl = message ? message->getHeader(name) : 0;
|
||||
const MimeHeaderLine* hl = message ? message->getHeader(name) : 0;
|
||||
if (hl) {
|
||||
header.append(hl->clone(newName));
|
||||
return true;
|
||||
|
@ -514,7 +320,7 @@ int SIPMessage::copyAllHeaders(const SIPMessage* message, const char* name, cons
|
|||
int c = 0;
|
||||
const ObjList* l = &message->header;
|
||||
for (; l; l = l->next()) {
|
||||
const SIPHeaderLine* hl = static_cast<const SIPHeaderLine*>(l->get());
|
||||
const MimeHeaderLine* hl = static_cast<const MimeHeaderLine*>(l->get());
|
||||
if (hl && (hl->name() &= name)) {
|
||||
++c;
|
||||
header.append(hl->clone(newName));
|
||||
|
@ -606,9 +412,9 @@ bool SIPMessage::parse(const char* buf, int len)
|
|||
(name &= "Proxy-Authenticate") ||
|
||||
(name &= "Authorization") ||
|
||||
(name &= "Proxy-Authorization"))
|
||||
header.append(new SIPAuthLine(name,*line));
|
||||
header.append(new MimeAuthLine(name,*line));
|
||||
else
|
||||
header.append(new SIPHeaderLine(name,*line));
|
||||
header.append(new MimeHeaderLine(name,*line));
|
||||
|
||||
if (content.null() && (name &= "Content-Type")) {
|
||||
content = *line;
|
||||
|
@ -650,27 +456,27 @@ SIPMessage* SIPMessage::fromParsing(SIPParty* ep, const char* buf, int len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
const SIPHeaderLine* SIPMessage::getHeader(const char* name) const
|
||||
const MimeHeaderLine* SIPMessage::getHeader(const char* name) const
|
||||
{
|
||||
if (!(name && *name))
|
||||
return 0;
|
||||
const ObjList* l = &header;
|
||||
for (; l; l = l->next()) {
|
||||
const SIPHeaderLine* t = static_cast<const SIPHeaderLine*>(l->get());
|
||||
const MimeHeaderLine* t = static_cast<const MimeHeaderLine*>(l->get());
|
||||
if (t && (t->name() &= name))
|
||||
return t;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const SIPHeaderLine* SIPMessage::getLastHeader(const char* name) const
|
||||
const MimeHeaderLine* SIPMessage::getLastHeader(const char* name) const
|
||||
{
|
||||
if (!(name && *name))
|
||||
return 0;
|
||||
const SIPHeaderLine* res = 0;
|
||||
const MimeHeaderLine* res = 0;
|
||||
const ObjList* l = &header;
|
||||
for (; l; l = l->next()) {
|
||||
const SIPHeaderLine* t = static_cast<const SIPHeaderLine*>(l->get());
|
||||
const MimeHeaderLine* t = static_cast<const MimeHeaderLine*>(l->get());
|
||||
if (t && (t->name() &= name))
|
||||
res = t;
|
||||
}
|
||||
|
@ -683,7 +489,7 @@ void SIPMessage::clearHeaders(const char* name)
|
|||
return;
|
||||
ObjList* l = &header;
|
||||
while (l) {
|
||||
const SIPHeaderLine* t = static_cast<const SIPHeaderLine*>(l->get());
|
||||
const MimeHeaderLine* t = static_cast<const MimeHeaderLine*>(l->get());
|
||||
if (t && (t->name() &= name))
|
||||
l->remove();
|
||||
else
|
||||
|
@ -698,7 +504,7 @@ int SIPMessage::countHeaders(const char* name) const
|
|||
int res = 0;
|
||||
const ObjList* l = &header;
|
||||
for (; l; l = l->next()) {
|
||||
const SIPHeaderLine* t = static_cast<const SIPHeaderLine*>(l->get());
|
||||
const MimeHeaderLine* t = static_cast<const MimeHeaderLine*>(l->get());
|
||||
if (t && (t->name() &= name))
|
||||
++res;
|
||||
}
|
||||
|
@ -707,13 +513,13 @@ int SIPMessage::countHeaders(const char* name) const
|
|||
|
||||
const NamedString* SIPMessage::getParam(const char* name, const char* param) const
|
||||
{
|
||||
const SIPHeaderLine* hl = getHeader(name);
|
||||
const MimeHeaderLine* hl = getHeader(name);
|
||||
return hl ? hl->getParam(param) : 0;
|
||||
}
|
||||
|
||||
const String& SIPMessage::getHeaderValue(const char* name) const
|
||||
{
|
||||
const SIPHeaderLine* hl = getHeader(name);
|
||||
const MimeHeaderLine* hl = getHeader(name);
|
||||
return hl ? *static_cast<const String*>(hl) : String::empty();
|
||||
}
|
||||
|
||||
|
@ -733,7 +539,7 @@ const String& SIPMessage::getHeaders() const
|
|||
|
||||
const ObjList* l = &header;
|
||||
for (; l; l = l->next()) {
|
||||
SIPHeaderLine* t = static_cast<SIPHeaderLine*>(l->get());
|
||||
MimeHeaderLine* t = static_cast<MimeHeaderLine*>(l->get());
|
||||
if (t) {
|
||||
t->buildLine(m_string);
|
||||
m_string << "\r\n";
|
||||
|
@ -749,8 +555,8 @@ const DataBlock& SIPMessage::getBuffer() const
|
|||
m_data.assign((void*)(getHeaders().c_str()),getHeaders().length());
|
||||
if (body) {
|
||||
String s;
|
||||
s << "Content-Type: " << body->getType() << "\r\n";
|
||||
s << "Content-Length: " << body->getBody().length() << "\r\n\r\n";
|
||||
body->getType().buildLine(s);
|
||||
s << "\r\nContent-Length: " << body->getBody().length() << "\r\n\r\n";
|
||||
m_data += s;
|
||||
}
|
||||
else
|
||||
|
@ -787,30 +593,30 @@ void SIPMessage::setParty(SIPParty* ep)
|
|||
m_ep->ref();
|
||||
}
|
||||
|
||||
SIPAuthLine* SIPMessage::buildAuth(const String& username, const String& password,
|
||||
MimeAuthLine* SIPMessage::buildAuth(const String& username, const String& password,
|
||||
const String& meth, const String& uri, bool proxy) const
|
||||
{
|
||||
const char* hdr = proxy ? "Proxy-Authenticate" : "WWW-Authenticate";
|
||||
const ObjList* l = &header;
|
||||
for (; l; l = l->next()) {
|
||||
const SIPAuthLine* t = YOBJECT(SIPAuthLine,l->get());
|
||||
const MimeAuthLine* t = YOBJECT(MimeAuthLine,l->get());
|
||||
if (t && (t->name() &= hdr) && (*t &= "Digest")) {
|
||||
String nonce(t->getParam("nonce"));
|
||||
delQuotes(nonce);
|
||||
MimeHeaderLine::delQuotes(nonce);
|
||||
if (nonce.null())
|
||||
continue;
|
||||
String realm(t->getParam("realm"));
|
||||
delQuotes(realm);
|
||||
MimeHeaderLine::delQuotes(realm);
|
||||
int par = uri.find(';');
|
||||
String msguri = uri.substr(0,par);
|
||||
String response;
|
||||
SIPEngine::buildAuth(username,realm,password,nonce,meth,msguri,response);
|
||||
SIPAuthLine* auth = new SIPAuthLine(proxy ? "Proxy-Authorization" : "Authorization","Digest");
|
||||
auth->setParam("username",quote(username));
|
||||
auth->setParam("realm",quote(realm));
|
||||
auth->setParam("nonce",quote(nonce));
|
||||
auth->setParam("uri",quote(msguri));
|
||||
auth->setParam("response",quote(response));
|
||||
MimeAuthLine* auth = new MimeAuthLine(proxy ? "Proxy-Authorization" : "Authorization","Digest");
|
||||
auth->setParam("username",MimeHeaderLine::quote(username));
|
||||
auth->setParam("realm",MimeHeaderLine::quote(realm));
|
||||
auth->setParam("nonce",MimeHeaderLine::quote(nonce));
|
||||
auth->setParam("uri",MimeHeaderLine::quote(msguri));
|
||||
auth->setParam("response",MimeHeaderLine::quote(response));
|
||||
auth->setParam("algorithm","MD5");
|
||||
// copy opaque data as-is, only if present
|
||||
const NamedString* opaque = t->getParam("opaque");
|
||||
|
@ -822,7 +628,7 @@ SIPAuthLine* SIPMessage::buildAuth(const String& username, const String& passwor
|
|||
return 0;
|
||||
}
|
||||
|
||||
SIPAuthLine* SIPMessage::buildAuth(const SIPMessage& original) const
|
||||
MimeAuthLine* SIPMessage::buildAuth(const SIPMessage& original) const
|
||||
{
|
||||
if (original.getAuthUsername().null())
|
||||
return 0;
|
||||
|
@ -835,18 +641,18 @@ ObjList* SIPMessage::getRoutes() const
|
|||
ObjList* list = 0;
|
||||
const ObjList* l = &header;
|
||||
for (; l; l = l->next()) {
|
||||
const SIPHeaderLine* h = YOBJECT(SIPHeaderLine,l->get());
|
||||
const MimeHeaderLine* h = YOBJECT(MimeHeaderLine,l->get());
|
||||
if (h && (h->name() &= "Record-Route")) {
|
||||
int p = 0;
|
||||
while (p >= 0) {
|
||||
SIPHeaderLine* line = 0;
|
||||
int s = findSep(*h,',',p);
|
||||
MimeHeaderLine* line = 0;
|
||||
int s = MimeHeaderLine::findSep(*h,',',p);
|
||||
String tmp;
|
||||
if (s < 0) {
|
||||
if (p)
|
||||
tmp = h->substr(p);
|
||||
else
|
||||
line = new SIPHeaderLine(*h,"Route");
|
||||
line = new MimeHeaderLine(*h,"Route");
|
||||
p = -1;
|
||||
}
|
||||
else {
|
||||
|
@ -856,7 +662,7 @@ ObjList* SIPMessage::getRoutes() const
|
|||
}
|
||||
tmp.trimBlanks();
|
||||
if (tmp)
|
||||
line = new SIPHeaderLine("Route",tmp);
|
||||
line = new MimeHeaderLine("Route",tmp);
|
||||
if (!line)
|
||||
continue;
|
||||
if (!list)
|
||||
|
@ -877,7 +683,7 @@ void SIPMessage::addRoutes(const ObjList* routes)
|
|||
{
|
||||
if (isAnswer() || !routes)
|
||||
return;
|
||||
SIPHeaderLine* hl = YOBJECT(SIPHeaderLine,routes->get());
|
||||
MimeHeaderLine* hl = YOBJECT(MimeHeaderLine,routes->get());
|
||||
if (hl) {
|
||||
// check if first route is to a RFC 2543 proxy
|
||||
String tmp = *hl;
|
||||
|
@ -886,7 +692,7 @@ void SIPMessage::addRoutes(const ObjList* routes)
|
|||
tmp = tmp.matchString(1);
|
||||
if (tmp.find(";lr") < 0) {
|
||||
// prepare a new final route
|
||||
hl = new SIPHeaderLine("Route","<" + uri + ">");
|
||||
hl = new MimeHeaderLine("Route","<" + uri + ">");
|
||||
// set the first route as Request-URI and then skip it
|
||||
uri = tmp;
|
||||
routes = routes->next();
|
||||
|
@ -897,7 +703,7 @@ void SIPMessage::addRoutes(const ObjList* routes)
|
|||
|
||||
// add (remaining) routes
|
||||
for (; routes; routes = routes->next()) {
|
||||
const SIPHeaderLine* h = YOBJECT(SIPHeaderLine,routes->get());
|
||||
const MimeHeaderLine* h = YOBJECT(MimeHeaderLine,routes->get());
|
||||
if (h)
|
||||
addHeader(h->clone());
|
||||
}
|
||||
|
@ -949,7 +755,7 @@ SIPDialog::SIPDialog(const SIPMessage& message)
|
|||
{
|
||||
Regexp r("<\\([^>]\\+\\)>");
|
||||
bool local = message.isOutgoing() ^ message.isAnswer();
|
||||
const SIPHeaderLine* hl = message.getHeader(local ? "From" : "To");
|
||||
const MimeHeaderLine* hl = message.getHeader(local ? "From" : "To");
|
||||
localURI = hl;
|
||||
if (localURI.matches(r))
|
||||
localURI = localURI.matchString(1);
|
||||
|
@ -972,7 +778,7 @@ SIPDialog& SIPDialog::operator=(const SIPMessage& message)
|
|||
String::operator=(cid);
|
||||
Regexp r("<\\([^>]\\+\\)>");
|
||||
bool local = message.isOutgoing() ^ message.isAnswer();
|
||||
const SIPHeaderLine* hl = message.getHeader(local ? "From" : "To");
|
||||
const MimeHeaderLine* hl = message.getHeader(local ? "From" : "To");
|
||||
localURI = hl;
|
||||
if (localURI.matches(r))
|
||||
localURI = localURI.matchString(1);
|
||||
|
|
|
@ -48,7 +48,7 @@ SIPTransaction::SIPTransaction(SIPMessage* message, SIPEngine* engine, bool outg
|
|||
if (ns)
|
||||
m_tag = *ns;
|
||||
|
||||
const SIPHeaderLine* hl = message->getHeader("Call-ID");
|
||||
const MimeHeaderLine* hl = message->getHeader("Call-ID");
|
||||
if (hl)
|
||||
m_callid = *hl;
|
||||
|
||||
|
@ -83,7 +83,7 @@ SIPTransaction::SIPTransaction(SIPTransaction& original, SIPMessage* answer)
|
|||
&original,answer,this);
|
||||
|
||||
SIPMessage* msg = new SIPMessage(*original.m_firstMessage);
|
||||
SIPAuthLine* auth = answer->buildAuth(*original.m_firstMessage);
|
||||
MimeAuthLine* auth = answer->buildAuth(*original.m_firstMessage);
|
||||
m_firstMessage->setAutoAuth();
|
||||
msg->complete(m_engine);
|
||||
msg->addHeader(auth);
|
||||
|
@ -370,7 +370,7 @@ void SIPTransaction::requestAuth(const String& realm, const String& domain, bool
|
|||
if (realm) {
|
||||
String tmp;
|
||||
tmp << "Digest realm=\"" << realm << "\"";
|
||||
SIPHeaderLine* line = new SIPHeaderLine(hdr,tmp,',');
|
||||
MimeHeaderLine* line = new MimeHeaderLine(hdr,tmp,',');
|
||||
if (domain)
|
||||
line->setParam(" domain","\"" + domain + "\"");
|
||||
m_engine->nonceGet(tmp);
|
||||
|
|
|
@ -75,68 +75,6 @@ const char* compactForm(const char* header)
|
|||
return header;
|
||||
}
|
||||
|
||||
// Utility function, puts quotes around a string
|
||||
void addQuotes(String& str)
|
||||
{
|
||||
str.trimBlanks();
|
||||
int l = str.length();
|
||||
if ((l < 2) || (str[0] != '"') || (str[l-1] != '"'))
|
||||
str = "\"" + str + "\"";
|
||||
}
|
||||
|
||||
// Utility function, removes quotes around a string
|
||||
void delQuotes(String& str)
|
||||
{
|
||||
str.trimBlanks();
|
||||
int l = str.length();
|
||||
if ((l >= 2) && (str[0] == '"') && (str[l-1] == '"')) {
|
||||
str = str.substr(1,l-2);
|
||||
str.trimBlanks();
|
||||
}
|
||||
}
|
||||
|
||||
// Utility function, puts quotes around a string
|
||||
String quote(const String& str)
|
||||
{
|
||||
String tmp(str);
|
||||
addQuotes(tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Utility function to find a separator not in "quotes" or inside <uri>
|
||||
int findSep(const char* str, char sep, int offs)
|
||||
{
|
||||
if (!(str && sep))
|
||||
return -1;
|
||||
str += offs;
|
||||
bool inQ = false;
|
||||
bool inU = false;
|
||||
char c;
|
||||
for (; (c = *str++) ; offs++) {
|
||||
if (inQ) {
|
||||
if (c == '"')
|
||||
inQ = false;
|
||||
continue;
|
||||
}
|
||||
if (inU) {
|
||||
if (c == '>')
|
||||
inU = false;
|
||||
continue;
|
||||
}
|
||||
if (c == sep)
|
||||
return offs;
|
||||
switch (c) {
|
||||
case '"':
|
||||
inQ = true;
|
||||
break;
|
||||
case '<':
|
||||
inU = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* vi: set ts=8 sw=4 sts=4 noet: */
|
||||
|
|
|
@ -31,18 +31,6 @@ const char* uncompactForm(const char* header);
|
|||
// Utility function, returns a compacted header name
|
||||
const char* compactForm(const char* header);
|
||||
|
||||
// Utility function, puts quotes around a string
|
||||
void addQuotes(String& str);
|
||||
|
||||
// Utility function, removes quotes around a string
|
||||
void delQuotes(String& str);
|
||||
|
||||
// Utility function, puts quotes around a string
|
||||
String quote(const String& str);
|
||||
|
||||
// Utility function to find a separator not in "quotes" or inside <uri>
|
||||
int findSep(const char* str, char sep, int offs = 0);
|
||||
|
||||
}
|
||||
|
||||
/* vi: set ts=8 sw=4 sts=4 noet: */
|
||||
|
|
|
@ -84,39 +84,6 @@ protected:
|
|||
int m_partyPort;
|
||||
};
|
||||
|
||||
class YSIP_API SIPHeaderLine : public NamedString
|
||||
{
|
||||
public:
|
||||
SIPHeaderLine(const char* name, const String& value, char sep = 0);
|
||||
SIPHeaderLine(const SIPHeaderLine& original, const char* newName = 0);
|
||||
virtual ~SIPHeaderLine();
|
||||
virtual void* getObject(const String& name) const;
|
||||
virtual SIPHeaderLine* clone(const char* newName = 0) const;
|
||||
virtual void buildLine(String& line) const;
|
||||
inline SIPHeaderLine& operator=(const char* value)
|
||||
{ NamedString::operator=(value); return *this; }
|
||||
inline const ObjList& params() const
|
||||
{ return m_params; }
|
||||
inline char separator() const
|
||||
{ return m_separator; }
|
||||
void setParam(const char* name, const char* value = 0);
|
||||
void delParam(const char* name);
|
||||
const NamedString* getParam(const char* name) const;
|
||||
protected:
|
||||
ObjList m_params;
|
||||
char m_separator;
|
||||
};
|
||||
|
||||
class YSIP_API SIPAuthLine : public SIPHeaderLine
|
||||
{
|
||||
public:
|
||||
SIPAuthLine(const char* name, const String& value);
|
||||
SIPAuthLine(const SIPAuthLine& original, const char* newName = 0);
|
||||
virtual void* getObject(const String& name) const;
|
||||
virtual SIPHeaderLine* clone(const char* newName = 0) const;
|
||||
virtual void buildLine(String& line) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* An object that holds the sip message parsed into this library model.
|
||||
* This class can be used to parse a sip message from a text buffer, or it
|
||||
|
@ -241,14 +208,14 @@ public:
|
|||
* @param name Name of the header to locate
|
||||
* @return A pointer to the first matching header line or 0 if not found
|
||||
*/
|
||||
const SIPHeaderLine* getHeader(const char* name) const;
|
||||
const MimeHeaderLine* getHeader(const char* name) const;
|
||||
|
||||
/**
|
||||
* Find the last header line that matches a given name name
|
||||
* @param name Name of the header to locate
|
||||
* @return A pointer to the last matching header line or 0 if not found
|
||||
*/
|
||||
const SIPHeaderLine* getLastHeader(const char* name) const;
|
||||
const MimeHeaderLine* getLastHeader(const char* name) const;
|
||||
|
||||
/**
|
||||
* Count the header lines matching a specific name
|
||||
|
@ -286,13 +253,13 @@ public:
|
|||
* @param value Content of the new header line
|
||||
*/
|
||||
inline void addHeader(const char* name, const char* value = 0)
|
||||
{ header.append(new SIPHeaderLine(name,value)); }
|
||||
{ header.append(new MimeHeaderLine(name,value)); }
|
||||
|
||||
/**
|
||||
* Append an already constructed header line
|
||||
* @param line Header line to add
|
||||
*/
|
||||
inline void addHeader(SIPHeaderLine* line)
|
||||
inline void addHeader(MimeHeaderLine* line)
|
||||
{ header.append(line); }
|
||||
|
||||
/**
|
||||
|
@ -316,7 +283,7 @@ public:
|
|||
* @param proxy Set to true to authenticate to a proxy, false to a server
|
||||
* @return A new authorization line to be used in a new transaction
|
||||
*/
|
||||
SIPAuthLine* buildAuth(const String& username, const String& password,
|
||||
MimeAuthLine* buildAuth(const String& username, const String& password,
|
||||
const String& meth, const String& uri, bool proxy = false) const;
|
||||
|
||||
/**
|
||||
|
@ -324,7 +291,7 @@ public:
|
|||
* @param original Origianl outgoing message
|
||||
* @return A new authorization line to be used in a new transaction
|
||||
*/
|
||||
SIPAuthLine* buildAuth(const SIPMessage& original) const;
|
||||
MimeAuthLine* buildAuth(const SIPMessage& original) const;
|
||||
|
||||
/**
|
||||
* Prepare the message for automatic client transaction authentication.
|
||||
|
@ -350,13 +317,13 @@ public:
|
|||
|
||||
/**
|
||||
* Extract routes from Record-Route: headers
|
||||
* @return A list of SIPHeaderLine representing SIP routes
|
||||
* @return A list of MimeHeaderLine representing SIP routes
|
||||
*/
|
||||
ObjList* getRoutes() const;
|
||||
|
||||
/**
|
||||
* Add Route: headers to an outgoing message
|
||||
* @param routes List of SIPHeaderLine representing SIP routes
|
||||
* @param routes List of MimeHeaderLine representing SIP routes
|
||||
*/
|
||||
void addRoutes(const ObjList* routes);
|
||||
|
||||
|
|
|
@ -377,7 +377,7 @@ private:
|
|||
bool addSdpParams(Message& msg, const MimeBody* body);
|
||||
bool addRtpParams(Message& msg, const String& natAddr, const MimeBody* body);
|
||||
bool startClientReInvite(Message& msg);
|
||||
bool initUnattendedTransfer(Message*& msg, SIPMessage*& sipNotify, const SIPMessage* sipRefer, const SIPHeaderLine* refHdr);
|
||||
bool initUnattendedTransfer(Message*& msg, SIPMessage*& sipNotify, const SIPMessage* sipRefer, const MimeHeaderLine* refHdr);
|
||||
|
||||
SIPTransaction* m_tr;
|
||||
SIPTransaction* m_tr2;
|
||||
|
@ -723,7 +723,7 @@ static void copySipHeaders(Message& msg, const SIPMessage& sip, bool filter = tr
|
|||
{
|
||||
const ObjList* l = sip.header.skipNull();
|
||||
for (; l; l = l->skipNext()) {
|
||||
const SIPHeaderLine* t = static_cast<const SIPHeaderLine*>(l->get());
|
||||
const MimeHeaderLine* t = static_cast<const MimeHeaderLine*>(l->get());
|
||||
String name(t->name());
|
||||
name.toLower();
|
||||
if (matchAny(name,s_rejectHeaders))
|
||||
|
@ -763,7 +763,7 @@ static void copySipHeaders(SIPMessage& sip, const Message& msg, const char* pref
|
|||
static void copyPrivacy(Message& msg, const SIPMessage& sip)
|
||||
{
|
||||
bool anonip = (sip.getHeaderValue("Anonymity") &= "ipaddr");
|
||||
const SIPHeaderLine* hl = sip.getHeader("Remote-Party-ID");
|
||||
const MimeHeaderLine* hl = sip.getHeader("Remote-Party-ID");
|
||||
if (!(anonip || hl))
|
||||
return;
|
||||
const NamedString* p = hl ? hl->getParam("screen") : 0;
|
||||
|
@ -807,7 +807,7 @@ static void copyPrivacy(SIPMessage& sip, const Message& msg)
|
|||
if (tmp)
|
||||
tmp = "\"" + tmp + "\" ";
|
||||
tmp << "<sip:" << caller << "@" << msg.getValue("domain","domain") << ">";
|
||||
SIPHeaderLine* hl = new SIPHeaderLine("Remote-Party-ID",tmp);
|
||||
MimeHeaderLine* hl = new MimeHeaderLine("Remote-Party-ID",tmp);
|
||||
if (screen)
|
||||
hl->setParam("screen","yes");
|
||||
if (privname && privuri)
|
||||
|
@ -1451,7 +1451,7 @@ void YateSIPEndPoint::regreq(SIPEvent* e, SIPTransaction* t)
|
|||
return;
|
||||
}
|
||||
const SIPMessage* message = e->getMessage();
|
||||
const SIPHeaderLine* hl = message->getHeader("Contact");
|
||||
const MimeHeaderLine* hl = message->getHeader("Contact");
|
||||
if (!hl) {
|
||||
t->setResponse(400);
|
||||
return;
|
||||
|
@ -1542,7 +1542,7 @@ void YateSIPEndPoint::regreq(SIPEvent* e, SIPTransaction* t)
|
|||
tmp = expires;
|
||||
SIPMessage* r = new SIPMessage(t->initialMessage(),200);
|
||||
r->addHeader("Expires",tmp);
|
||||
SIPHeaderLine* contact = new SIPHeaderLine("Contact","<" + addr + ">");
|
||||
MimeHeaderLine* contact = new MimeHeaderLine("Contact","<" + addr + ">");
|
||||
contact->setParam("expires",tmp);
|
||||
r->addHeader(contact);
|
||||
if (natChanged) {
|
||||
|
@ -1562,7 +1562,7 @@ void YateSIPEndPoint::regreq(SIPEvent* e, SIPTransaction* t)
|
|||
|
||||
void YateSIPEndPoint::options(SIPEvent* e, SIPTransaction* t)
|
||||
{
|
||||
const SIPHeaderLine* acpt = e->getMessage()->getHeader("Accept");
|
||||
const MimeHeaderLine* acpt = e->getMessage()->getHeader("Accept");
|
||||
if (acpt) {
|
||||
if (*acpt != "application/sdp") {
|
||||
t->setResponse(415);
|
||||
|
@ -1736,7 +1736,7 @@ YateSIPConnection::YateSIPConnection(SIPEvent* ev, SIPTransaction* tr)
|
|||
m->addParam("called",uri.getUser());
|
||||
if (m_uri.getDescription())
|
||||
m->addParam("callername",m_uri.getDescription());
|
||||
const SIPHeaderLine* hl = m_tr->initialMessage()->getHeader("Call-Info");
|
||||
const MimeHeaderLine* hl = m_tr->initialMessage()->getHeader("Call-Info");
|
||||
if (hl) {
|
||||
const NamedString* type = hl->getParam("purpose");
|
||||
if (!type || *type == "info")
|
||||
|
@ -1885,14 +1885,14 @@ YateSIPConnection::YateSIPConnection(Message& msg, const String& uri, const char
|
|||
if (display) {
|
||||
String desc;
|
||||
desc << "\"" << display << "\" ";
|
||||
SIPHeaderLine* hl = const_cast<SIPHeaderLine*>(m->getHeader("From"));
|
||||
MimeHeaderLine* hl = const_cast<MimeHeaderLine*>(m->getHeader("From"));
|
||||
if (hl)
|
||||
*hl = desc + *hl;
|
||||
}
|
||||
if (msg.getParam("calledname")) {
|
||||
String desc;
|
||||
desc << "\"" << msg.getValue("calledname") << "\" ";
|
||||
SIPHeaderLine* hl = const_cast<SIPHeaderLine*>(m->getHeader("To"));
|
||||
MimeHeaderLine* hl = const_cast<MimeHeaderLine*>(m->getHeader("To"));
|
||||
if (hl)
|
||||
*hl = desc + *hl;
|
||||
}
|
||||
|
@ -1909,19 +1909,19 @@ YateSIPConnection::YateSIPConnection(Message& msg, const String& uri, const char
|
|||
// add some Call-Info headers
|
||||
const char* info = msg.getValue("caller_info_uri");
|
||||
if (info) {
|
||||
SIPHeaderLine* hl = new SIPHeaderLine("Call-Info",info);
|
||||
MimeHeaderLine* hl = new MimeHeaderLine("Call-Info",info);
|
||||
hl->setParam("purpose","info");
|
||||
m->addHeader(hl);
|
||||
}
|
||||
info = msg.getValue("caller_icon_uri");
|
||||
if (info) {
|
||||
SIPHeaderLine* hl = new SIPHeaderLine("Call-Info",info);
|
||||
MimeHeaderLine* hl = new MimeHeaderLine("Call-Info",info);
|
||||
hl->setParam("purpose","icon");
|
||||
m->addHeader(hl);
|
||||
}
|
||||
info = msg.getValue("caller_card_uri");
|
||||
if (info) {
|
||||
SIPHeaderLine* hl = new SIPHeaderLine("Call-Info",info);
|
||||
MimeHeaderLine* hl = new MimeHeaderLine("Call-Info",info);
|
||||
hl->setParam("purpose","card");
|
||||
m->addHeader(hl);
|
||||
}
|
||||
|
@ -2058,7 +2058,7 @@ void YateSIPConnection::hangup()
|
|||
tmp << i->getCSeq() << " CANCEL";
|
||||
m->addHeader("CSeq",tmp);
|
||||
if (m_reason == "pickup") {
|
||||
SIPHeaderLine* hl = new SIPHeaderLine("Reason","SIP");
|
||||
MimeHeaderLine* hl = new MimeHeaderLine("Reason","SIP");
|
||||
hl->setParam("cause","200");
|
||||
hl->setParam("text","\"Call completed elsewhere\"");
|
||||
m->addHeader(hl);
|
||||
|
@ -2078,7 +2078,7 @@ void YateSIPConnection::hangup()
|
|||
if (m) {
|
||||
if (m_reason) {
|
||||
// FIXME: add SIP and Q.850 cause codes, set the proper reason
|
||||
SIPHeaderLine* hl = new SIPHeaderLine("Reason","SIP");
|
||||
MimeHeaderLine* hl = new MimeHeaderLine("Reason","SIP");
|
||||
hl->setParam("text","\"" + m_reason + "\"");
|
||||
m->addHeader(hl);
|
||||
}
|
||||
|
@ -2108,7 +2108,7 @@ SIPMessage* YateSIPConnection::createDlgMsg(const char* method, const char* uri)
|
|||
m->addHeader("Call-ID",m_callid);
|
||||
String tmp;
|
||||
tmp << "<" << m_dialog.localURI << ">";
|
||||
SIPHeaderLine* hl = new SIPHeaderLine("From",tmp);
|
||||
MimeHeaderLine* hl = new MimeHeaderLine("From",tmp);
|
||||
tmp = m_dialog.localTag;
|
||||
if (tmp.null() && m_tr)
|
||||
tmp = m_tr->getDialogTag();
|
||||
|
@ -2117,7 +2117,7 @@ SIPMessage* YateSIPConnection::createDlgMsg(const char* method, const char* uri)
|
|||
m->addHeader(hl);
|
||||
tmp.clear();
|
||||
tmp << "<" << m_dialog.remoteURI << ">";
|
||||
hl = new SIPHeaderLine("To",tmp);
|
||||
hl = new MimeHeaderLine("To",tmp);
|
||||
tmp = m_dialog.remoteTag;
|
||||
if (tmp.null() && m_tr)
|
||||
tmp = m_tr->getDialogTag();
|
||||
|
@ -2134,8 +2134,8 @@ bool YateSIPConnection::emitPRACK(const SIPMessage* msg)
|
|||
return false;
|
||||
if (!plugin.ep()->engine()->prack())
|
||||
return true;
|
||||
const SIPHeaderLine* rs = msg->getHeader("RSeq");
|
||||
const SIPHeaderLine* cs = msg->getHeader("CSeq");
|
||||
const MimeHeaderLine* rs = msg->getHeader("RSeq");
|
||||
const MimeHeaderLine* cs = msg->getHeader("CSeq");
|
||||
if (!(rs && cs))
|
||||
return true;
|
||||
int seq = rs->toInteger(0,10);
|
||||
|
@ -2148,7 +2148,7 @@ bool YateSIPConnection::emitPRACK(const SIPMessage* msg)
|
|||
return false;
|
||||
}
|
||||
String tmp;
|
||||
const SIPHeaderLine* co = msg->getHeader("Contact");
|
||||
const MimeHeaderLine* co = msg->getHeader("Contact");
|
||||
if (co) {
|
||||
tmp = *co;
|
||||
Regexp r("^[^<]*<\\([^>]*\\)>.*$");
|
||||
|
@ -2616,7 +2616,7 @@ bool YateSIPConnection::process(SIPEvent* ev)
|
|||
// see if we should detect our external address
|
||||
const YateSIPLine* line = plugin.findLine(m_line);
|
||||
if (line && line->localDetect()) {
|
||||
SIPHeaderLine* hl = const_cast<SIPHeaderLine*>(msg->getHeader("Via"));
|
||||
MimeHeaderLine* hl = const_cast<MimeHeaderLine*>(msg->getHeader("Via"));
|
||||
if (hl) {
|
||||
const NamedString* par = hl->getParam("received");
|
||||
if (par && *par) {
|
||||
|
@ -2922,7 +2922,7 @@ void YateSIPConnection::doBye(SIPTransaction* t)
|
|||
if (m_authBye && !checkUser(t))
|
||||
return;
|
||||
DDebug(this,DebugAll,"YateSIPConnection::doBye(%p) [%p]",t,this);
|
||||
const SIPHeaderLine* hl = t->initialMessage()->getHeader("Reason");
|
||||
const MimeHeaderLine* hl = t->initialMessage()->getHeader("Reason");
|
||||
if (hl) {
|
||||
const NamedString* text = hl->getParam("text");
|
||||
if (text)
|
||||
|
@ -3001,7 +3001,7 @@ void YateSIPConnection::doRefer(SIPTransaction* t)
|
|||
return;
|
||||
}
|
||||
m_referring = true;
|
||||
const SIPHeaderLine* refHdr = t->initialMessage()->getHeader("Refer-To");
|
||||
const MimeHeaderLine* refHdr = t->initialMessage()->getHeader("Refer-To");
|
||||
if (!(refHdr && refHdr->length())) {
|
||||
DDebug(this,DebugAll,"YateSIPConnection::doRefer(%p) [%p]. Empty or missing 'Refer-To' header.",t,this);
|
||||
t->setResponse(400); // Bad request
|
||||
|
@ -3093,7 +3093,7 @@ bool YateSIPConnection::msgAnswered(Message& msg)
|
|||
}
|
||||
m->setBody(sdp);
|
||||
|
||||
const SIPHeaderLine* co = m_tr->initialMessage()->getHeader("Contact");
|
||||
const MimeHeaderLine* co = m_tr->initialMessage()->getHeader("Contact");
|
||||
if (co) {
|
||||
// INVITE had a Contact: header - time to change remote URI
|
||||
m_uri = *co;
|
||||
|
@ -3422,7 +3422,7 @@ void YateSIPConnection::startPendingUpdate()
|
|||
// sipRefer: received REFER message, refHdr: 'Refer-To' header
|
||||
// If return false, msg and sipNotify are 0
|
||||
bool YateSIPConnection::initUnattendedTransfer(Message*& msg, SIPMessage*& sipNotify,
|
||||
const SIPMessage* sipRefer, const SIPHeaderLine* refHdr)
|
||||
const SIPMessage* sipRefer, const MimeHeaderLine* refHdr)
|
||||
{
|
||||
// call.route
|
||||
msg = new Message("call.route");
|
||||
|
@ -3432,7 +3432,7 @@ bool YateSIPConnection::initUnattendedTransfer(Message*& msg, SIPMessage*& sipNo
|
|||
if (m_user)
|
||||
msg->addParam("username",m_user);
|
||||
|
||||
const SIPHeaderLine* sh = sipRefer->getHeader("To"); // caller
|
||||
const MimeHeaderLine* sh = sipRefer->getHeader("To"); // caller
|
||||
if (sh) {
|
||||
URI uriCaller(*sh);
|
||||
uriCaller.parse();
|
||||
|
@ -3456,7 +3456,7 @@ bool YateSIPConnection::initUnattendedTransfer(Message*& msg, SIPMessage*& sipNo
|
|||
msg->addParam("reason","transfer"); // reason
|
||||
// NOTIFY
|
||||
String tmp;
|
||||
const SIPHeaderLine* co = sipRefer->getHeader("Contact");
|
||||
const MimeHeaderLine* co = sipRefer->getHeader("Contact");
|
||||
if (co) {
|
||||
tmp = *co;
|
||||
Regexp r("^[^<]*<\\([^>]*\\)>.*$");
|
||||
|
@ -3651,7 +3651,7 @@ void YateSIPLine::detectLocal(const SIPMessage* msg)
|
|||
return;
|
||||
String laddr = m_localAddr;
|
||||
int lport = m_localPort;
|
||||
SIPHeaderLine* hl = const_cast<SIPHeaderLine*>(msg->getHeader("Via"));
|
||||
MimeHeaderLine* hl = const_cast<MimeHeaderLine*>(msg->getHeader("Via"));
|
||||
if (hl) {
|
||||
const NamedString* par = hl->getParam("received");
|
||||
if (par && *par)
|
||||
|
|
189
yatemime.h
189
yatemime.h
|
@ -36,6 +36,176 @@
|
|||
*/
|
||||
namespace TelEngine {
|
||||
|
||||
/**
|
||||
* A MIME header line.
|
||||
* The NamedString's value contain the first parameter after the header name
|
||||
* @short MIME header line
|
||||
*/
|
||||
class YATE_API MimeHeaderLine : public NamedString
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* Builds a MIME header line from a string buffer.
|
||||
* Splits the value into header parameters
|
||||
* @param name The header name
|
||||
* @param value The header value
|
||||
* @param sep Optional parameter separator. If 0, the default ';' will be used
|
||||
*/
|
||||
MimeHeaderLine(const char* name, const String& value, char sep = 0);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Builds this MIME header line from another one
|
||||
* @param original Original header line to build from.
|
||||
* @param newName Optional new header name. If 0, the original name will be used
|
||||
*/
|
||||
MimeHeaderLine(const MimeHeaderLine& original, const char* newName = 0);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~MimeHeaderLine();
|
||||
|
||||
/**
|
||||
* RTTI method, get a pointer to a derived class given the class name.
|
||||
* @param name Name of the class we are asking for
|
||||
* @return Pointer to the requested class or NULL if this object doesn't implement it
|
||||
*/
|
||||
virtual void* getObject(const String& name) const;
|
||||
|
||||
/**
|
||||
* Duplicate this MIME header line.
|
||||
* @param newName Optional new header name. If 0, this header's name will be used
|
||||
* @return Copy of this MIME header line
|
||||
*/
|
||||
virtual MimeHeaderLine* clone(const char* newName = 0) const;
|
||||
|
||||
/**
|
||||
* Build a string line from this MIME header without adding a line separator
|
||||
* @param line Destination string
|
||||
*/
|
||||
virtual void buildLine(String& line) const;
|
||||
|
||||
/**
|
||||
* Assignement operator. Set the header's value
|
||||
* @param value The new headr value
|
||||
*/
|
||||
inline MimeHeaderLine& operator=(const char* value)
|
||||
{ NamedString::operator=(value); return *this; }
|
||||
|
||||
/**
|
||||
* Get the header's parameters
|
||||
* @return This header's list of parameters
|
||||
*/
|
||||
inline const ObjList& params() const
|
||||
{ return m_params; }
|
||||
|
||||
/**
|
||||
* Get the character used as separator in header line
|
||||
* @return This header's separator
|
||||
*/
|
||||
inline char separator() const
|
||||
{ return m_separator; }
|
||||
|
||||
/**
|
||||
* Replace the value of an existing parameter or add a new one
|
||||
* @param name Parameter's name
|
||||
* @param value Parameter's value
|
||||
*/
|
||||
void setParam(const char* name, const char* value = 0);
|
||||
|
||||
/**
|
||||
* Remove a parameter from list
|
||||
* @param name Parameter's name
|
||||
*/
|
||||
void delParam(const char* name);
|
||||
|
||||
/**
|
||||
* Get a header parameter
|
||||
* @param name Parameter's name
|
||||
* @return Pointer to the desired parameter or 0 if not found
|
||||
*/
|
||||
const NamedString* getParam(const char* name) const;
|
||||
|
||||
/**
|
||||
* Utility function, puts quotes around a string.
|
||||
* @param str String to put quotes around.
|
||||
*/
|
||||
static void addQuotes(String& str);
|
||||
|
||||
/**
|
||||
* Utility function, removes quotes around a string.
|
||||
* @param str String to remove quotes.
|
||||
*/
|
||||
static void delQuotes(String& str);
|
||||
|
||||
/**
|
||||
* Utility function, puts quotes around a string.
|
||||
* @param str String to put quotes around.
|
||||
* @return The input string enclosed in quotes.
|
||||
*/
|
||||
static String quote(const String& str);
|
||||
|
||||
/**
|
||||
* Utility function to find a separator not in "quotes" or inside <uri>.
|
||||
* @param str Input string used to find the separator.
|
||||
* @param sep The separator to find.
|
||||
* @param offs Starting offset in input string.
|
||||
* @return The position of the separator in input string or -1 if not found.
|
||||
*/
|
||||
static int findSep(const char* str, char sep, int offs = 0);
|
||||
|
||||
protected:
|
||||
ObjList m_params; // Header list of parameters
|
||||
char m_separator; // Parameter separator
|
||||
};
|
||||
|
||||
/**
|
||||
* A MIME header line containing authentication data.
|
||||
* @short MIME authentication line
|
||||
*/
|
||||
class YATE_API MimeAuthLine : public MimeHeaderLine
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* Builds a MIME authentication header line from a string buffer.
|
||||
* Splits the value into header parameters
|
||||
* @param name The header name
|
||||
* @param value The header value
|
||||
*/
|
||||
MimeAuthLine(const char* name, const String& value);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Builds this MIME authentication header line from another one
|
||||
* @param original Original header line to build from.
|
||||
* @param newName Optional new header name. If 0, the original name will be used
|
||||
*/
|
||||
MimeAuthLine(const MimeAuthLine& original, const char* newName = 0);
|
||||
|
||||
/**
|
||||
* RTTI method, get a pointer to a derived class given the class name.
|
||||
* @param name Name of the class we are asking for
|
||||
* @return Pointer to the requested class or NULL if this object doesn't implement it
|
||||
*/
|
||||
virtual void* getObject(const String& name) const;
|
||||
|
||||
/**
|
||||
* Duplicate this MIME header line.
|
||||
* @param newName Optional new header name. If 0, this header's name will be used
|
||||
* @return Copy of this MIME header line
|
||||
*/
|
||||
virtual MimeHeaderLine* clone(const char* newName = 0) const;
|
||||
|
||||
/**
|
||||
* Build a string line from this MIME header without adding a line separator
|
||||
* @param line Destination string
|
||||
*/
|
||||
virtual void buildLine(String& line) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract base class for holding Multipurpose Internet Mail Extensions data
|
||||
* @short Abstract MIME data holder
|
||||
|
@ -49,7 +219,7 @@ public:
|
|||
virtual ~MimeBody();
|
||||
|
||||
/**
|
||||
* RTTI method, get a pointer to a derived class given that class name
|
||||
* RTTI method, get a pointer to a derived class given the class name
|
||||
* @param name Name of the class we are asking for
|
||||
* @return Pointer to the requested class or NULL if this object doesn't implement it
|
||||
*/
|
||||
|
@ -59,7 +229,7 @@ public:
|
|||
* Retrive the MIME type of this body
|
||||
* @return Name of the MIME type/subtype
|
||||
*/
|
||||
inline const String& getType() const
|
||||
inline const MimeHeaderLine& getType() const
|
||||
{ return m_type; }
|
||||
|
||||
/**
|
||||
|
@ -92,7 +262,8 @@ public:
|
|||
* Method to build a MIME body from a type and data buffer
|
||||
* @param buf Pointer to buffer of data
|
||||
* @param len Length of data in buffer
|
||||
* @param type Name of the MIME type/subtype, must be lower case
|
||||
* @param type Name of the MIME type/subtype, must be lower case.
|
||||
* This is the whole content type line, including the parameters
|
||||
* @return Newly allocated MIME body or NULL if type is unknown
|
||||
*/
|
||||
static MimeBody* build(const char* buf, int len, const String& type);
|
||||
|
@ -123,7 +294,7 @@ protected:
|
|||
mutable DataBlock m_body;
|
||||
|
||||
private:
|
||||
String m_type;
|
||||
MimeHeaderLine m_type; // Content type header line
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -140,9 +311,9 @@ public:
|
|||
|
||||
/**
|
||||
* Constructor from block of data
|
||||
* @param type Name of the MIME type/subtype, should be "application/sdp"
|
||||
* @param buf Pointer to buffer of data
|
||||
* @param len Length of data in buffer
|
||||
* @param type Name of the MIME type/subtype, should be "application/sdp"
|
||||
*/
|
||||
MimeSdpBody(const String& type, const char* buf, int len);
|
||||
|
||||
|
@ -152,7 +323,7 @@ public:
|
|||
virtual ~MimeSdpBody();
|
||||
|
||||
/**
|
||||
* RTTI method, get a pointer to a derived class given that class name
|
||||
* RTTI method, get a pointer to a derived class given the class name
|
||||
* @param name Name of the class we are asking for
|
||||
* @return Pointer to the requested class or NULL if this object doesn't implement it
|
||||
*/
|
||||
|
@ -236,7 +407,7 @@ public:
|
|||
virtual ~MimeBinaryBody();
|
||||
|
||||
/**
|
||||
* RTTI method, get a pointer to a derived class given that class name
|
||||
* RTTI method, get a pointer to a derived class given the class name
|
||||
* @param name Name of the class we are asking for
|
||||
* @return Pointer to the requested class or NULL if this object doesn't implement it
|
||||
*/
|
||||
|
@ -281,7 +452,7 @@ public:
|
|||
virtual ~MimeStringBody();
|
||||
|
||||
/**
|
||||
* RTTI method, get a pointer to a derived class given that class name
|
||||
* RTTI method, get a pointer to a derived class given the class name
|
||||
* @param name Name of the class we are asking for
|
||||
* @return Pointer to the requested class or NULL if this object doesn't implement it
|
||||
*/
|
||||
|
@ -336,7 +507,7 @@ public:
|
|||
virtual ~MimeLinesBody();
|
||||
|
||||
/**
|
||||
* RTTI method, get a pointer to a derived class given that class name
|
||||
* RTTI method, get a pointer to a derived class given the class name
|
||||
* @param name Name of the class we are asking for
|
||||
* @return Pointer to the requested class or NULL if this object doesn't implement it
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue