mimescan.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:9k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: mimescan.cpp,v 1.5.32.1 2004/07/09 02:05:26 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "hlxclib/ctype.h"
  50. //#include "hlxclib/string.h"
  51. #if !defined(_WINDOWS) && !defined(_OPENWAVE)
  52. #include <unistd.h> // not supported by VC++
  53. #endif
  54. #include "mimescan.h"
  55. #include "hxheap.h"
  56. #ifdef _DEBUG
  57. #undef HX_THIS_FILE
  58. static const char HX_THIS_FILE[] = __FILE__;
  59. #endif
  60. MIMEInputStream::MIMEInputStream(const char* pBuf, UINT32 nBufSize):
  61.     m_nBufSize(nBufSize),
  62.     m_nCurOffset(0),
  63.     m_bUndoValid(FALSE),
  64.     m_nUndo(-1)
  65. {
  66.     m_pBuffer = new char[m_nBufSize];
  67.     memcpy(m_pBuffer, pBuf, HX_SAFESIZE_T(m_nBufSize)); /* Flawfinder: ignore */
  68. }
  69. MIMEInputStream::MIMEInputStream(const CHXString& str)
  70. {
  71.     const char* pBuf = (const char*)str;
  72.     m_nCurOffset = 0;
  73.     m_nBufSize = str.GetLength();
  74.     m_pBuffer = new char[m_nBufSize];
  75.     memcpy(m_pBuffer, pBuf, HX_SAFESIZE_T(m_nBufSize)); /* Flawfinder: ignore */
  76.     m_bUndoValid = FALSE;
  77.     m_nUndo = -1;
  78. }
  79. MIMEInputStream::~MIMEInputStream()
  80. {
  81.     delete[] m_pBuffer;
  82. }
  83. int 
  84. MIMEInputStream::read()
  85. {
  86.     if(m_bUndoValid)
  87.     {
  88. int rc = m_nUndo;
  89. m_bUndoValid = FALSE;
  90. m_nUndo = -1;
  91. return rc;
  92.     }
  93.     if(m_nCurOffset < m_nBufSize)
  94.     {
  95. int chRet = m_pBuffer[m_nCurOffset];
  96. //XXXkshoop treat a EOF in the string as an end of file.
  97. // never read beyond it. don't inc the offset.
  98. if(chRet != -1)
  99. {
  100.     ++m_nCurOffset;
  101.     return chRet;
  102. }
  103.     }
  104.     return -1;
  105. }
  106. int
  107. MIMEInputStream::peek()
  108. {
  109.     if(m_bUndoValid)
  110.     {
  111. return m_nUndo;
  112.     }
  113.     //XXXkshoop ignore whether the location contains EOF 
  114.     // since we don't inc the offset.
  115.     if(m_nCurOffset < m_nBufSize)
  116.     {
  117. return m_pBuffer[m_nCurOffset];
  118.     }
  119.     return -1;
  120. }
  121. int 
  122. MIMEInputStream::read(char* pBuf, UINT32 nLen)
  123. {
  124.     UINT32 offset = 0;
  125.     int ch;
  126.     while((offset < nLen) && (ch = read()) >= 0)
  127. pBuf[offset++] = ch;
  128.     return HX_SAFEINT(offset);
  129. }
  130. UINT32 
  131. MIMEInputStream::available()
  132. {
  133.     return m_nBufSize - m_nCurOffset;
  134. }
  135. UINT32
  136. MIMEInputStream::max_distance_to(char* p)
  137. {
  138.     UINT32 ulDist = 0;
  139.     if (m_bUndoValid)
  140.     {
  141. if (strchr(p, m_nUndo) || m_nUndo == -1)
  142. {
  143.     return 0;
  144. }
  145. ulDist++;
  146.     }
  147.     UINT32 ulTempIndex = m_nCurOffset;
  148.     while (ulTempIndex < m_nBufSize &&
  149. !strchr(p, m_pBuffer[ulTempIndex]) &&
  150. m_pBuffer[ulTempIndex] != -1)
  151.     {
  152. ulDist++;
  153. ulTempIndex++;
  154.     }
  155.     return  ulDist;
  156. }
  157. MIMEScanner::MIMEScanner(MIMEInputStream& input): m_input(input)
  158. {
  159. }
  160. MIMEScanner::~MIMEScanner()
  161. {
  162. }
  163. static const char* const tspecials = " t=:;,-";
  164. MIMEToken 
  165. MIMEScanner::nextToken(char* upTo)
  166. {
  167.     int bInQuote = 0; // are we in a quoted string?
  168.     m_tokstr = "";
  169.     skipWS();
  170.     /*
  171.      * if a token end character is specified, ignore
  172.      * the tspecials, handle 'n' as a special case
  173.      * since lines can be continued by using leading
  174.      * white space on the next line.
  175.      */ 
  176.     if(upTo)
  177.     {
  178. m_tokstr.SetMinBufSize(m_input.max_distance_to(upTo));
  179. int ch = m_input.read();
  180. while(ch != -1)
  181. {
  182.     if(strchr(upTo, ch) && (ch != 'n'))
  183. break;
  184.     if(ch == 'r')
  185.     {
  186. ch = m_input.read();
  187. if(ch == 'n')
  188. {
  189.     ch = m_input.read();
  190.     if(ch == ' ' || ch == 't')
  191.     {
  192. if (m_tokstr == "")
  193. {
  194.     // If a line is blank, we will not allow it to be
  195.     // continued on the next line, since this is 
  196.     // probably the dividing line between headers and
  197.     // content. The content may have whitespace at
  198.     // the beginning (PR #23661) which we want to
  199.     // treat as content and not part of the headers.
  200.     m_input.putBack(ch);
  201.     return MIMEToken(m_tokstr, MIMEToken::T_EOL);
  202. }
  203. else
  204. {
  205.     skipWS();
  206. }
  207.     }
  208.     else
  209.     {
  210. m_input.putBack(ch);
  211. return MIMEToken(m_tokstr, MIMEToken::T_EOL);
  212.     }
  213. }
  214. else if(ch == ' ' || ch == 't')
  215. {
  216.     skipWS();
  217. }
  218. else
  219. {
  220.     m_input.putBack(ch);
  221.     return MIMEToken(m_tokstr, MIMEToken::T_EOL);
  222. }
  223.     }
  224.     else if(ch == 'n')
  225.     {
  226. ch = m_input.read();
  227. if(ch == 'r')
  228. {
  229.     ch = m_input.read();
  230.     if(ch == ' ' || ch == 't')
  231.     {
  232. if (m_tokstr == "")
  233. {
  234.     // If a line is blank, we will not allow it to be
  235.     // continued on the next line, since this is 
  236.     // probably the dividing line between headers and
  237.     // content. The content may have whitespace at
  238.     // the beginning (PR #23661) which we want to
  239.     // treat as content and not part of the headers.
  240.     m_input.putBack(ch);
  241.     return MIMEToken(m_tokstr, MIMEToken::T_EOL);
  242. }
  243. else
  244. {
  245.     skipWS();
  246. }
  247.     }
  248.     else
  249.     {
  250. m_input.putBack(ch);
  251. return MIMEToken(m_tokstr, MIMEToken::T_EOL);
  252.     }
  253. }
  254. else if(ch == ' ' || ch == 't')
  255. {
  256.     skipWS();
  257. }
  258. else
  259. {
  260.     m_input.putBack(ch);
  261.     return MIMEToken(m_tokstr, MIMEToken::T_EOL);
  262. }
  263.     }
  264.     else
  265.     {
  266. m_tokstr += ch;
  267.     }
  268.     ch = m_input.read();
  269. }
  270. return MIMEToken(m_tokstr, ch);
  271.     }
  272.     int ch = m_input.read();
  273.     switch(ch)
  274.     {
  275. case -1:
  276.     return MIMEToken(MIMEToken::T_EOF);
  277.     break;
  278. case 'r':
  279.     if((ch = m_input.read()) != 'n')
  280. m_input.putBack(ch);
  281.     return MIMEToken(MIMEToken::T_EOL);
  282.     break;
  283. case 'n':
  284.     if((ch = m_input.read()) != 'r')
  285. m_input.putBack(ch);
  286.     return MIMEToken(MIMEToken::T_EOL);
  287. case '"':
  288.     bInQuote = 1;
  289.     ch = m_input.read(); // get to next char
  290.     break;
  291. default:
  292.     break; // assume T_STRING - need more error processing here
  293.     }
  294.     // read string
  295.     while(ch != MIMEToken::T_EOF) 
  296.     {
  297. if(bInQuote)
  298. {
  299.     if(ch == '"')
  300.     {
  301. ch = m_input.read(); // next char to be put back
  302. bInQuote = 0;
  303. break;
  304.     }
  305. }
  306. else
  307. {
  308.     if(strchr(tspecials, ch) || iscntrl(ch))
  309. break;
  310. }
  311. /*
  312.  * Handle escaped double quotes
  313.  */
  314. if(ch == '\')
  315. {
  316.     ch = m_input.peek();
  317.     if(ch == '"')
  318.     {
  319. ch = m_input.read();
  320.     }
  321. }
  322.     
  323. m_tokstr += ch;
  324. ch = m_input.read();
  325.     }
  326.     m_input.putBack(ch);
  327.     return MIMEToken(m_tokstr, ch);
  328. }
  329. void 
  330. MIMEScanner::skipWS()
  331. {
  332.     int ch = m_input.read();
  333.     while(ch == ' ' || ch == 't')
  334. ch = m_input.read();
  335.     m_input.putBack(ch);
  336. }