📄 sipparser.cxx
字号:
/********************************************************************* $Id: SIPParser.cxx,v 1.3 1999/08/31 02:22:05 cullen Exp $ ********************************************************************* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. In addition to the terms and conditions set forth in the GNU Lesser General Public License, as a condition of using this library you are required to grant to all users of this library or any implementation utilizing or derived from this library a reciprocal, no cost, worldwide, perpetual, non-exclusive, non-transferable, unrestricted license to your claims of all patents and patent applications throughout the world that are infringed by the library or any implementation utilizing or derived from this library. In the event you redistribute this library or any implementation utilizing or derived from this library, you must prominently display the foregoing terms and conditions with the library or the implementation utilizing or derived from this library. In the event of a conflict of terms between the foregoing license grant and the terms set forth in the GNU Lesser General Public License, the foregoing terms and conditions shall be deemed to govern. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not; write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. Copyright 1999 Vovida Networks, Inc. All Rights Reserved. ********************************************************************* $Log: SIPParser.cxx,v $ Revision 1.3 1999/08/31 02:22:05 cullen updated header **********************************************************************/#include <string>#include <vector>#include <stdio.h>#include "mstring.h"#include "MpCommon.h"#include "MpError.h"#include "MpItems.h"#include "SIPParser.h"namespace msip{ static const char null_pointer_detected[] = "MsgParser: Null pointer detected"; //--------------------------------------------------------------------------------------- std::mstring MsgParser::detectLineSep(const std::mstring & str) { std::mstring sep; std::string::size_type pos = str.find_first_of("\r\n"); if(pos == std::string::npos) return sep; char sep1 = str[pos]; char sep2 = 0; if(pos < str.length() - 1) { char c = str[pos + 1]; if((c == '\n' || c == '\r') && c != sep1) { sep2 = c; } } sep += sep1; if(sep2) sep += sep2; return sep; } //--------------------------------------------------------------------------------------- std::mstring MsgParser::findHeader(const std::mstring & str, const std::mstring & name, const std::mstring & separator) { std::mstr_vector names; name.split(&names, "|", ""); std::mstr_vector::iterator it; std::mstring ret; for(it = names.begin(); it != names.end(); ++it) { *it += ':'; } std::string::size_type start = 0; std::mstring tmp; while((start = str.token(&tmp, start, separator, QuoteSymb, QPairSymb, std::mstring::sep_whole_str)) != std::string::npos) { for(it = names.begin(); it != names.end(); ++it) { if(tmp.comparei(*it, it->length()) == 0) { //found ret.assign(tmp, it->length(), tmp.length() - it->length()); return ret.atrim(); } } } return ret; } //--------------------------------------------------------------------------------------- std::string::size_type MsgParser::findMessageEnd(const std::mstring & str) { //Detect line separator, It may be "\n" or "\r" or "\r\n" or "\n\r" std::mstring sep = detectLineSep(str); if(str.empty()) return std::string::npos; std::mstring dbl_sep; dbl_sep = sep + sep; //Check, if headers part is complete - there must be a double separator. std::string::size_type dbl_sep_pos = str.find(dbl_sep); if(dbl_sep_pos == std::string::npos) return std::string::npos; if(dbl_sep_pos == 0) return dbl_sep.length(); //Find the Content-Length header std::mstring cont = findHeader(str, hdrnContentLength, sep); //Calculate total expected length std::string::size_type exp_len = dbl_sep_pos + dbl_sep.length() + atoi(cont.c_str()); //Check if the length is not less than expected one if(str.length() < exp_len) exp_len = std::string::npos; return exp_len; } //--------------------------------------------------------------------------------------- MsgParser::~MsgParser() { HdrArray::iterator it = mp_HdrArray.begin(); for(; it != mp_HdrArray.end(); ++it) { if(*it) delete *it; } ContentArray::iterator itc = mp_Content.begin(); for(; itc != mp_Content.end(); ++itc) { if(itc->m_type) delete itc->m_type; } } //--------------------------------------------------------------------------------------- void MsgParser::erase() { HdrArray::iterator it = mp_HdrArray.begin(); for(; it != mp_HdrArray.end(); ++it) { MpHeader * p_hdr = *it; if(p_hdr == 0) { throw MpAccessError(null_pointer_detected); } delete p_hdr; } mp_HdrArray.clear(); mp_StartLine.erase(); setLineSep("\r\n"); ContentArray::iterator itc = mp_Content.begin(); for(; itc != mp_Content.end(); ++itc) { if(itc->m_type) delete itc->m_type; } mp_Content.clear(); } //--------------------------------------------------------------------------------------- MpHeader & MsgParser::header(const char * name, unsigned index) { MpHeader *p_hdr = find(name, index); if(p_hdr == 0) { p_hdr = &insertHeader(name, index + 1); } return *p_hdr; } //--------------------------------------------------------------------------------------- MpHeader & MsgParser::operator [] (unsigned index) { if(index >= mp_HdrArray.size()) { throw MpAccessError("MsgParser: Out of index"); } if(mp_HdrArray[index] == 0) { throw MpAccessError(null_pointer_detected); } return *mp_HdrArray[index]; } //--------------------------------------------------------------------------------------- MpHeader & MsgParser::insertHeader(const char * name, unsigned index) { unsigned count = 0; MpHeader *last_found = 0; HdrArray::iterator it = mp_HdrArray.begin(); for(; it != mp_HdrArray.end(); ++it) { MpHeader * p_hdr = *it; if(p_hdr == 0) { throw MpAccessError(null_pointer_detected); } if(p_hdr->isHeader(name)) { last_found = p_hdr; if(count >= index) { break; } count++; } else { if(last_found) break; } } //Check, if multiple header is allowed if(last_found) { if(!last_found->is_multiple_hdr()) { throw MpAccessError(std::string("MsgParser: Only one header '") + last_found->encodeHeaderName() + "' allowed"); } } MpHeader * p_hdr = MpHeader::headerFactory(name); if(p_hdr == 0) { throw MpAccessError("MsgParser: Header creation error"); } return **mp_HdrArray.insert(it, p_hdr); } //--------------------------------------------------------------------------------------- void MsgParser::addHeader(const pMpHeader p_hdr) { if(p_hdr) { mp_HdrArray.push_back(p_hdr); } } //--------------------------------------------------------------------------------------- //!!!Can be implemented more efficiently with 'std::map<name, count>' unsigned MsgParser::count(const char * name) const { if(name == 0) return mp_HdrArray.size(); unsigned count = 0; HdrArray::const_iterator it; for(it = mp_HdrArray.begin(); it != mp_HdrArray.end(); ++it) { MpHeader * p_hdr = *it; if(p_hdr == 0) { throw MpAccessError(null_pointer_detected); } if(p_hdr->isHeader(name)) { count++; } } return count; } //--------------------------------------------------------------------------------------- MpHeader * MsgParser::find(const char * name, unsigned index) { unsigned count = 0; HdrArray::const_iterator it; for(it = mp_HdrArray.begin(); it != mp_HdrArray.end(); ++it) { MpHeader * p_hdr = *it; if(p_hdr == 0) { throw MpAccessError(null_pointer_detected); } if(p_hdr->isHeader(name)) { if(count >= index) { return p_hdr; } count++; } } return 0; } //--------------------------------------------------------------------------------------- MsgParser & MsgParser::operator = (const MsgParser &mp) { if(this == &mp) return *this; erase(); mp_StartLine.decode(mp.mp_StartLine.encode(false), false); HdrArray::const_iterator it; for(it = mp.mp_HdrArray.begin(); it != mp.mp_HdrArray.end(); ++it) { MpHeader * p_hdr = (*it)->clone(); if(p_hdr) { p_hdr->decode((*it)->encode(false), false); addHeader(p_hdr); } } unsigned i; for(i = 0; i < mp.countContents(); i++) { contentType(i).decode(mp.contentType(i).encode(false), false); setContent(mp.getContent(i), i); } return *this; } //--------------------------------------------------------------------------------------- void MsgParser::dump(std::mstring * str) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -