reSIProcate/stack  9694
Classes | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes
resip::MessageWaitingContents Class Reference

SIP body type for holding MWI contents (MIME content-type application/simple-message-summary). More...

#include <MessageWaitingContents.hxx>

Inheritance diagram for resip::MessageWaitingContents:
Inheritance graph
[legend]
Collaboration diagram for resip::MessageWaitingContents:
Collaboration graph
[legend]

List of all members.

Classes

class  AccountHeader
 makes accessing the MessageAccount Uri operate like accessing the other MessageWaiting headers. More...
class  Header
 Provides an interface for reading and modifying MessageWaiting bodies. More...

Public Member Functions

 MessageWaitingContents ()
 MessageWaitingContents (const HeaderFieldValue &hfv, const Mime &contentType)
 MessageWaitingContents (const Data &data, const Mime &contentType)
 MessageWaitingContents (const MessageWaitingContents &rhs)
virtual ~MessageWaitingContents ()
MessageWaitingContentsoperator= (const MessageWaitingContents &rhs)
virtual Contentsclone () const
 duplicate an MessageWaitingContents object
virtual EncodeStreamencodeParsed (EncodeStream &str) const
virtual void parse (ParseBuffer &pb)
Headerheader (HeaderType ht)
 Get the header correspoding to ht.
const Headerheader (HeaderType ht) const
bool exists (HeaderType ht) const
 Check if HeaderType is present.
void remove (HeaderType ht)
 Remove the header correspoding to ht.
const Uriheader (const AccountHeader &ht) const
 Get the Uri for Message-Account line.
Uriheader (const AccountHeader &ht)
bool exists (const AccountHeader &ht) const
 Check if Message-Account line is present.
void remove (const AccountHeader &ht)
 Remove the Uri for Message-Account line.
const Dataheader (const Data &hn) const
 Get the value correspoding to optional message header hn in the MessageWaiting doc.
Dataheader (const Data &hn)
bool exists (const Data &hn) const
 Check if optional message header hn is present.
void remove (const Data &hn)
 Remove the optional message header corresponding to hn.
bool & hasMessages ()
 Check to see if there are messages.

Static Public Member Functions

static const MimegetStaticType ()
static bool init ()

Private Member Functions

void clear ()

Private Attributes

bool mHasMessages
UrimAccountUri
HeadermHeaders [MW_MAX]
std::map< Data, DatamExtensions

Detailed Description

SIP body type for holding MWI contents (MIME content-type application/simple-message-summary).

See resip/stack/test/testMessageWaiting.cxx for usage examples.

Definition at line 26 of file MessageWaitingContents.hxx.


Constructor & Destructor Documentation

MessageWaitingContents::MessageWaitingContents ( )

Definition at line 32 of file MessageWaitingContents.cxx.

References mHeaders.

Referenced by clone().

   : Contents(getStaticType()),
     mHasMessages(false),
     mAccountUri(0)
{
   for(int i = 0; i < (int)MW_MAX; i++)
   {
      mHeaders[i] = 0;
   }
}
MessageWaitingContents::MessageWaitingContents ( const HeaderFieldValue hfv,
const Mime contentType 
)

Definition at line 43 of file MessageWaitingContents.cxx.

References mHeaders.

   : Contents(hfv, contentType),
     mHasMessages(false),
     mAccountUri(0)
{
   for(int i = 0; i < (int)MW_MAX; i++)
   {
      mHeaders[i] = 0;
   }
}
MessageWaitingContents::MessageWaitingContents ( const Data data,
const Mime contentType 
)

Definition at line 54 of file MessageWaitingContents.cxx.

References mHeaders.

   : Contents(contentType),
     mHasMessages(false),
     mAccountUri(0)
{
   for(int i = 0; i < (int)MW_MAX; i++)
   {
      mHeaders[i] = 0;
   }
   assert(0);
}
MessageWaitingContents::MessageWaitingContents ( const MessageWaitingContents rhs)

