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

📄 msgheaderscanner.cxx

📁 一个著名的SIP协议栈
💻 CXX
📖 第 1 页 / 共 3 页
字号:
                  taNone,
                  sScanNValue);
   specTransition(sScanNValueInAngles,
                  ccCarriageReturn,
                  taNone,
                  sHalfLineBreakInAnglesInNValue);
   specHalfLineBreakState(sHalfLineBreakInAnglesInNValue,
                          sAfterLineBreakInAnglesInNValue);
   specDefaultTransition(sAfterLineBreakInAnglesInNValue,
                         taError,
                         sAfterLineBreakInAnglesInNValue);
   specTransition(sAfterLineBreakInAnglesInNValue,
                  ccWhitespace,
                  taNone,
                  sScanNValueInAngles);
   specHalfLineBreakState(sHalfLineBreakAfterLineBreak, sMsgStart);

   // Most half-line-break states do nothing when they read a line feed,
   // but sHalfLineBreakAfterLineBreak must end the message header scanning.

   specTransition(sHalfLineBreakAfterLineBreak,
                  ccLineFeed,
                  taEndHeader,
                  sMsgStart); // Arbitrary but possibly handy.
}

// Debug follows
#if defined(RESIP_MSG_HEADER_SCANNER_DEBUG)  

static void printText(const char *  text,
                      unsigned int  textLength)
{
   const char *charPtr = text;
   for (unsigned int counter = 0; counter < textLength; ++charPtr, ++counter)
   {
      char c = *charPtr;
      switch (c)
      {
         case '\\': printf("\\\\");
            break;
         case '\r': printf("\\r");
            break;
         case '\n': printf("\\n");
            break;
         case '\t': printf("\\t");
            break;
         case '\0': printf("\\0");
            break;
         default:   putchar(c);
      }
   }
}

static const char *
categorySymbol(CharCategory c)
{
   switch(c)
   {
      case ccChunkTermSentinel: return "TERM";
      case ccOther: return "*";
      case ccFieldName: return "FName";
      case ccWhitespace: return "WS";
      case ccColon: return "\\\":\\\"";
      case ccDoubleQuotationMark: return "\\\"";
      case ccLeftAngleBracket: return "\\\"<\\\"";
      case ccRightAngleBracket: return "\\\">\\\"";
      case ccBackslash: return "\\\"\\\\\\\"";
      case ccComma: return "\\\",\\\"";
      case ccCarriageReturn: return "CR";
      case ccLineFeed: return "LF";
   }
   return "??CC??";
}

static const char *
categoryName(CharCategory c)
{
   switch(c)
   {
      case ccChunkTermSentinel: return "ccChunkTermSentinel";
      case ccOther: return "ccOther";
      case ccFieldName: return "ccFieldName";
      case ccWhitespace: return "ccWhitespace";
      case ccColon: return "ccColon";
      case ccDoubleQuotationMark: return "ccDoubleQuotationMark";
      case ccLeftAngleBracket: return "ccLeftAngleBracket";
      case ccRightAngleBracket: return "ccRightAngleBracket";
      case ccBackslash: return "ccBackslash";
      case ccComma: return "ccComma";
      case ccCarriageReturn: return "ccCarriageReturn";
      case ccLineFeed: return "ccLineFeed";
   }
   return "UNKNOWNCC";
}

static const char *
cleanName(const char * name)
{
   // Remove leading type-noise from name
   static char *leaders[] = {
      "cc",
      "s",
      "taChunkTerm", // hack to make ChunkTermSentinel smaller
      "ta"
   };
   const int nLeaders = sizeof(leaders)/sizeof(*leaders);
   int offset = 0;
   for(int i = 0 ; i < nLeaders ; i++)
   {
      unsigned int l = strlen(leaders[i]);
      if (strstr(name,leaders[i]) == name &&
          strlen(name) > l && 
          isupper(name[l]))
      {
         offset = l;
         break;
      }
   }
   return &name[offset];
}

