⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 contents.cxx

📁 一个著名的SIP协议栈
💻 CXX
字号:
#include <vector>

#if defined(HAVE_CONFIG_H)
#include "resip/stack/config.hxx"
#endif

#include "resip/stack/Contents.hxx"
#include "rutil/ParseBuffer.hxx"
#include "rutil/Logger.hxx"
#include "resip/stack/OctetContents.hxx"
#include "rutil/WinLeakCheck.hxx"

using namespace resip;
using namespace std;

#define RESIPROCATE_SUBSYSTEM Subsystem::CONTENTS

H_ContentID resip::h_ContentID;
H_ContentDescription resip::h_ContentDescription;

Contents::Contents(HeaderFieldValue* headerFieldValue,
                   const Mime& contentType) 
   : LazyParser(headerFieldValue),
      mType(contentType)
{
   init();
}

Contents::Contents(const Mime& contentType) 
   : mType(contentType)
{
   init();
}

Contents::Contents(const Contents& rhs) 
    : LazyParser(rhs)
{
   init(rhs);
}

Contents::Contents(const Contents& rhs,HeaderFieldValue::CopyPaddingEnum e) 
    : LazyParser(rhs,e)
{
   init(rhs);
}

Contents::~Contents()
{
   freeMem();
}

const Data&
Contents::errorContext() const
{
   static const Data context("Contents");
   return context;
}

Contents& 
Contents::operator=(const Contents& rhs) 
{
   if (this != &rhs)
   {
      freeMem();
      LazyParser::operator=(rhs);
      init(rhs);
   }

   return *this;
}

void
Contents::init(const Contents& orig)
{
   mBufferList.clear();
   mType = orig.mType;
   if (orig.mDisposition)
   {
       mDisposition = new H_ContentDisposition::Type(*orig.mDisposition);
   }
   else
   {
      mDisposition = 0;
   }
   
   if (orig.mTransferEncoding)
   {
       mTransferEncoding = new H_ContentTransferEncoding::Type(*orig.mTransferEncoding);
   }
   else
   {
      mTransferEncoding = 0;
   }
   
   if (orig.mLanguages)
   {
       mLanguages = new H_ContentLanguages::Type(*orig.mLanguages);
   }
   else
   {
      mLanguages = 0;
   }
   
   if (orig.mId)
   {
       mId = new Token(*orig.mId);
   }
   else
   {
      mId = 0;
   }
   
   if (orig.mDescription)
   {
       mDescription = new StringCategory(*orig.mDescription);
   }
   else
   {
      mDescription = 0;
   }
   
   if(orig.mLength)
   {
      mLength = new StringCategory(*orig.mLength);
   }
   else
   {
      mLength = 0;
   }

   mVersion = orig.mVersion;
   mMinorVersion = orig.mMinorVersion;

}

Contents*
Contents::createContents(const Mime& contentType, 
                         const Data& contents)
{
  // !ass! why are we asserting that the Data doesn't own the buffer?
  // .dlb. because this method is to be called only within a multipart
  // !ass! HFV is an overlay -- then setting c->mIsMine to true ?? dlb Q
  // .dlb. we are telling the content that it owns its HFV, not the data that it
  // .dlb. owns its memory

   assert(!contents.mMine);
   HeaderFieldValue *hfv = new HeaderFieldValue(contents.data(), contents.size());

   if(contentType.subType()=="sipfrag"||contentType.subType()=="external-body")
   {
      // !bwc! The parser for sipfrag requires padding at the end of the hfv.
      HeaderFieldValue* temp = hfv;
      hfv = new HeaderFieldValue(*temp,HeaderFieldValue::CopyPadding);
      delete temp;
   }
   
   Contents* c;
   if (ContentsFactoryBase::getFactoryMap().find(contentType) != ContentsFactoryBase::getFactoryMap().end())
   {
      c = ContentsFactoryBase::getFactoryMap()[contentType]->create(hfv, contentType);
   }
   else
   {
      c = new OctetContents(hfv, contentType);
   }
   c->mIsMine = true;
   return c;
}

bool
Contents::exists(const HeaderBase& headerType) const
{
   checkParsed();
   switch (headerType.getTypeNum())
   {
      case Headers::ContentType :
      {
         return true;
      }
      case Headers::ContentDisposition :
      {
         return mDisposition != 0;
      }
      case Headers::ContentTransferEncoding :
      {
         return mTransferEncoding != 0;
      }
      case Headers::ContentLanguage :
      {
         return mLanguages != 0;
      }
      default : return false;
   }
}