Definition at line 66 of file MessageWaitingContents.cxx.

References mHeaders.

   : Contents(rhs),
     mHasMessages(rhs.mHasMessages),
     mAccountUri(rhs.mAccountUri ? new Uri(*rhs.mAccountUri) : 0),
     mExtensions(rhs.mExtensions)
{
   for(int i = 0; i < (int)MW_MAX; i++)
   {
      if (rhs.mHeaders[i] != 0)
      {
         mHeaders[i] = new Header(*rhs.mHeaders[i]);
      }
      else
      {
         mHeaders[i] = 0;
      }
   }
}   
MessageWaitingContents::~MessageWaitingContents ( ) [virtual]

Definition at line 85 of file MessageWaitingContents.cxx.

References clear().

{
   clear();
}

Here is the call graph for this function:


Member Function Documentation

void MessageWaitingContents::clear ( void  ) [private]
Todo:
!bwc! Calls freeMem(), then reverts members to a default state (including setting pointers to 0)

Reimplemented from resip::Contents.

Definition at line 91 of file MessageWaitingContents.cxx.

References mAccountUri, mHasMessages, and mHeaders.

Referenced by operator=(), and ~MessageWaitingContents().

{
   mHasMessages = false;

   delete mAccountUri;
   mAccountUri = 0;
   
   for (int i = 0; i < (int)MW_MAX; i++)
   {
      delete mHeaders[i];
   }
}
Contents * MessageWaitingContents::clone ( ) const [virtual]

duplicate an MessageWaitingContents object

Returns:
pointer to a new MessageWaitingContents object

Implements resip::Contents.

Definition at line 140 of file MessageWaitingContents.cxx.

References MessageWaitingContents().

Referenced by main().

{
   return new MessageWaitingContents(*this);
}

Here is the call graph for this function:

EncodeStream & MessageWaitingContents::encodeParsed ( EncodeStream str) const [virtual]

Implements resip::LazyParser.

Definition at line 146 of file MessageWaitingContents.cxx.

References resip::Symbols::COLON, resip::Symbols::CRLF, CRLF, exists(), header(), resip::Symbols::LPAREN, MessageHeaders, mExtensions, mHasMessages, mHeaders, resip::MessageWaitingContents::Header::mNew, resip::MessageWaitingContents::Header::mOld, resip::MessageWaitingContents::Header::mUrgentNew, resip::MessageWaitingContents::Header::mUrgentOld, resip::Symbols::RPAREN, resip::Symbols::SLASH, and resip::Symbols::SPACE.

{
   s << "Messages-Waiting" << Symbols::COLON[0] << Symbols::SPACE[0]
     << (mHasMessages ? "yes" : "no") << Symbols::CRLF;

   if (exists(mw_account))
   {
      s << "Message-Account" << Symbols::COLON[0] << Symbols::SPACE[0];
      header(mw_account).encode(s);
      s << Symbols::CRLF;
   }

   for(int i = 0; i < (int)MW_MAX; i++)
   {
      if (mHeaders[i] != 0)
      {
         s << MessageHeaders[i] << Symbols::COLON[0] << Symbols::SPACE[0]
           << mHeaders[i]->mNew << Symbols::SLASH[0] 
           << mHeaders[i]->mOld;

         if (mHeaders[i]->mHasUrgent)
         {
            s << Symbols::SPACE[0] << Symbols::LPAREN[0]    
              << mHeaders[i]->mUrgentNew << Symbols::SLASH[0] 
              << mHeaders[i]->mUrgentOld << Symbols::RPAREN[0]; 
         }

         s << Symbols::CRLF;
      }
   }

   if (!mExtensions.empty())
   {
      s << Symbols::CRLF;
      for (map<Data, Data>::const_iterator i = mExtensions.begin();
           i != mExtensions.end(); i++)
      {
         s << i->first << Symbols::COLON[0] << Symbols::SPACE[0]
           << i->second << Symbols::CRLF;
      }
   }

   return s;
}

Here is the call graph for this function:

bool MessageWaitingContents::exists ( HeaderType  ht) const

Check if HeaderType is present.

Parameters:
htHeaderType used to lookup MessageWaiting header
Returns:
bool true if HeaderType exists

Definition at line 507 of file MessageWaitingContents.cxx.

References resip::LazyParser::checkParsed(), and mHeaders.

Referenced by encodeParsed(), and main().

{
   checkParsed();
   return mHeaders[ht] != 0;
}

Here is the call graph for this function:

bool MessageWaitingContents::exists ( const AccountHeader ht) const

Check if Message-Account line is present.

Note:
This call only indicates the actual existence of the Message-Account line in the MessageWaiting doc if header(mw_account) hasn't been called. After that call the exists(mw_account) call will return true (since a Uri now exists) whether or not the Uri was built based on the MessageWaiting doc.
Parameters:
htAccountHeader used to lookup MessageWaiting header - not really used computationally
Returns:
bool true if HeaderType exists

Definition at line 562 of file MessageWaitingContents.cxx.

References resip::LazyParser::checkParsed(), and mAccountUri.

{
   checkParsed();
   return mAccountUri != 0;
}

Here is the call graph for this function:

bool MessageWaitingContents::exists ( const Data hn) const

Check if optional message header hn is present.

Parameters:
hnHeaderType used to lookup the optional MessageWaiting header
Returns:
bool true if optional message header exists

Definition at line 606 of file MessageWaitingContents.cxx.

References resip::LazyParser::checkParsed(), and mExtensions.

{
   checkParsed();
   return mExtensions.find(hn) != mExtensions.end();
}

Here is the call graph for this function:

const Mime & MessageWaitingContents::getStaticType ( ) [static]

Definition at line 132 of file MessageWaitingContents.cxx.

References type.

{
   static Mime type("application", "simple-message-summary");
   //static Mime type("text", "data");
   return type;
}
bool& resip::MessageWaitingContents::hasMessages ( ) [inline]

Check to see if there are messages.

Returns:
bool true if there are messages

Definition at line 126 of file MessageWaitingContents.hxx.

References resip::LazyParser::checkParsed(), and mHasMessages.

Referenced by main().

{ checkParsed(); return mHasMessages; }

Here is the call graph for this function:

MessageWaitingContents::Header & MessageWaitingContents::header ( HeaderType  ht)

Get the header correspoding to ht.

Parameters:
htHeaderType used to lookup MessageWaiting header
Returns:
Header corresponding to ht

Definition at line 467 of file MessageWaitingContents.cxx.

References resip::LazyParser::checkParsed(), and mHeaders.

Referenced by encodeParsed(), main(), and parse().

{
   checkParsed();

   /* this is a trick to allow a const method to update "this" with an empty
      Header in case there wasn't a corresponding header line in the MessageWaiting doc
    */
   if (mHeaders[ht] == 0)
   {
      mHeaders[ht] = new Header(0, 0);
   }
   return *mHeaders[ht];
}

Here is the call graph for this function:

const MessageWaitingContents::Header & MessageWaitingContents::header ( HeaderType  ht) const

Definition at line 482 of file MessageWaitingContents.cxx.

References resip::LazyParser::checkParsed(), ErrLog, and mHeaders.

{
   checkParsed();

   /* this is a trick to allow a const method to update "this" with an empty
      Header in case there wasn't a corresponding header line in the MessageWaiting doc
    */
   if (mHeaders[ht] == 0)
   {
      ErrLog(<< "You called "
            "MessageWaitingContents::header(HeaderType ht) _const_ "
            "without first calling exists(), and the header does not exist. Our"
            " behavior in this scenario is to implicitly create the header(using const_cast!); "
            "this is probably not what you want, but it is either this or "
            "assert/throw an exception. Since this has been the behavior for "
            "so long, we are not throwing here, _yet_. You need to fix your "
            "code, before we _do_ start throwing. This is why const-correctness"
            " should never be made a TODO item </rant>");
      MessageWaitingContents* ncthis = const_cast<MessageWaitingContents*>(this);
      ncthis->mHeaders[ht] = new Header(0, 0);
   }
   return *mHeaders[ht];
}

