home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / software / pelne / optionp / iis4_07.cab / keyword.cpp < prev    next >
C/C++ Source or Header  |  1997-10-25  |  10KB  |  415 lines

  1. #include "CkyPch.h"
  2.  
  3. #include "keyword.h"
  4. #include "filter.h"
  5. #include "utils.h"
  6.  
  7. #undef EXTERN
  8. #define EXTERN
  9. #include "globals.h"
  10.  
  11.  
  12. // Build table of keywords
  13.  
  14. typedef struct {
  15.     LPCTSTR          ptszKwd;
  16.     CToken::BOUNDARY bndPrefix;
  17.     CToken::BOUNDARY bndSuffix;
  18. } SKeywordData;
  19.  
  20.  
  21. #define KEYWORD(KWD, tszKwd, bndStart, bndEnd, DoFilterDecl)        \
  22.                                                       \
  23.     class CKwd##KWD : public CToken                   \
  24.     {                                                 \
  25.     public:                                           \
  26.         CKwd##KWD(                                    \
  27.             LPCTSTR ptsz,                             \
  28.             BOUNDARY bndPrefix,                       \
  29.             BOUNDARY bndSuffix)                       \
  30.             : CToken(ptsz, bndPrefix, bndSuffix)      \
  31.         {}                                            \
  32.                                                       \
  33.         virtual UINT                                  \
  34.         CountBytes(                                   \
  35.             CStateStack& rss,                         \
  36.             LPCTSTR      ptszData,                    \
  37.             UINT         cchData) const;              \
  38.                                                       \
  39.         DoFilterDecl                                  \
  40.     };                                                \
  41.                                                       \
  42.     static const SKeywordData kd##KWD =               \
  43.         {tszKwd, CToken::bndStart, CToken::bndEnd};
  44.  
  45.  
  46. #define DO_FILTER_DECL                                \
  47.         virtual UINT                                  \
  48.         DoFilter(                                     \
  49.             CStateStack& rss,                         \
  50.             LPCTSTR&     rptszData,                   \
  51.             UINT         cchData,                     \
  52.             LPTSTR&      rptszOutBuf) const;          \
  53.  
  54. #define NO_DO_FILTER_DECL /*none*/
  55.  
  56.  
  57. KEYWORD(StartTag, _T("<"),          IRRELEVANT, IRRELEVANT, NO_DO_FILTER_DECL);
  58. KEYWORD(Anchor,   _T("<a"),         IRRELEVANT, WHITESPACE, NO_DO_FILTER_DECL);
  59. KEYWORD(Area,     _T("<area"),      IRRELEVANT, WHITESPACE, NO_DO_FILTER_DECL);
  60. KEYWORD(EndTag,   _T(">"),          IRRELEVANT, IRRELEVANT, NO_DO_FILTER_DECL);
  61. KEYWORD(HRef,     _T("href="),      WHITESPACE, IRRELEVANT, DO_FILTER_DECL);
  62. KEYWORD(BegCmnt,  _T("<--!"),       IRRELEVANT, WHITESPACE, NO_DO_FILTER_DECL);
  63. KEYWORD(EndCmnt,  _T("-->"),        WHITESPACE, IRRELEVANT, NO_DO_FILTER_DECL);
  64. KEYWORD(BegCmnt2, _T("<comment>"),  IRRELEVANT, WHITESPACE, NO_DO_FILTER_DECL);
  65. KEYWORD(EndCmnt2, _T("</comment>"), WHITESPACE, IRRELEVANT, NO_DO_FILTER_DECL);
  66.  
  67.  
  68.  
  69. #define KEYWORD_INIT(KWD)                             \
  70.     g_trie.AddToken(new CKwd##KWD(kd##KWD.ptszKwd,    \
  71.                                   kd##KWD.bndPrefix,  \
  72.                                   kd##KWD.bndSuffix))
  73.  
  74.  
  75. BOOL
  76. InitKeywords()
  77. {
  78.     KEYWORD_INIT(StartTag);
  79.     KEYWORD_INIT(Anchor);
  80.     KEYWORD_INIT(Area);
  81.     KEYWORD_INIT(EndTag);
  82.     KEYWORD_INIT(HRef);
  83.     KEYWORD_INIT(BegCmnt);
  84.     KEYWORD_INIT(EndCmnt);
  85.     KEYWORD_INIT(BegCmnt2);
  86.     KEYWORD_INIT(EndCmnt2);
  87.  
  88.     DUMP(&g_trie);
  89.  
  90.     return TRUE;
  91. }
  92.  
  93.  
  94.  
  95. BOOL
  96. TerminateKeywords()
  97. {
  98.     g_trie.Flush();
  99.     return TRUE;
  100. }
  101.  
  102.  
  103.  
  104. //----------------------------------------------------------------
  105. // "<" starting a tag
  106.  
  107. UINT
  108. CKwdStartTag::CountBytes(
  109.     CStateStack& rss,
  110.     LPCTSTR      ptszData,
  111.     UINT         cchData) const
  112. {
  113.     rss.m_fInTag = TRUE;
  114.     return 0;
  115. }
  116.  
  117.  
  118.  
  119. //----------------------------------------------------------------
  120. // "<a"
  121.  
  122. UINT
  123. CKwdAnchor::CountBytes(
  124.     CStateStack& rss,
  125.     LPCTSTR      ptszData,
  126.     UINT         cchData) const
  127. {
  128.     if (!rss.m_fInComment)
  129.         rss.push(ANCHOR);
  130.  
  131.     return 0;
  132. }
  133.  
  134.  
  135.  
  136. //----------------------------------------------------------------
  137. // "<area" (occurs inside <map> ... </map>)
  138.  
  139. UINT
  140. CKwdArea::CountBytes(
  141.     CStateStack& rss,
  142.     LPCTSTR      ptszData,
  143.     UINT         cchData) const
  144. {
  145.     if (!rss.m_fInComment)
  146.         rss.push(AREA);
  147.  
  148.     return 0;
  149. }
  150.  
  151.  
  152.  
  153. //----------------------------------------------------------------
  154. // ">" closing "<a [href=...] ...>" or "<area [href=...] ...>"
  155.  
  156. UINT
  157. CKwdEndTag::CountBytes(
  158.     CStateStack& rss,
  159.     LPCTSTR      ptszData,
  160.     UINT         cchData) const
  161. {
  162.     if (!rss.m_fInComment  && !rss.m_fInComment2)
  163.     {
  164.         PARSESTATE ps = rss.top();
  165.         
  166.         if (ps == HREF)
  167.         {
  168.             ps = rss.top();
  169.             rss.pop();
  170.         }
  171.         
  172.         if (ps == ANCHOR  ||  ps == AREA)
  173.         {
  174.             ps = rss.top();
  175.             rss.pop();
  176.         }
  177.     }
  178.  
  179.     rss.m_fInTag = FALSE;
  180.     return 0;
  181. }
  182.  
  183.  
  184.  
  185. //----------------------------------------------------------------
  186. // "href="
  187.  
  188. UINT
  189. CKwdHRef::CountBytes(
  190.     CStateStack& rss,
  191.     LPCTSTR      ptszData,
  192.     UINT         cchData) const
  193. {
  194.     PARSESTATE ps = rss.top();
  195.  
  196.     if (!rss.m_fInComment  && !rss.m_fInComment2)
  197.         if (ps == ANCHOR  ||  ps == AREA)
  198.             rss.push(HREF);
  199.  
  200.     const TCHAR* const ptszEnd = ptszData + cchData;
  201.     
  202.     ptszData += m_str.length();
  203.  
  204.     const TCHAR tchDelim = *ptszData;
  205.  
  206.     if (tchDelim == _T('"'))
  207.         ++ptszData;
  208.     
  209.     int cLen;
  210.     const URLTYPE ut = UrlType(ptszData, ptszEnd, cLen);
  211.     
  212.     if (ut != UT_HTTP  &&  ut != UT_HTTPS  &&  ut != UT_NONE)
  213.         return 0;
  214.     else
  215.         ptszData += cLen;
  216.  
  217.     // Is it an absolute URL?  E.g., http://server/foo/...
  218.     // Don't want to mangle URLs that belong to some other
  219.     // server, as it won't know what to do with them
  220.     if (ptszData[0] == '/'  &&  ptszData[1] == '/')
  221.         return 0;
  222.  
  223.     // Is it a server-relative absolute URL?  E.g., http:/foo/...
  224.     // Session IDs are scoped by application (virtual root) in ASP 1.0
  225.     if (ptszData[0] == '/')
  226.         return 0;
  227.  
  228.     TRACE("href = %x\n", 
  229.           (SESSION_ID_PREFIX_SIZE
  230.            + g_SessionIDSize
  231.            + SESSION_ID_SUFFIX_SIZE));
  232.  
  233.     return (SESSION_ID_PREFIX_SIZE
  234.             + g_SessionIDSize
  235.             + SESSION_ID_SUFFIX_SIZE);
  236. }
  237.  
  238.  
  239.  
  240. UINT
  241. CKwdHRef::DoFilter(
  242.     CStateStack& rss,
  243.     LPCTSTR&     rptszData,
  244.     UINT         cchData,
  245.     LPTSTR&      rptszOutBuf) const
  246. {
  247.     UINT cb = CountBytes(rss, rptszData, cchData);
  248.  
  249.     if (cb != 0)
  250.     {
  251.         const TCHAR* const ptszEnd = rptszData + cchData;
  252.         
  253.         LPCTSTR ptsz = rptszData + m_str.length();
  254.         
  255.         const TCHAR tchDelim = *ptsz;
  256.         
  257.         if (tchDelim == _T('"'))
  258.             ++ptsz;
  259.         
  260.         int cLen;
  261.         const URLTYPE ut = UrlType(ptsz, ptszEnd, cLen);
  262.         
  263.         if (ut != UT_HTTP  &&  ut != UT_HTTPS  &&  ut != UT_NONE)
  264.         {
  265.             ASSERT(FALSE);
  266.             return 0;
  267.         }
  268.         else
  269.             ptsz += cLen;
  270.         
  271.         // Is it an absolute URL?  E.g., http://server/foo/...
  272.         if (ptsz[0] == '/'  &&  ptsz[1] == '/')
  273.         {
  274.             ASSERT(FALSE);
  275.             return 0;
  276.         }
  277.         
  278.         while (*ptsz != _T('?')
  279.                && *ptsz != _T(' ')
  280.                && *ptsz != _T('>')
  281.                && *ptsz != _T('"'))
  282.         {
  283.             // TRACE("%c", *ptsz);
  284.             ++ptsz;
  285.         }
  286.  
  287.         memcpy(rptszOutBuf, rptszData, ptsz - rptszData);
  288.         rptszOutBuf += ptsz - rptszData;
  289.  
  290.         strcpy(rptszOutBuf, SESSION_ID_PREFIX);
  291.         rptszOutBuf += SESSION_ID_PREFIX_SIZE;
  292.  
  293.         strcpy(rptszOutBuf, rss.m_szSessionID);
  294.         rptszOutBuf += g_SessionIDSize;
  295.  
  296.         strcpy(rptszOutBuf, SESSION_ID_SUFFIX);
  297.         rptszOutBuf += SESSION_ID_SUFFIX_SIZE;
  298.  
  299.         // TRACE("%s%s%s",
  300.         //       SESSION_ID_PREFIX, rss.m_szSessionID, SESSION_ID_SUFFIX);
  301.  
  302.         rptszData = ptsz;
  303.     }
  304.     else
  305.     {
  306.         // we must skip over the keyword
  307.        rptszData += m_str.length();
  308.        memcpy( rptszOutBuf, m_str.c_str(), m_str.length() );
  309.        rptszOutBuf += m_str.length();
  310.     }
  311.  
  312.     return 0;   // we have taken care of updating rptszOutBuf
  313. }
  314.  
  315.  
  316.  
  317. //----------------------------------------------------------------
  318. // "<--! "
  319.  
  320. UINT
  321. CKwdBegCmnt::CountBytes(
  322.     CStateStack& rss,
  323.     LPCTSTR      ptszData,
  324.     UINT         cchData) const
  325. {
  326.     rss.push(COMMENT);
  327.     rss.m_fInComment = TRUE;
  328.  
  329.     return 0;
  330. }
  331.  
  332.  
  333.  
  334. //----------------------------------------------------------------
  335. // " -->"
  336.  
  337. UINT
  338. CKwdEndCmnt::CountBytes(
  339.     CStateStack& rss,
  340.     LPCTSTR      ptszData,
  341.     UINT         cchData) const
  342. {
  343.     PARSESTATE ps = rss.top();
  344.  
  345.     if (ps == COMMENT)
  346.     {
  347.         ASSERT(rss.m_fInComment);
  348.         ps = rss.top();
  349.         rss.pop();
  350.     }
  351.     else if (rss.m_fInComment)
  352.     {
  353.         do
  354.         {
  355.             ps = rss.top();
  356.             rss.pop();
  357.         } while (ps != COMMENT  &&  ps != INVALID);
  358.     }
  359.  
  360.     rss.m_fInComment = FALSE;
  361.  
  362.     return 0;
  363. }
  364.  
  365.  
  366.  
  367.  
  368. //----------------------------------------------------------------
  369. // "<comment": an IE- and Mosaic-specific tag
  370.  
  371. UINT
  372. CKwdBegCmnt2::CountBytes(
  373.     CStateStack& rss,
  374.     LPCTSTR      ptszData,
  375.     UINT         cchData) const
  376. {
  377.     rss.push(COMMENT2);
  378.     rss.m_fInComment2 = TRUE;
  379.  
  380.     return 0;
  381. }
  382.  
  383.  
  384.  
  385. //----------------------------------------------------------------
  386. // " </comment"
  387.  
  388. UINT
  389. CKwdEndCmnt2::CountBytes(
  390.     CStateStack& rss,
  391.     LPCTSTR      ptszData,
  392.     UINT         cchData) const
  393. {
  394.     PARSESTATE ps = rss.top();
  395.  
  396.     if (ps == COMMENT2)
  397.     {
  398.         ASSERT(rss.m_fInComment2);
  399.         ps = rss.top();
  400.         rss.pop();
  401.     }
  402.     else if (rss.m_fInComment2)
  403.     {
  404.         do
  405.         {
  406.             ps = rss.top();
  407.             rss.pop();
  408.         } while (ps != COMMENT2  &&  ps != INVALID);
  409.     }
  410.  
  411.     rss.m_fInComment2 = FALSE;
  412.  
  413.     return 0;
  414. }
  415.