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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: chxfmtpparse.cpp,v 1.6.2.1 2004/07/09 02:05:16 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 "chxfmtpparse.h"
  50. #include "chxcharstack.h"
  51. #include "hlxclib/string.h"
  52. #include "hlxclib/stdlib.h"
  53. #include "hlxclib/errno.h"
  54. #include "hlxclib/limits.h"
  55. static const char FMTP_PREFIX[] = "FMTP";
  56. CHXFMTPParser::CHXFMTPParser(IUnknown* pUnk) :
  57.     m_pCCF(0)
  58. {
  59.     if (pUnk)
  60.     {
  61.         pUnk->QueryInterface(IID_IHXCommonClassFactory, (void**)&m_pCCF);
  62.     }
  63. }
  64. CHXFMTPParser::~CHXFMTPParser()
  65. {
  66.     HX_RELEASE(m_pCCF);
  67. }
  68. HX_RESULT CHXFMTPParser::Parse(const char* pFMTPStr, IHXValues* pHeaders)
  69. {
  70.     HX_RESULT res = HXR_UNEXPECTED;
  71.     // e.g. a=fmtp:101 emphasis=50/15;foo=bar;flag
  72.     
  73.     if (m_pCCF)
  74.     {
  75.         const char* pCur = pFMTPStr;
  76.             
  77.         // Skip payload type
  78.         //for (;*pCur && (*pCur != ' '); pCur++)
  79.         //;
  80.         
  81.         res = HXR_OK;
  82.         
  83.         IHXBuffer* pFieldName = 0;
  84.         IHXBuffer* pFieldValue = 0;
  85.         UINT32 ulState = 0;
  86.         const char* pDelims = 0;
  87.         while ((HXR_OK == res) && *pCur)
  88.         {
  89.             // Skip whitespace
  90.             for (;*pCur && (*pCur == ' '); pCur++)
  91.                 ;
  92.             
  93.             BOOL bCollectValue = FALSE;
  94.             BOOL bAddValue = FALSE;
  95.             IHXBuffer** ppTokDest = 0;
  96.             switch (ulState) {
  97.             case 0:
  98.                 pDelims = " ;=";
  99.                 if (strchr(pDelims, *pCur))
  100.                 {
  101.                     pCur++; // Skip delimiter
  102.                 }
  103.                 else
  104.                 {
  105.                     ulState = 1;
  106.                     bCollectValue = TRUE;
  107.                     ppTokDest = &pFieldName;
  108.                 }
  109.                 break;
  110.             case 1:
  111.                 if (*pCur == '=')
  112.                 {
  113.                     pCur++; // Skip delimiter
  114.                     pDelims = " ;";
  115.                     ulState = 2;
  116.                 }
  117.                 else
  118.                 {
  119.                     bAddValue = TRUE;
  120.                     if (strchr(pDelims, *pCur))
  121.                         pCur++; // Skip delimiter
  122.                 }               
  123.                 break;
  124.             case 2:
  125.                 ppTokDest = &pFieldValue;
  126.                 bCollectValue = TRUE;
  127.                 ulState = 3;
  128.                 break;
  129.             case 3:
  130.                 if (*pCur && strchr(pDelims, *pCur))
  131.                     pCur++; // Skip delimiter
  132.                 bAddValue = TRUE;
  133.                 break;
  134.             }
  135.             if (bCollectValue)
  136.             {
  137.                 res = CollectToken(pCur, pDelims, ppTokDest, bAddValue);
  138.             }
  139.             if (bAddValue)
  140.             {
  141.                 res = AddParam(pFieldName, pFieldValue, pHeaders);
  142.                 HX_RELEASE(pFieldName);
  143.                 HX_RELEASE(pFieldValue);
  144.                 ulState = 0;
  145.             }
  146.         }
  147.         
  148.         if (HXR_OK == res)
  149.         {
  150.             // Add last parameter
  151.             res = AddParam(pFieldName, pFieldValue, pHeaders);
  152.         }
  153.         HX_RELEASE(pFieldName);
  154.         HX_RELEASE(pFieldValue);
  155.     }
  156.     return res;
  157. }
  158. HX_RESULT CHXFMTPParser::CollectToken(const char*& pBuf, const char* pDelims,
  159.                                       IHXBuffer** ppTokDest, BOOL& bAddValue)
  160. {
  161.     HX_RESULT res = HXR_OK;
  162.     CHXCharStack tok(m_pCCF);
  163.     
  164.     // Collect value
  165.     while((HXR_OK == res) && *pBuf && !strchr(pDelims, *pBuf))
  166.     {
  167.         res = tok.AddChar(*pBuf++);
  168.     }
  169.     
  170.     
  171.     IHXBuffer* pTok = 0;
  172.     
  173.     if ((HXR_OK == res) && 
  174.         (HXR_OK == (res = tok.Finish(pTok))))
  175.     {
  176.         // Make sure we dont have an empty string
  177.         if (pTok->GetSize() > 1)
  178.         {
  179.             *ppTokDest = pTok;
  180.         }
  181.         else
  182.         {
  183.             bAddValue = TRUE;
  184.             HX_RELEASE(pTok);
  185.         }
  186.     }
  187.     return res;
  188. }
  189. HX_RESULT CHXFMTPParser::AddParam(IHXBuffer* pFieldName, 
  190.                                   IHXBuffer* pFieldValue,
  191.                                   IHXValues* pHeaders)
  192. {
  193.     HX_RESULT res = HXR_OK;
  194.     if (pFieldName)
  195.     {
  196.         IHXBuffer* pParamName = 0;
  197.         
  198.         res = ContructParamName(pFieldName, pParamName);
  199.         if (HXR_OK == res)
  200.         {
  201.             char* pNameStr = (char*)pParamName->GetBuffer();
  202.             if (pFieldValue)
  203.             {
  204.                 ULONG32 ulValue;
  205.                 if (HXR_OK == ConvertToULONG32(pFieldValue, ulValue))
  206.                 {
  207.                     // Insert as a numeric field
  208.                     res = pHeaders->SetPropertyULONG32(pNameStr, ulValue);
  209.                 }
  210.                 else
  211.                 {
  212.                     res = pHeaders->SetPropertyCString(pNameStr, pFieldValue);
  213.                 }
  214.             }
  215.             else
  216.             {
  217.                 // Assume this is a flag field
  218.                 res = pHeaders->SetPropertyULONG32(pNameStr, 1);
  219.             }
  220.         }
  221.     }
  222.     return res;
  223. }
  224. HX_RESULT CHXFMTPParser::ContructParamName(IHXBuffer* pFieldName, 
  225.                                            REF(IHXBuffer*) pParamName)
  226. {
  227.     HX_RESULT res = HXR_UNEXPECTED;
  228.     pParamName = 0;
  229.     ULONG32 ulSize = 
  230.         strlen((char*)pFieldName->GetBuffer()) + strlen(FMTP_PREFIX) + 1;
  231.     res = m_pCCF->CreateInstance(IID_IHXBuffer, (void**)&pParamName);
  232.     if ((HXR_OK == res) &&
  233.         (HXR_OK == (res = pParamName->SetSize(ulSize))))
  234.     {
  235.         // Construct parameter name. This will be something
  236.         // like FMTPconfig
  237.         strcpy((char*)pParamName->GetBuffer(), FMTP_PREFIX);
  238.         strcat((char*)pParamName->GetBuffer(), (char*)pFieldName->GetBuffer());
  239.     }
  240.     return res;
  241. }
  242. HX_RESULT CHXFMTPParser::ConvertToULONG32(IHXBuffer* pValue, 
  243.                                           REF(ULONG32) ulValue)
  244. {
  245.     HX_RESULT res = HXR_FAILED;
  246.     char* pValueStr = (char*)pValue->GetBuffer();
  247.     char* pEnd = 0;
  248.     ulValue = ::strtoul(pValueStr, &pEnd, 10);
  249.     if (*pValueStr && (*pEnd == '') && 
  250.         ((ulValue != ULONG_MAX) || (errno != ERANGE)))
  251.     {
  252.         res = HXR_OK;
  253.     }
  254.     return res;
  255. }