Here is the call graph for this function:

const Uri & MessageWaitingContents::header ( const AccountHeader ht) const

Get the Uri for Message-Account line.

Parameters:
htAccountHeader used to lookup MessageWaiting header - not really used computationally
Returns:
Uri for Message-Account line

Definition at line 537 of file MessageWaitingContents.cxx.

References resip::LazyParser::checkParsed(), ErrLog, and mAccountUri.

{
   checkParsed();

   /* this is a trick to allow a const method to update "this" with an empty
      Uri in case there wasn't a Message-Account line in the MessageWaiting doc
    */
   if (mAccountUri == 0)
   {
      ErrLog(<< "You called "
            "MessageWaitingContents::header(const AccountHeader& ht) _const_ "
            "without first calling exists(), and the header does not exist. Our"
            " behavior in this scenario is to implicitly create the header(using const_cast!); "
            "this is probably not what you want, but it is either this or "
            "assert/throw an exception. Since this has been the behavior for "
            "so long, we are not throwing here, _yet_. You need to fix your "
            "code, before we _do_ start throwing. This is why const-correctness"
            " should never be made a TODO item </rant>");
      MessageWaitingContents* ncthis = const_cast<MessageWaitingContents*>(this);
      ncthis->mAccountUri = new Uri();
   }
   return *mAccountUri;
}

Here is the call graph for this function:

Uri & MessageWaitingContents::header ( const AccountHeader ht)

Definition at line 522 of file MessageWaitingContents.cxx.

References resip::LazyParser::checkParsed(), and mAccountUri.

{
   checkParsed();

   /* this is a trick to allow a const method to update "this" with an empty
      Uri in case there wasn't a Message-Account line in the MessageWaiting doc
    */
   if (mAccountUri == 0)
   {
      mAccountUri = new Uri();
   }
   return *mAccountUri;
}

Here is the call graph for this function:

const Data & MessageWaitingContents::header ( const Data hn) const

Get the value correspoding to optional message header hn in the MessageWaiting doc.

Used to access optional message headers in the MessageWaiting doc

Parameters:
hnHeaderType used to lookup the optional MessageWaiting header
Returns:
Data corresponding to hn

Definition at line 584 of file MessageWaitingContents.cxx.

References resip::LazyParser::checkParsed(), resip::Data::Empty, ErrLog, and mExtensions.

{
   checkParsed();
   std::map<Data, Data>::const_iterator h=mExtensions.find(hn);
   if(h==mExtensions.end())
   {
      ErrLog(<< "You called "
            "MessageWaitingContents::header(const Data& hn) _const_ "
            "without first calling exists(), and the header does not exist. Our"
            " behavior in this scenario is to implicitly create the header(using const_cast!); "
            "this is probably not what you want, but it is either this or "
            "assert/throw an exception. Since this has been the behavior for "
            "so long, we are not throwing here, _yet_. You need to fix your "
            "code, before we _do_ start throwing. This is why const-correctness"
            " should never be made a TODO item </rant>");
      MessageWaitingContents* ncthis = const_cast<MessageWaitingContents*>(this);
      h=ncthis->mExtensions.insert(std::make_pair<Data, Data>(hn,Data::Empty)).first;
   }
   return h->second;
}

Here is the call graph for this function:

Data & MessageWaitingContents::header ( const Data hn)

Definition at line 577 of file MessageWaitingContents.cxx.

References resip::LazyParser::checkParsed(), and mExtensions.

{
   checkParsed();
   return mExtensions[hn];
}

Here is the call graph for this function:

bool MessageWaitingContents::init ( ) [static]

Reimplemented from resip::Contents.

Definition at line 17 of file MessageWaitingContents.cxx.