static const char * 
stateName(State state)
{
   const char *stateName;
   switch (state) 
   {
      case sMsgStart:
         stateName = "sMsgStart";
         break;
      case sHalfLineBreakAtMsgStart:
         stateName = "sHalfLineBreakAtMsgStart";
         break;
      case sScanStatusLine:
         stateName = "sScanStatusLine";
         break;
      case sHalfLineBreakAfterStatusLine:
         stateName = "sHalfLineBreakAfterStatusLine";
         break;
      case sAfterLineBreakAfterStatusLine:
         stateName = "sAfterLineBreakAfterStatusLine";
         break;
      case sScanFieldName:
         stateName = "sScanFieldName";
         break;
      case sScanWhitespaceAfter1FieldName:
         stateName = "sScanWhitespaceAfter1FieldName";
         break;
      case sScanWhitespaceAfterNFieldName:
         stateName = "sScanWhitespaceAfterNFieldName";
         break;
      case sScanWhitespaceOr1Value:
         stateName = "sScanWhitespaceOr1Value";
         break;
      case sScanWhitespaceOrNValue:
         stateName = "sScanWhitespaceOrNValue";
         break;
      case sHalfLineBreakInWhitespaceBefore1Value:
         stateName = "sHalfLineBreakInWhitespaceBefore1Value";
         break;
      case sHalfLineBreakInWhitespaceBeforeNValue:
         stateName = "sHalfLineBreakInWhitespaceBeforeNValue";
         break;
      case sAfterLineBreakInWhitespaceBefore1Value:
         stateName = "sAfterLineBreakInWhitespaceBefore1Value";
         break;
      case sAfterLineBreakInWhitespaceBeforeNValue:
         stateName = "sAfterLineBreakInWhitespaceBeforeNValue";
         break;
      case sScan1Value:
         stateName = "sScan1Value";
         break;
      case sScanNValue:
         stateName = "sScanNValue";
         break;
      case sHalfLineBreakIn1Value:
         stateName = "sHalfLineBreakIn1Value";
         break;
      case sHalfLineBreakInNValue:
         stateName = "sHalfLineBreakInNValue";
         break;
      case sAfterLineBreakIn1Value:
         stateName = "sAfterLineBreakIn1Value";
         break;
      case sAfterLineBreakInNValue:
         stateName = "sAfterLineBreakInNValue";
         break;
      case sScanNValueInQuotes:
         stateName = "sScanNValueInQuotes";
         break;
      case sAfterEscCharInQuotesInNValue:
         stateName = "sAfterEscCharInQuotesInNValue";
         break;
      case sHalfLineBreakInQuotesInNValue:
         stateName = "sHalfLineBreakInQuotesInNValue";
         break;
      case sAfterLineBreakInQuotesInNValue:
         stateName = "sAfterLineBreakInQuotesInNValue";
         break;
      case sScanNValueInAngles:
         stateName = "sScanNValueInAngles";
         break;
      case sHalfLineBreakInAnglesInNValue:
         stateName = "sHalfLineBreakInAnglesInNValue";
         break;
      case sAfterLineBreakInAnglesInNValue:
         stateName = "sAfterLineBreakInAnglesInNValue";
         break;
      case sHalfLineBreakAfterLineBreak:
         stateName = "sHalfLineBreakAfterLineBreak";
         break;
      default:
         stateName = "<unknown>";
   }//switch
   return stateName;
}

static const char *
trActionName(TransitionAction transitionAction)
{  
   const char *transitionActionName;
   switch (transitionAction)
   {
      case taNone:
         transitionActionName = "taNone";
         break;
      case taTermStatusLine:
         transitionActionName = "taTermStatusLine";
         break;
      case taTermFieldName:
         transitionActionName = "taTermFieldName";
         break;
      case taBeyondEmptyValue:
         transitionActionName = "taBeyondEmptyValue";
         break;
      case taTermValueAfterLineBreak:
         transitionActionName = "taTermValueAfterLineBreak";
         break;
      case taTermValue:
         transitionActionName = "taTermValue";
         break;
      case taStartText:
         transitionActionName = "taStartText";
         break;
      case taEndHeader:
         transitionActionName = "taEndHeader";
         break;
      case taChunkTermSentinel:
         transitionActionName = "taChunkTermSentinel";
         break;
      case taError:
         transitionActionName = "taError";
         break;
      default:
         transitionActionName = "<unknown>";
   }
   return transitionActionName;
}

