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

📄 msgheaderscanner.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 3 页
字号:
processMsgHeaderStatusLine(   SipMessage *                       msg,   char *                             lineText,   unsigned int                       lineTextLength,   MsgHeaderScanner::TextPropBitMask  lineTextPropBitMask){   printf("status line: ");   printText(lineText, lineTextLength);   printf("\n");   return true;}staticvoidprocessMsgHeaderFieldNameAndValue(   SipMessage *                       msg,   int                                fieldKind,   const char *                       fieldName,   unsigned int                       fieldNameLength,   char *                             valueText,   unsigned int                       valueTextLength,   MsgHeaderScanner::TextPropBitMask  valueTextPropBitMask){   printText(fieldName, fieldNameLength);   printf(": [[[[");   printText(valueText, valueTextLength);   printf("]]]]\n");}#else //!defined(RESIP_MSG_HEADER_SCANNER_DEBUG) } {//   Determine a field's kind and whether it allows (comma separated) multi-values.//   "fieldName" is not empty and contains only legal characters.//   The text in "fieldName" may be canonicalized (eg, translating % escapes),//   including shrinking it if necessary.inline voidlookupMsgHeaderFieldInfo(char * fieldName,                         unsigned int *fieldNameLength,                            MsgHeaderScanner::TextPropBitMask fieldNameTextPropBitMask,                         int *fieldKind,                                      bool *isMultiValueAllowed)    {   //.jacob. Don't ignore fieldNameTextPropBitMask.   *fieldKind = Headers::getType(fieldName, *fieldNameLength);   *isMultiValueAllowed =      Headers::isCommaTokenizing(static_cast<Headers::Type>(*fieldKind));}// "lineText" contains no carriage returns and no line feeds.// Return true on success, false on failure.inline boolprocessMsgHeaderStatusLine(SipMessage * msg,                           char * lineText,                           unsigned int lineTextLength,                           MsgHeaderScanner::TextPropBitMask lineTextPropBitMask){   //.jacob. Don't ignore valueTextPropBitMask, and don't always return true.   msg->setStartLine(lineText, lineTextLength);   return true;}// This function is called once for a field with one value.  (The value could be// several values, but separated by something other than commas.)// This function is called once for a field with 0 comma-separated values, with// an empty value.// This function is called N times for a field with N comma-separated values,// but with the same value of "fieldName" each time.// "fieldName" is not empty and contains only legal characters.// "valueText" may be empty, has no leading whitespace, may contain trailing// whitespace, contains carriage returns and line feeds only in correct pairs// and followed by whitespace, and, if the field is multi-valued, contains// balanced '<'/'>' and '"' pairs, contains ',' only within '<'/'>' or '"'// pairs, and respects '\\'s within '"' pairs.// The text in "valueText" may be canonicalized (eg, translating % escapes),// including shrinking it if necessary.inline voidprocessMsgHeaderFieldNameAndValue(SipMessage * msg,                                  int fieldKind,                                  const char * fieldName,                                  unsigned int fieldNameLength,                                  char * valueText,                                  unsigned int valueTextLength,                                  MsgHeaderScanner::TextPropBitMask valueTextPropBitMask){   //.jacob. Don't ignore valueTextPropBitMask, particularly for '\r' & '\n'.   msg->addHeader(static_cast<Headers::Type>(fieldKind),                  fieldName,                  fieldNameLength,                  valueText,                  valueTextLength);}#endif //!defined(RESIP_MSG_HEADER_SCANNER_DEBUG) }bool MsgHeaderScanner::mInitialized = false;MsgHeaderScanner::MsgHeaderScanner(){   if (!mInitialized)   {      mInitialized = true;      initialize();   }}voidMsgHeaderScanner::prepareForMessage(SipMessage *  msg){   mMsg = msg;   mState = sMsgStart;   mPrevScanChunkNumSavedTextChars = 0;}voidMsgHeaderScanner::prepareForFrag(SipMessage *  msg, bool hasStartLine){   mMsg = msg;   if (hasStartLine)   {      mState = sMsgStart;   }   else   {      mState = sAfterLineBreakAfterStatusLine;   }   mPrevScanChunkNumSavedTextChars = 0;}MsgHeaderScanner::ScanChunkResultMsgHeaderScanner::scanChunk(char * chunk,                            unsigned int chunkLength,                            char ** unprocessedCharPtr){   MsgHeaderScanner::ScanChunkResult result;   CharInfo* localCharInfoArray = charInfoArray;   TransitionInfo (*localStateMachine)[numCharCategories] = stateMachine;   State localState = mState;   char *charPtr = chunk + mPrevScanChunkNumSavedTextChars;   char *termCharPtr = chunk + chunkLength;   char saveChunkTermChar = *termCharPtr;   *termCharPtr = chunkTermSentinelChar;   char *textStartCharPtr;   MsgHeaderScanner::TextPropBitMask localTextPropBitMask = mTextPropBitMask;   if (mPrevScanChunkNumSavedTextChars == 0)   {      textStartCharPtr = 0;   }   else   {      textStartCharPtr = chunk;   }   --charPtr;  // The loop starts by advancing "charPtr", so pre-adjust it.   for (;;)   {      // BEGIN message header character scan block BEGIN      // The code in this block is executed once per message header character.      // This entire file is designed specifically to minimize this block's size.      ++charPtr;      CharInfo *charInfo = &localCharInfoArray[((unsigned char) (*charPtr))];      CharCategory charCategory = charInfo->category;      localTextPropBitMask |= charInfo->textPropBitMask;     determineTransitionFromCharCategory:      TransitionInfo *transitionInfo =         &(localStateMachine[localState][(size_t)charCategory]);      TransitionAction transitionAction = transitionInfo->action;#if defined(RESIP_MSG_HEADER_SCANNER_DEBUG)        printStateTransition(localState, *charPtr, transitionAction);#endif      localState = transitionInfo->nextState;      if (transitionAction == taNone) continue;      // END message header character scan block END      // The loop remainder is executed about 4-5 times per message header line.      switch (transitionAction)      {         case taTermStatusLine:            if (!processMsgHeaderStatusLine(mMsg,                                            textStartCharPtr,                                            charPtr - textStartCharPtr,                                            localTextPropBitMask))            {               result = MsgHeaderScanner::scrError;               *unprocessedCharPtr = charPtr;               goto endOfFunction;            }            textStartCharPtr = 0;            break;         case taTermFieldName:         {            mFieldNameLength = charPtr - textStartCharPtr;            bool isMultiValueAllowed;            lookupMsgHeaderFieldInfo(textStartCharPtr,                                     &mFieldNameLength,                                     localTextPropBitMask,                                     &mFieldKind,                                     &isMultiValueAllowed);            mFieldName = textStartCharPtr;            textStartCharPtr = 0;            if (isMultiValueAllowed)             {               localState += deltaOfNStateFrom1State;            }         }         break;         case taBeyondEmptyValue:            processMsgHeaderFieldNameAndValue(mMsg,                                              mFieldKind,                                              mFieldName,                                              mFieldNameLength,                                              0,                                              0,                                              0);            goto performStartTextAction;         case taTermValueAfterLineBreak:            processMsgHeaderFieldNameAndValue(mMsg,                                              mFieldKind,                                              mFieldName,                                              mFieldNameLength,                                              textStartCharPtr,                                              (charPtr - textStartCharPtr) - 2,                                              localTextPropBitMask);       //^:CRLF            goto performStartTextAction;         case taTermValue:            processMsgHeaderFieldNameAndValue(mMsg,                                              mFieldKind,                                              mFieldName,                                              mFieldNameLength,                                              textStartCharPtr,                                              charPtr - textStartCharPtr,                                              localTextPropBitMask);            textStartCharPtr = 0;            break;         case taStartText:        performStartTextAction:            textStartCharPtr = charPtr;            localTextPropBitMask = 0;            break;         case taEndHeader:            // textStartCharPtr is not 0.  Not currently relevant.            result = MsgHeaderScanner::scrEnd;            *unprocessedCharPtr = charPtr + 1;  // The current char is processed.            goto endOfFunction;            break;         case taChunkTermSentinel:            if (charPtr == termCharPtr)            {               // The chunk has been consumed.  Save some state and request another.               mState = localState;               if (textStartCharPtr == 0)                {                  mPrevScanChunkNumSavedTextChars = 0;               }               else               {                  mPrevScanChunkNumSavedTextChars = termCharPtr - textStartCharPtr;               }               mTextPropBitMask = localTextPropBitMask;               result = MsgHeaderScanner::scrNextChunk;               *unprocessedCharPtr = termCharPtr - mPrevScanChunkNumSavedTextChars;               goto endOfFunction;            }            else            {               // The character is not the sentinel.  Treat it like any other.               charCategory = ccOther;               goto determineTransitionFromCharCategory;            }            break;         default:            result = MsgHeaderScanner::scrError;            *unprocessedCharPtr = charPtr;            goto endOfFunction;      }//switch   }//for  endOfFunction:   *termCharPtr = saveChunkTermChar;   return result;}boolMsgHeaderScanner::initialize(){   initCharInfoArray();   initStateMachine();   return true;}} //namespace resip#if defined(RESIP_MSG_HEADER_SCANNER_DEBUG) && defined(MSG_SCANNER_STANDALONE)externintmain(unsigned int   numArgs,     const char * * argVector){   ::resip::MsgHeaderScanner scanner;   scanner.prepareForMessage(0);   char *text =      "status\r\n"      "bobby: dummy\r\n"      "allow: foo, bar, \"don,\\\"xyz\r\n zy\", buzz\r\n\r\n";   unsigned int textLength = strlen(text);   char chunk[10000];   strcpy(chunk, text);   ::resip::MsgHeaderScanner::ScanChunkResult scanChunkResult;   char *unprocessedCharPtr;   scanChunkResult = scanner.scanChunk(chunk, 21, &unprocessedCharPtr);   if (scanChunkResult == ::resip::MsgHeaderScanner::scrNextChunk)   {      printf("Scanning another chunk '.");      ::resip::printText(unprocessedCharPtr, 1);      printf("'\n");      scanChunkResult =         scanner.scanChunk(unprocessedCharPtr,                           (chunk + textLength) - unprocessedCharPtr,                           &unprocessedCharPtr);   }   if (scanChunkResult != ::resip::MsgHeaderScanner::scrEnd)   {      printf("Error %d at character %d.\n",             scanChunkResult,             unprocessedCharPtr - chunk);   }   return 0;}#endif //!defined(RESIP_MSG_HEADER_SCANNER_DEBUG) }/* ==================================================================== * 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 + -