{
   static ContentsFactory<MessageWaitingContents> factory;
   (void)factory;
   return true;
}
MessageWaitingContents & MessageWaitingContents::operator= ( const MessageWaitingContents rhs)

Definition at line 105 of file MessageWaitingContents.cxx.

References clear(), mAccountUri, mExtensions, mHasMessages, and mHeaders.

{
   if (this != &rhs)
   {
      Contents::operator=(rhs);
      clear();

      mHasMessages = rhs.mHasMessages;
      mAccountUri = rhs.mAccountUri ? new Uri(*rhs.mAccountUri) : 0;
      mExtensions = rhs.mExtensions;

      for(int i = 0; i < (int)MW_MAX; i++)
      {
         if (rhs.mHeaders[i] != 0)
         {
            mHeaders[i] = new Header(*rhs.mHeaders[i]);
         }
         else
         {
            mHeaders[i] = 0;
         }
      }
   }
   return *this;
}

Here is the call graph for this function:

void MessageWaitingContents::parse ( ParseBuffer pb) [virtual]

Implements resip::LazyParser.

Definition at line 288 of file MessageWaitingContents.cxx.

References resip::Symbols::COLON, resip::Symbols::CR, resip::Symbols::CRLF, resip::ParseBuffer::data(), resip::ParseBuffer::eof(), resip::ParseBuffer::fail(), header(), resip::ParseBuffer::integer(), resip::isEqualNoCase(), resip::Symbols::LPAREN, mAccountUri, mExtensions, mHasMessages, mHeaders, resip::Uri::parse(), resip::ParseBuffer::position(), resip::ParseBuffer::reset(), resip::Symbols::RPAREN, resip::ParseBuffer::skipChar(), resip::ParseBuffer::skipChars(), resip::ParseBuffer::skipNonWhitespace(), resip::ParseBuffer::skipToChar(), resip::ParseBuffer::skipToOneOf(), resip::ParseBuffer::skipWhitespace(), resip::Symbols::SLASH, and resip::ParseBuffer::Whitespace.

{
   pb.skipChars("Messages-Waiting");
   pb.skipWhitespace();
   pb.skipChar(Symbols::COLON[0]);
   const char* anchor = pb.skipWhitespace();
   pb.skipNonWhitespace();
   
   Data has;
   pb.data(has, anchor);
   if (isEqualNoCase(has, "yes"))
   {
      mHasMessages = true;
   }
   else if (isEqualNoCase(has, "no"))
   {
      mHasMessages = false;
   }
   else
   {
      pb.fail(__FILE__, __LINE__);
   }

   anchor = pb.skipWhitespace();
   if (pb.eof())
   {
      return;
   }

   Data accountHeader;
   pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::COLON);
   pb.data(accountHeader, anchor);
   static const Data AccountMessage("message-account");
   if (isEqualNoCase(accountHeader, AccountMessage))
   {
      pb.skipWhitespace();
      pb.skipChar(Symbols::COLON[0]);
      pb.skipWhitespace();
      
      mAccountUri = new Uri();
      mAccountUri->parse(pb);
      pb.skipChars(Symbols::CRLF);
   }
   else
   {
      pb.reset(anchor);
   }

   while (!pb.eof() && *pb.position() != Symbols::CR[0])
   {
      int ht = -1;
      switch (tolower(*pb.position()))
      {
         case 'v' :
            ht = mw_voice;
            break;
         case 'f' :
            ht = mw_fax;
            break;
         case 'p' :
            ht = mw_pager;
            break;
         case 'm' :
            ht = mw_multimedia;
            break;
         case 't' :
            ht = mw_text;
            break;
         case 'n' :
            ht = mw_none;
            break;
         default :
            pb.fail(__FILE__, __LINE__);
      }
      assert(ht != -1);

      pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::COLON);
      pb.skipWhitespace();
      pb.skipChar(Symbols::COLON[0]);
      pb.skipWhitespace();

      unsigned int numNew = pb.integer();
      pb.skipWhitespace();
      pb.skipChar(Symbols::SLASH[0]);
      pb.skipWhitespace();

      unsigned int numOld = pb.integer();
      skipSipLWS(pb);

      if (!pb.eof() && *pb.position() != Symbols::LPAREN[0])
      {
         if (mHeaders[ht] != 0)
         {
            pb.fail(__FILE__, __LINE__);
         }
         mHeaders[ht] = new Header(numNew, numOld);
      }
      else
      {
         pb.skipChar();
         pb.skipWhitespace();

         unsigned int numUrgentNew = pb.integer();
         pb.skipWhitespace();
         pb.skipChar(Symbols::SLASH[0]);
         pb.skipWhitespace();

         unsigned int numUrgentOld = pb.integer();
         pb.skipWhitespace();
         pb.skipChar(Symbols::RPAREN[0]);
         // skip LWS as specified in rfc3261
         skipSipLWS(pb);

         if (mHeaders[ht] != 0)
         {
            pb.fail(__FILE__, __LINE__);
         }
         mHeaders[ht] = new Header(numNew, numOld, numUrgentNew, numUrgentOld);
      }
      
      pb.skipChars(Symbols::CRLF);
   }

   if (!pb.eof() && *pb.position() == Symbols::CR[0])
   {
      pb.skipChars(Symbols::CRLF);
      
      while (!pb.eof())
      {
         anchor = pb.position();
         Data header;
         pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::COLON);
         pb.data(header, anchor);

         pb.skipWhitespace();
         pb.skipChar(Symbols::COLON[0]);
         anchor = pb.skipWhitespace();

         while (true)
         {
            // CodeWarrior isn't helpful enough to pick the "obvious" operator definition
            // so we add volatile here so CW is completely unconfused what to do.
            const volatile char* pos = pb.skipToChar(Symbols::CR[0]);
            skipSipLWS(pb);
            if (pb.position() == pos)
            {
               Data content;
               pb.data(content, anchor);
               mExtensions[header] = content;

               pb.skipChars(Symbols::CRLF);
               break;
            }
         }
      }
   }
}

Here is the call graph for this function:

void MessageWaitingContents::remove ( HeaderType  ht)

Remove the header correspoding to ht.

Parameters:
htHeaderType used to remove from MessageWaiting header

Definition at line 514 of file MessageWaitingContents.cxx.

References resip::LazyParser::checkParsed(), and mHeaders.

{
   checkParsed();
   delete mHeaders[ht];
   mHeaders[ht] = 0;
}

Here is the call graph for this function:

void MessageWaitingContents::remove ( const AccountHeader ht)

Remove the Uri for Message-Account line.

Parameters:
htAccountHeader used to lookup MessageWaiting header - not really used computationally

Definition at line 569 of file MessageWaitingContents.cxx.

References resip::LazyParser::checkParsed(), and mAccountUri.

{
   checkParsed();
   delete mAccountUri;
   mAccountUri = 0;
}

Here is the call graph for this function:

void MessageWaitingContents::remove ( const Data hn)

Remove the optional message header corresponding to hn.

Parameters:
hnHeaderType used to lookup the optional MessageWaiting header

Definition at line 613 of file MessageWaitingContents.cxx.

References resip::LazyParser::checkParsed(), and mExtensions.

{
   checkParsed();
   mExtensions.erase(hn);
}

Here is the call graph for this function:


Member Data Documentation

Definition at line 220 of file MessageWaitingContents.hxx.

Referenced by clear(), exists(), header(), operator=(), parse(), and remove().

Definition at line 222 of file MessageWaitingContents.hxx.

Referenced by encodeParsed(), exists(), header(), operator=(), parse(), and remove().

Definition at line 219 of file MessageWaitingContents.hxx.

Referenced by clear(), encodeParsed(), hasMessages(), operator=(), and parse().


The documentation for this class was generated from the following files: