reSIProcate/stack  9694
Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes
resip::MsgHeaderScanner Class Reference

#include <MsgHeaderScanner.hxx>

Collaboration diagram for resip::MsgHeaderScanner:
Collaboration graph
[legend]

List of all members.

Public Types

enum  { MaxNumCharsChunkOverflow = 5 }
enum  TextPropBitMaskEnum {
  tpbmContainsLineBreak = 1 << 0, tpbmContainsWhitespace = 1 << 1, tpbmContainsBackslash = 1 << 2, tpbmContainsPercent = 1 << 3,
  tpbmContainsSemicolon = 1 << 4, tpbmContainsParen = 1 << 5
}
enum  ScanChunkResult { scrEnd, scrNextChunk, scrError }
typedef unsigned char TextPropBitMask

Public Member Functions

unsigned int getHeaderCount () const
 MsgHeaderScanner ()
void prepareForMessage (SipMessage *msg)
void prepareForFrag (SipMessage *msg, bool hasStartLine)
MsgHeaderScanner::ScanChunkResult scanChunk (char *chunk, unsigned int chunkLength, char **unprocessedCharPtr)

Static Public Member Functions

static char * allocateBuffer (int size)
static int dumpStateMachine (int fd)

Private Member Functions

 MsgHeaderScanner (const MsgHeaderScanner &from)
MsgHeaderScanneroperator= (const MsgHeaderScanner &from)
bool initialize ()

Private Attributes

SipMessagemMsg
unsigned int mNumHeaders
int mState
int mPrevScanChunkNumSavedTextChars
MsgHeaderScanner::TextPropBitMask mTextPropBitMask
const char * mFieldName
unsigned int mFieldNameLength
int mFieldKind

Static Private Attributes

static bool mInitialized = false
 defined(RESIP_MSG_HEADER_SCANNER_DEBUG) }

Detailed Description

Definition at line 51 of file MsgHeaderScanner.hxx.


Member Typedef Documentation

Definition at line 67 of file MsgHeaderScanner.hxx.


Member Enumeration Documentation

anonymous enum
Enumerator:
MaxNumCharsChunkOverflow 

Definition at line 55 of file MsgHeaderScanner.hxx.

Enumerator:
scrEnd 
scrNextChunk 
scrError 

Definition at line 102 of file MsgHeaderScanner.hxx.

                           {
         scrEnd,       // Message header scan ended.
         scrNextChunk, // Another chunk is needed.
         scrError      // The message header is in error.
      };
Enumerator:
tpbmContainsLineBreak 
tpbmContainsWhitespace 
tpbmContainsBackslash 
tpbmContainsPercent 
tpbmContainsSemicolon 
tpbmContainsParen 

Definition at line 58 of file MsgHeaderScanner.hxx.

      {
         tpbmContainsLineBreak  = 1 << 0,     // '\r' or '\n', always paired
         tpbmContainsWhitespace = 1 << 1,     // ' ' or '\t'
         tpbmContainsBackslash  = 1 << 2,     // '\\'
         tpbmContainsPercent    = 1 << 3,     // '%'
         tpbmContainsSemicolon  = 1 << 4,     // ';'
         tpbmContainsParen      = 1 << 5      // '(' or ')', possibly mismatched
      };

Constructor & Destructor Documentation

resip::MsgHeaderScanner::MsgHeaderScanner ( )

Definition at line 878 of file MsgHeaderScanner.cxx.

References initialize(), and mInitialized.

{
   if (!mInitialized)
   {
      mInitialized = true;
      initialize();
   }
}

Here is the call graph for this function:

resip::MsgHeaderScanner::MsgHeaderScanner ( const MsgHeaderScanner from) [private]

Member Function Documentation

char * resip::MsgHeaderScanner::allocateBuffer ( int  size) [static]
static int resip::MsgHeaderScanner::dumpStateMachine ( int  fd) [static]

Referenced by main().

unsigned int resip::MsgHeaderScanner::getHeaderCount ( ) const [inline]

Definition at line 69 of file MsgHeaderScanner.hxx.

References mNumHeaders.

Referenced by resip::ConnectionBase::preparseNewBytes().

{ return mNumHeaders;} 
bool resip::MsgHeaderScanner::initialize ( ) [private]

Definition at line 1066 of file MsgHeaderScanner.cxx.

Referenced by MsgHeaderScanner().

{
   initCharInfoArray();
   initStateMachine();
   return true;
}
MsgHeaderScanner& resip::MsgHeaderScanner::operator= ( const MsgHeaderScanner from) [private]
void resip::MsgHeaderScanner::prepareForFrag ( SipMessage msg,
bool  hasStartLine 
)

Definition at line 897 of file MsgHeaderScanner.cxx.

References mMsg, mNumHeaders, mPrevScanChunkNumSavedTextChars, and mState.

Referenced by resip::SipFrag::parse().

{
   mMsg = msg;
   if (hasStartLine)
   {
      mState = sMsgStart;
   }
   else
   {
      mState = sAfterLineBreakAfterStatusLine;
   }
   mPrevScanChunkNumSavedTextChars = 0;
   mNumHeaders=0;
}
void resip::MsgHeaderScanner::prepareForMessage ( SipMessage msg)
MsgHeaderScanner::ScanChunkResult resip::MsgHeaderScanner::scanChunk ( char *  chunk,
unsigned int  chunkLength,
char **  unprocessedCharPtr 
)

Definition at line 913 of file MsgHeaderScanner.cxx.

References resip::TransitionInfo::action, resip::CharInfo::category, mFieldKind, mFieldName, mFieldNameLength, mMsg, mNumHeaders, mPrevScanChunkNumSavedTextChars, mState, mTextPropBitMask, resip::TransitionInfo::nextState, scrEnd, scrError, scrNextChunk, and resip::CharInfo::textPropBitMask.

Referenced by resip::SipFrag::parse(), resip::ConnectionBase::preparseNewBytes(), and resip::UdpTransport::processRxParse().

{
   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[(unsigned)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,
                                            (unsigned int)(charPtr - textStartCharPtr),
                                            localTextPropBitMask))
            {
               result = MsgHeaderScanner::scrError;
               *unprocessedCharPtr = charPtr;
               goto endOfFunction;
            }
            textStartCharPtr = 0;
            break;
         case taTermFieldName:
         {
            mFieldNameLength = (unsigned int)(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);
            ++mNumHeaders;
            goto performStartTextAction;
         case taTermValueAfterLineBreak:
            processMsgHeaderFieldNameAndValue(mMsg,
                                              mFieldKind,
                                              mFieldName,
                                              mFieldNameLength,
                                              textStartCharPtr,
                                              (unsigned int)((charPtr - textStartCharPtr) - 2),
                                              localTextPropBitMask);       //^:CRLF
            ++mNumHeaders;
            goto performStartTextAction;
         case taTermValue:
            processMsgHeaderFieldNameAndValue(mMsg,
                                              mFieldKind,
                                              mFieldName,
                                              mFieldNameLength,
                                              textStartCharPtr,
                                              (unsigned int)(charPtr - textStartCharPtr),
                                              localTextPropBitMask);
            textStartCharPtr = 0;
            ++mNumHeaders;
            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 = (unsigned int)(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;
}

Member Data Documentation

Definition at line 81 of file MsgHeaderScanner.hxx.

Referenced by scanChunk().

const char* resip::MsgHeaderScanner::mFieldName [private]

Definition at line 79 of file MsgHeaderScanner.hxx.

Referenced by scanChunk().

Definition at line 80 of file MsgHeaderScanner.hxx.

Referenced by scanChunk().

bool resip::MsgHeaderScanner::mInitialized = false [static, private]

defined(RESIP_MSG_HEADER_SCANNER_DEBUG) }

Definition at line 135 of file MsgHeaderScanner.hxx.

Referenced by MsgHeaderScanner().

Definition at line 74 of file MsgHeaderScanner.hxx.

Referenced by prepareForFrag(), prepareForMessage(), and scanChunk().

unsigned int resip::MsgHeaderScanner::mNumHeaders [private]

Definition at line 75 of file MsgHeaderScanner.hxx.

Referenced by getHeaderCount(), prepareForFrag(), prepareForMessage(), and scanChunk().

Definition at line 77 of file MsgHeaderScanner.hxx.

Referenced by prepareForFrag(), prepareForMessage(), and scanChunk().

Definition at line 76 of file MsgHeaderScanner.hxx.

Referenced by prepareForFrag(), prepareForMessage(), and scanChunk().

Definition at line 78 of file MsgHeaderScanner.hxx.

Referenced by scanChunk().


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