static void
printStateTransition(State state,
                     char character,
                     TransitionAction transitionAction)
{
   printf("                %s['", cleanName(stateName(state)));
   printText(&character, 1);
   printf("']: %s\n", cleanName(trActionName(transitionAction)));
}
#if !defined(RESIP_MSG_HEADER_SCANNER_DEBUG)
static const char* stateName(const char*)
{ return "RECOMPILE_WITH_SCANNER_DEBUG"; }
static const char* trActionName(const char*)
{ return stateName(0); }
#endif
/// START OF MEMBER METHODS



int
MsgHeaderScanner::dumpStateMachine(int fd)
{
   FILE *fp = fdopen(fd,"w");
   if (!fp) 
   {
      fprintf(stderr,"MsgHeaderScanner:: unable to open output file\n");
      return -1;
   }
   // Force instance so things are initialized -- YUCK! 
   MsgHeaderScanner scanner;(void)scanner;
   fprintf(fp,"digraph MsgHeaderScannerFSM {\n");
   fprintf(fp,"\tnode[shape=record\n\t\tfontsize=8\n\t\tfontname=\"Helvetica\"\n\t]\n");
   fprintf(fp,"\tedge [ fontsize=6 fontname=\"Helvetica\"]\n");
   
   fprintf(fp,"\tgraph [ ratio=0.8\n\t\tfontsize=6 compound=true ]");
   for(int state  = 0 ; state < numStates; ++state)
   {
      fprintf(fp,
              "  %s [ label = \"%d|%s\" ]\n",
              cleanName(stateName(state)),
              state,
              cleanName(stateName(state))
         );
      for(int category = 0 ; category < numCharCategories; ++category)
      {
         // Skip Verbose Error or Empty Transitions
         if (stateMachine[state][category].nextState == state &&
             (stateMachine[state][category].action == taError ||
              stateMachine[state][category].action == taNone
                )) continue;
              
         fprintf(fp,
                 "    %s -> %s [label=\"%s\\n%s\" ]\n",
                 cleanName(stateName(state)),
                 cleanName(stateName(stateMachine[state][category].nextState)),
                 categorySymbol(category),
                 cleanName(trActionName(stateMachine[state][category].action)));
      }
      fprintf(fp,"\n");
   }
   fprintf(fp,"}\n");

   return 0;
}

#endif //defined(RESIP_MSG_HEADER_SCANNER_DEBUG) 



#if defined(RESIP_MSG_HEADER_SCANNER_DEBUG)  

static const char *const multiValuedFieldNameArray[] = {
   "allow-events",
   "accept-encoding",
   "accept-language",
   "allow",
   "content-language",
   "proxy-require",
   "require",
   "supported",
   "subscription-state",
   "unsupported",
   "security-client",
   "security-server",
   "security-verify",
   "accept",
   "call-info",
   "alert-info",
   "error-info",
   "record-route",
   "route",
   "contact",
   "authorization",
   "proxy-authenticate",
   "proxy-authorization",
   "www-authenticate",
   "via",
   0
};

extern
void
lookupMsgHeaderFieldInfo(
   char *                             fieldName,               //inout
   unsigned int                       *fieldNameLength,        //inout
   MsgHeaderScanner::TextPropBitMask  fieldNameTextPropBitMask,
   int                                *fieldKind,              //out
   bool                               *isMultiValueAllowed)    //out
{
   *isMultiValueAllowed = false;
   const char *const *multiValuedFieldNamePtr = multiValuedFieldNameArray;
   for (;;)
   {
      const char *multiValuedFieldName = *multiValuedFieldNamePtr;
      if (!multiValuedFieldName) 
      {
         break;
      }
      if (strncmp(fieldName, multiValuedFieldName, *fieldNameLength) == 0) 
      {
         *isMultiValueAllowed = true;
         break;
      }
      ++multiValuedFieldNamePtr;
   }//for
}

static
bool

⌨️ 快捷键说明

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