bool
Contents::exists(const MIME_Header& type) const
{
   if (&type == &h_ContentID)
   {
      return mId != 0;
   }
   
   if (&type == &h_ContentDescription)
   {
      return mDescription != 0;
   }

   assert(false);
   return false;
}

void
Contents::remove(const HeaderBase& headerType)
{
   switch (headerType.getTypeNum())
   {
      case Headers::ContentDisposition :
      {
         delete mDisposition;
         mDisposition = 0;
         break;
      }
      case Headers::ContentLanguage :
      {
         delete mLanguages;
         mLanguages = 0;
         break;
      }
      case Headers::ContentTransferEncoding :
      {
         delete mTransferEncoding;
         mTransferEncoding = 0;
         break;
      }
      default :
         ;
   }
}

void
Contents::remove(const MIME_Header& type)
{
   if (&type == &h_ContentID)
   {
      delete mId;
      mId = 0;
      return;
   }
    
   if (&type == &h_ContentDescription)
   {
      delete mDescription;
      mDescription = 0;
      return;
   }

   assert(false);
}

H_ContentType::Type&
Contents::header(const H_ContentType& headerType) const
{
   return mType;
}

H_ContentDisposition::Type&
Contents::header(const H_ContentDisposition& headerType) const
{
   checkParsed();
   if (mDisposition == 0)
   {
      mDisposition = new H_ContentDisposition::Type;
   }
   return *mDisposition;
}

H_ContentTransferEncoding::Type&
Contents::header(const H_ContentTransferEncoding& headerType) const
{
   checkParsed();
   if (mTransferEncoding == 0)
   {
      mTransferEncoding = new H_ContentTransferEncoding::Type;
   }
   return *mTransferEncoding;
}

H_ContentLanguages::Type&
Contents::header(const H_ContentLanguages& headerType) const 
{
   checkParsed();
   if (mLanguages == 0)
   {
      mLanguages = new H_ContentLanguages::Type;
   }
   return *mLanguages;
}

H_ContentDescription::Type&
Contents::header(const H_ContentDescription& headerType) const
{
   checkParsed();
   if (mDescription == 0)
   {
      mDescription = new H_ContentDescription::Type;
   }
   return *mDescription;
}

H_ContentID::Type&
Contents::header(const H_ContentID& headerType) const
{
   checkParsed();
   if (mId == 0)
   {
      mId = new H_ContentID::Type;
   }
   return *mId;
}

// !dlb! headers except Content-Disposition may contain (comments)
void
Contents::preParseHeaders(ParseBuffer& pb)
{
   const char* start = pb.position();
   Data all( start, pb.end()-start);

   Data headerName;

   try
   {
      
   while (!pb.eof())
   {
      const char* anchor = pb.skipWhitespace();
      pb.skipToOneOf(Symbols::COLON, ParseBuffer::Whitespace);
      pb.data(headerName, anchor);

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

      Headers::Type type = Headers::getType(headerName.data(), headerName.size());
      ParseBuffer subPb(anchor, pb.position() - anchor);

      switch (type)
      {
         case Headers::ContentType :
         {
            // already set
            break;
         }
         case Headers::ContentDisposition :
         {
            mDisposition = new H_ContentDisposition::Type;
            mDisposition->parse(subPb);
            break;
         }
         case Headers::ContentTransferEncoding :
         {
            mTransferEncoding = new H_ContentTransferEncoding::Type;
            mTransferEncoding->parse(subPb);
            break;
         }
         // !dlb! not sure this ever happens?
         case Headers::ContentLanguage :
         {
            if (mLanguages == 0)
            {
               mLanguages = new H_ContentLanguages::Type;
            }

            subPb.skipWhitespace();
            while (!subPb.eof() && *subPb.position() != Symbols::COMMA[0])
            {
               H_ContentLanguages::Type::value_type tmp;
               header(h_ContentLanguages).push_back(tmp);
               header(h_ContentLanguages).back().parse(subPb);
               subPb.skipLWS();
            }
         }
         default :
         {
            if (isEqualNoCase(headerName, "Content-Transfer-Encoding"))
            {
               mTransferEncoding = new StringCategory();
               mTransferEncoding->parse(subPb);
            }
            else if (isEqualNoCase(headerName, "Content-Description"))
            {
               mDescription = new StringCategory();
               mDescription->parse(subPb);
            }
            else if (isEqualNoCase(headerName, "Content-Id"))
            {
               mId = new Token();
               mId->parse(subPb);
            }
            // Some people put this in ...
            else if (isEqualNoCase(headerName, "Content-Length"))
            {
               mLength = new StringCategory();
               mLength->parse(subPb);
            }
            else if (isEqualNoCase(headerName, "MIME-Version"))
            {
               subPb.skipWhitespace();
               if (!subPb.eof() && *subPb.position() == Symbols::LPAREN[0])
               {
                  subPb.skipToEndQuote(Symbols::RPAREN[0]);
                  subPb.skipChar(Symbols::RPAREN[0]);
               }
               mVersion = subPb.integer();

               if (!subPb.eof() && *subPb.position() == Symbols::LPAREN[0])
               {
                  subPb.skipToEndQuote(Symbols::RPAREN[0]);
                  subPb.skipChar(Symbols::RPAREN[0]);
               }
               subPb.skipChar(Symbols::PERIOD[0]);
               
               if (!subPb.eof() && *subPb.position() == Symbols::LPAREN[0])
               {
                  subPb.skipToEndQuote(Symbols::RPAREN[0]);
                  subPb.skipChar(Symbols::RPAREN[0]);
               }
               
               mMinorVersion = subPb.integer();
            }
            else
            {
               // add to application headers someday
               std::cerr << "Unknown MIME Content- header: " << headerName << std::endl;
               ErrLog(<< "Unknown MIME Content- header: " << headerName);
               assert(false);
            }
         }
      }
   }
   }
   catch (ParseBuffer::Exception & /* e */)
   {
      ErrLog( << "Some problem parsing contents" );
#if 0 // TODO CJ REMOVE this if 0 and make this throw
      throw;
#endif
   }
}

