|
reSIProcate/stack
9694
|
#include <MsgHeaderScanner.hxx>

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) | |
| MsgHeaderScanner & | operator= (const MsgHeaderScanner &from) |
| bool | initialize () |
Private Attributes | |
| SipMessage * | mMsg |
| 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) } | |
Definition at line 51 of file MsgHeaderScanner.hxx.
| typedef unsigned char resip::MsgHeaderScanner::TextPropBitMask |
Definition at line 67 of file MsgHeaderScanner.hxx.
| anonymous enum |
Definition at line 55 of file MsgHeaderScanner.hxx.
{ MaxNumCharsChunkOverflow = 5 };
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.
};
| 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
};
| resip::MsgHeaderScanner::MsgHeaderScanner | ( | ) |
Definition at line 878 of file MsgHeaderScanner.cxx.
References initialize(), and mInitialized.
{
if (!mInitialized)
{
mInitialized = true;
initialize();
}
}

| resip::MsgHeaderScanner::MsgHeaderScanner | ( | const MsgHeaderScanner & | from | ) | [private] |
| char * resip::MsgHeaderScanner::allocateBuffer | ( | int | size | ) | [static] |
Definition at line 43 of file MsgHeaderScanner.cxx.
References MaxNumCharsChunkOverflow.
Referenced by resip::HeaderFieldValue::copyWithPadding(), resip::ConnectionBase::getWriteBuffer(), resip::ConnectionBase::getWriteBufferForExtraBytes(), resip::HeaderFieldValue::HeaderFieldValue(), resip::ConnectionBase::preparseNewBytes(), resip::UdpTransport::processRxParse(), and resip::UdpTransport::processRxRecv().
{
return new char[size + MaxNumCharsChunkOverflow];
}
| 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 | ) |
Definition at line 888 of file MsgHeaderScanner.cxx.
References mMsg, mNumHeaders, mPrevScanChunkNumSavedTextChars, and mState.
Referenced by resip::SipMessage::make(), resip::ConnectionBase::preparseNewBytes(), and resip::UdpTransport::processRxParse().
{
mMsg = msg;
mState = sMsgStart;
mPrevScanChunkNumSavedTextChars = 0;
mNumHeaders=0;
}
| 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;
}
int resip::MsgHeaderScanner::mFieldKind [private] |
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().
unsigned int resip::MsgHeaderScanner::mFieldNameLength [private] |
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().
SipMessage* resip::MsgHeaderScanner::mMsg [private] |
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().
int resip::MsgHeaderScanner::mPrevScanChunkNumSavedTextChars [private] |
Definition at line 77 of file MsgHeaderScanner.hxx.
Referenced by prepareForFrag(), prepareForMessage(), and scanChunk().
int resip::MsgHeaderScanner::mState [private] |
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().
1.7.5.1