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

📄 msgheaderscanner.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 3 页
字号:
#if defined(HAVE_CONFIG_H)#include "resip/stack/config.hxx"#endif#include <ctype.h>#include <limits.h>#include <stdio.h>#include "resip/stack/HeaderTypes.hxx"#include "resip/stack/SipMessage.hxx"#include "resip/stack/MsgHeaderScanner.hxx"#include "rutil/WinLeakCheck.hxx"namespace resip {/////////////////////////////////////////////////////////////////////////////////   Any character could be used as the chunk terminating sentinel, as long as//   it would otherwise be character category "other".  The null character//   was chosen because it is unlikely to occur naturally -- but it's OK if it//   does.enum { chunkTermSentinelChar = '\0' };enum CharCategoryEnum{   ccChunkTermSentinel,   ccOther,   ccFieldName,   ccWhitespace,   ccColon,   ccDoubleQuotationMark,   ccLeftAngleBracket,   ccRightAngleBracket,   ccBackslash,   ccComma,   ccCarriageReturn,   ccLineFeed,   numCharCategories};typedef char CharCategory;char* MsgHeaderScanner::allocateBuffer(int size){   return new char[size + MaxNumCharsChunkOverflow];}struct CharInfo{      CharCategory category;      MsgHeaderScanner::TextPropBitMask textPropBitMask;};    static CharInfo charInfoArray[UCHAR_MAX+1];    static inline int c2i(unsigned char c){   return static_cast<int>(c); }static void initCharInfoArray(){   for(unsigned int charIndex = 0; charIndex <= UCHAR_MAX; ++charIndex)    {      charInfoArray[charIndex].category = ccOther;      charInfoArray[charIndex].textPropBitMask = 0;   }   for(const char *charPtr = "abcdefghijklmnopqrstuvwxyz"          "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.!%*_+`'~";       *charPtr;       ++charPtr)   {      charInfoArray[c2i(*charPtr)].category = ccFieldName;   }   charInfoArray[c2i(' ')].category  = ccWhitespace;   charInfoArray[c2i('\t')].category = ccWhitespace;   charInfoArray[c2i(':')].category  = ccColon;   charInfoArray[c2i('"')].category  = ccDoubleQuotationMark;   charInfoArray[c2i('<')].category  = ccLeftAngleBracket;   charInfoArray[c2i('>')].category  = ccRightAngleBracket;   charInfoArray[c2i('\\')].category  = ccBackslash;   charInfoArray[c2i(',')].category  = ccComma;   charInfoArray[c2i('\r')].category = ccCarriageReturn;   charInfoArray[c2i('\n')].category = ccLineFeed;   // Assert: "chunkTermSentinelChar"'s category is still the default "ccOther".   charInfoArray[c2i(chunkTermSentinelChar)].category = ccChunkTermSentinel;   // Init text property bit masks.   charInfoArray[c2i('\r')].textPropBitMask =      MsgHeaderScanner::tpbmContainsLineBreak;   charInfoArray[c2i('\n')].textPropBitMask =      MsgHeaderScanner::tpbmContainsLineBreak;   charInfoArray[c2i(' ')].textPropBitMask =      MsgHeaderScanner::tpbmContainsWhitespace;   charInfoArray[c2i('\t')].textPropBitMask =      MsgHeaderScanner::tpbmContainsWhitespace;   charInfoArray[c2i('\\')].textPropBitMask =      MsgHeaderScanner::tpbmContainsBackslash;   charInfoArray[c2i('%')].textPropBitMask =      MsgHeaderScanner::tpbmContainsPercent;   charInfoArray[c2i(';')].textPropBitMask =      MsgHeaderScanner::tpbmContainsSemicolon;   charInfoArray[c2i('(')].textPropBitMask =      MsgHeaderScanner::tpbmContainsParen;   charInfoArray[c2i(')')].textPropBitMask =      MsgHeaderScanner::tpbmContainsParen;}/////////////////////////////////////////////////////////////////////////////////   States marked '1' scan normal values.  States marked 'N' scan multi-values.enum StateEnum{   sMsgStart,   sHalfLineBreakAtMsgStart,   sScanStatusLine,   sHalfLineBreakAfterStatusLine,   sAfterLineBreakAfterStatusLine,   sScanFieldName,   sScanWhitespaceAfter1FieldName,   sScanWhitespaceAfterNFieldName,   sScanWhitespaceOr1Value,   sScanWhitespaceOrNValue,   sHalfLineBreakInWhitespaceBefore1Value,   sHalfLineBreakInWhitespaceBeforeNValue,   sAfterLineBreakInWhitespaceBefore1Value,   sAfterLineBreakInWhitespaceBeforeNValue,   sScan1Value,   sScanNValue,   sHalfLineBreakIn1Value,   sHalfLineBreakInNValue,   sAfterLineBreakIn1Value,   sAfterLineBreakInNValue,   sScanNValueInQuotes,   sAfterEscCharInQuotesInNValue,   sHalfLineBreakInQuotesInNValue,   sAfterLineBreakInQuotesInNValue,   sScanNValueInAngles,   sHalfLineBreakInAnglesInNValue,   sAfterLineBreakInAnglesInNValue,   sHalfLineBreakAfterLineBreak,   numStates};typedef char State;// For each '1' state, the 'N' state is "deltaOfNStateFrom1State" larger.enum { deltaOfNStateFrom1State = 1 };/////    enum TransitionActionEnum {   taNone,   taTermStatusLine,       // The current character terminates the status   //     line.   taTermFieldName,        // The current character terminates a field name.   //     If the field supports multi-values, shift   //     the state machine into multi-value scanning.   taBeyondEmptyValue,     // The current character terminates an empty value.   //     Implies taStartText.   taTermValueAfterLineBreak,    // The previous two characters are a linebreak   //      terminating a value.  Implies taStartText.   taTermValue,            // The current character terminates a value.   taStartText,            // The current character starts a text unit.   //     (The status line, a field name, or a value.)   taEndHeader,            // The current character mEnds_ the header.   taChunkTermSentinel,    // Either the current character terminates the   //    current chunk or it is an ordinary character.   taError                 // The input is erroneous.};typedef char TransitionAction;struct TransitionInfo{      TransitionAction  action;      State             nextState;};static TransitionInfo stateMachine[numStates][numCharCategories];inline void specTransition(State state,                           CharCategory charCategory,                           TransitionAction action,                           State nextState){   stateMachine[c2i(state)][c2i(charCategory)].action = action;   stateMachine[c2i(state)][c2i(charCategory)].nextState = nextState;}static void specDefaultTransition(State state,                                  TransitionAction action,                                  State nextState){   for (int charCategory = 0;        charCategory < numCharCategories;        ++charCategory)    {      specTransition(state, charCategory, action, nextState);   }   specTransition(state, ccCarriageReturn, taError, state);   specTransition(state, ccLineFeed, taError, state);   specTransition(state, ccChunkTermSentinel, taChunkTermSentinel, state);}static void specHalfLineBreakState(State halfLineBreakState,                                   State  afterLineBreakState){   specDefaultTransition(halfLineBreakState, taError, halfLineBreakState);   specTransition(halfLineBreakState, ccLineFeed, taNone, afterLineBreakState);}//   Single-value (1) scanning and multi-value (N) scanning involves several nearly//   identical states.//   "stateDelta" is either 0 or "deltaOfNStateFrom1State".static void specXValueStates(int  stateDelta){   specDefaultTransition(sScanWhitespaceAfter1FieldName + stateDelta,                         taError,                         sScanWhitespaceAfter1FieldName + stateDelta);   specTransition(sScanWhitespaceAfter1FieldName + stateDelta,                  ccWhitespace,                  taNone,                  sScanWhitespaceAfter1FieldName + stateDelta);   specTransition(sScanWhitespaceAfter1FieldName + stateDelta,                  ccColon,                  taNone,                  sScanWhitespaceOr1Value + stateDelta);   specDefaultTransition(sScanWhitespaceOr1Value + stateDelta,                         taStartText,                         sScan1Value + stateDelta);   specTransition(sScanWhitespaceOr1Value + stateDelta,                  ccWhitespace,                  taNone,                  sScanWhitespaceOr1Value + stateDelta);   if (stateDelta == deltaOfNStateFrom1State)   {      specTransition(sScanWhitespaceOr1Value + stateDelta,                     ccComma,                     taError,                     sScanWhitespaceOr1Value + stateDelta);      specTransition(sScanWhitespaceOr1Value + stateDelta,                     ccLeftAngleBracket,                     taStartText,                     sScanNValueInAngles);      specTransition(sScanWhitespaceOr1Value + stateDelta,                     ccDoubleQuotationMark,                     taStartText,                     sScanNValueInQuotes);   }   specTransition(sScanWhitespaceOr1Value + stateDelta,                  ccCarriageReturn,                  taNone,                  sHalfLineBreakInWhitespaceBefore1Value + stateDelta);   specHalfLineBreakState(sHalfLineBreakInWhitespaceBefore1Value + stateDelta,                          sAfterLineBreakInWhitespaceBefore1Value + stateDelta);   specDefaultTransition(sAfterLineBreakInWhitespaceBefore1Value + stateDelta,                         taError,                         sAfterLineBreakInWhitespaceBefore1Value + stateDelta);   specTransition(sAfterLineBreakInWhitespaceBefore1Value + stateDelta,                  ccFieldName,                  taBeyondEmptyValue,                  sScanFieldName);   specTransition(sAfterLineBreakInWhitespaceBefore1Value + stateDelta,                  ccWhitespace,                  taNone,                  sScanWhitespaceOr1Value + stateDelta);   specTransition(sAfterLineBreakInWhitespaceBefore1Value + stateDelta,                  ccCarriageReturn,                  taBeyondEmptyValue,                  sHalfLineBreakAfterLineBreak);   specDefaultTransition(sScan1Value + stateDelta,                         taNone,                         sScan1Value + stateDelta);   if (stateDelta == deltaOfNStateFrom1State)   {      specTransition(sScan1Value + stateDelta,                     ccComma,                     taTermValue,                     sScanWhitespaceOr1Value + stateDelta);      specTransition(sScan1Value + stateDelta,                     ccLeftAngleBracket,                     taNone,                     sScanNValueInAngles);      specTransition(sScan1Value + stateDelta,                     ccDoubleQuotationMark,                     taNone,                     sScanNValueInQuotes);   }   specTransition(sScan1Value + stateDelta,                  ccCarriageReturn,                  taNone,                  sHalfLineBreakIn1Value + stateDelta);   specHalfLineBreakState(sHalfLineBreakIn1Value + stateDelta,                          sAfterLineBreakIn1Value + stateDelta);   specDefaultTransition(sAfterLineBreakIn1Value + stateDelta,                         taError,                         sAfterLineBreakIn1Value + stateDelta);   specTransition(sAfterLineBreakIn1Value + stateDelta,                  ccFieldName,                  taTermValueAfterLineBreak,                  sScanFieldName);   specTransition(sAfterLineBreakIn1Value + stateDelta,                  ccWhitespace,                  taNone,                  sScan1Value + stateDelta);   specTransition(sAfterLineBreakIn1Value + stateDelta,                  ccCarriageReturn,                  taTermValueAfterLineBreak,                  sHalfLineBreakAfterLineBreak);}static void initStateMachine(){   // By convention, error transitions maintain the same state.   specDefaultTransition(sMsgStart, taStartText, sScanStatusLine);   specTransition(sMsgStart,                  ccCarriageReturn,                  taNone,                  sHalfLineBreakAtMsgStart);   specTransition(sMsgStart, ccLineFeed, taError, sMsgStart);   specHalfLineBreakState(sHalfLineBreakAtMsgStart, sMsgStart);   specDefaultTransition(sScanStatusLine, taNone, sScanStatusLine);   specTransition(sScanStatusLine,                  ccCarriageReturn,                  taTermStatusLine,                  sHalfLineBreakAfterStatusLine);   specHalfLineBreakState(sHalfLineBreakAfterStatusLine,                          sAfterLineBreakAfterStatusLine);   specDefaultTransition(sAfterLineBreakAfterStatusLine,                         taError,                         sAfterLineBreakAfterStatusLine);   specTransition(sAfterLineBreakAfterStatusLine,                  ccFieldName,                  taStartText,                  sScanFieldName);   specTransition(sAfterLineBreakAfterStatusLine,                  ccWhitespace,                  taError,                  sAfterLineBreakAfterStatusLine);   specTransition(sAfterLineBreakAfterStatusLine,                  ccCarriageReturn,                  taNone,                  sHalfLineBreakAfterLineBreak);   specDefaultTransition(sScanFieldName, taError, sScanFieldName);   specTransition(sScanFieldName, ccFieldName, taNone, sScanFieldName);   specTransition(sScanFieldName,                  ccWhitespace,                  taTermFieldName,                  sScanWhitespaceAfter1FieldName);   specTransition(sScanFieldName,                  ccColon,                  taTermFieldName,                  sScanWhitespaceOr1Value);   specXValueStates(0);   specXValueStates(deltaOfNStateFrom1State);   specDefaultTransition(sScanNValueInQuotes, taNone, sScanNValueInQuotes);   specTransition(sScanNValueInQuotes,                  ccDoubleQuotationMark,                  taNone,                  sScanNValue);   specTransition(sScanNValueInQuotes,                  ccBackslash,                  taNone,                  sAfterEscCharInQuotesInNValue);   specTransition(sScanNValueInQuotes,                  ccCarriageReturn,                  taNone,                  sHalfLineBreakInQuotesInNValue);   specDefaultTransition(sAfterEscCharInQuotesInNValue,                         taNone,                         sScanNValueInQuotes);   specHalfLineBreakState(sHalfLineBreakInQuotesInNValue,                          sAfterLineBreakInQuotesInNValue);   specDefaultTransition(sAfterLineBreakInQuotesInNValue,                         taError,                         sAfterLineBreakInQuotesInNValue);   specTransition(sAfterLineBreakInQuotesInNValue,                  ccWhitespace,                  taNone,                  sScanNValueInQuotes);   specDefaultTransition(sScanNValueInAngles, taNone, sScanNValueInAngles);   specTransition(sScanNValueInAngles,                  ccRightAngleBracket,

⌨️ 快捷键说明

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