std::ostream&
Contents::encodeHeaders(std::ostream& str) const
{
   if (mVersion != 1 || mMinorVersion != 0)
   {
      str << "MIME-Version" << Symbols::COLON[0] << Symbols::SPACE[0]
          << mVersion << Symbols::PERIOD[0] << mMinorVersion 
          << Symbols::CRLF;
   }

   str << "Content-Type" << Symbols::COLON[0] << Symbols::SPACE[0]
       << mType 
       << Symbols::CRLF;

   if (exists(h_ContentDisposition))
   {
      str <<  "Content-Disposition" << Symbols::COLON[0] << Symbols::SPACE[0];

      header(h_ContentDisposition).encode(str);
      str << Symbols::CRLF;
   }

   if (exists(h_ContentLanguages))
   {
      str <<  "Content-Languages" << Symbols::COLON[0] << Symbols::SPACE[0];

      int count = 0;
      int size = header(h_ContentLanguages).size();

      for (H_ContentLanguages::Type::iterator 
              i = header(h_ContentLanguages).begin();
           i != header(h_ContentLanguages).end(); ++i)
      {
         i->encode(str);

         if (++count < size)
             str << Symbols::COMMA << Symbols::SPACE;
      }
      str << Symbols::CRLF;
   }

   if (mTransferEncoding)
   {
      str << "Content-Transfer-Encoding" << Symbols::COLON[0] << Symbols::SPACE[0]
          << *mTransferEncoding
          << Symbols::CRLF;
   }

   if (mId)
   {
      str << "Content-Id" << Symbols::COLON[0] << Symbols::SPACE[0]
          << *mId
          << Symbols::CRLF;
   }

   if (mDescription)
   {
      str << "Content-Description" << Symbols::COLON[0] << Symbols::SPACE[0]
          << *mDescription
          << Symbols::CRLF;
   }

   if (mLength)
   {
      str << "Content-Length" << Symbols::COLON[0] << Symbols::SPACE[0]
          <<  *mLength 
          << Symbols::CRLF;
   }
   
   str << Symbols::CRLF;
   return str;
}

Data
Contents::getBodyData() const 
{
   ErrLog( << "Need to implement getBodyData function for " << getType() );
   assert(0);
   return Data::Empty;
}

void
Contents::addBuffer(char* buf)
{
   mBufferList.push_back(buf);
}

/* ====================================================================
 * The Vovida Software License, Version 1.0 
 * 
 * Copyright (c) 2000-2005
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 
 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
 *    and "Vovida Open Communication Application Library (VOCAL)" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact vocal@vovida.org.
 *
 * 4. Products derived from this software may not be called "VOCAL", nor
 *    may "VOCAL" appear in their name, without prior written
 *    permission of Vovida Networks, Inc.
 * 
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 * 
 * ====================================================================
 * 
 * This software consists of voluntary contributions made by Vovida
 * Networks, Inc. and many individuals on behalf of Vovida Networks,
 * Inc.  For more information on Vovida Networks, Inc., please see
 * <http://www.vovida.org/>.
 *
 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -