hxparse.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:17k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hlxclib/stdlib.h"
  36. //#include "hlxclib/stdio.h"
  37. #include "hlxclib/ctype.h"
  38. #include "hxtypes.h"
  39. #include "hxresult.h"
  40. #include "hxcom.h"
  41. #include "chxxtype.h"
  42. #include "hxwintyp.h"
  43. #include "hxstring.h"
  44. #include "hxstrutl.h"
  45. #include "hxparse.h"
  46. #include "hxheap.h"
  47. #ifdef _DEBUG
  48. #undef HX_THIS_FILE
  49. static const char HX_THIS_FILE[] = __FILE__;
  50. #endif
  51. /*
  52.  * our smil/html color string table
  53.  */
  54. static const struct smilColorTable
  55. {
  56.     const char* m_pColorName;
  57.     UINT8 m_ucRed;
  58.     UINT8 m_ucGreen;
  59.     UINT8 m_ucBlue;
  60. } SmilColorTable[] =
  61. {
  62.     {"black",  0x00, 0x00, 0x00},
  63.     {"silver",  0xc0, 0xc0, 0xc0},
  64.     {"gray",   0x80, 0x80, 0x80},
  65.     {"white",  0xff, 0xff, 0xff},
  66.     {"maroon", 0x80, 0x00, 0x00},
  67.     {"red",    0xff, 0x00, 0x00},
  68.     {"purple", 0x80, 0x00, 0x80},
  69.     {"fuchsia", 0xff, 0x00, 0xff},
  70.     {"green", 0x00, 0x80, 0x00},
  71.     {"lime", 0x00, 0xff, 0x00},
  72.     {"olive", 0x80, 0x80, 0x00},
  73.     {"yellow", 0xff, 0xff, 0x00},
  74.     {"navy", 0x00, 0x00, 0x80},
  75.     {"blue", 0x00, 0x00, 0xff},
  76.     {"teal", 0x00, 0x80, 0x80},
  77.     {"aqua", 0x00, 0xff, 0xff},
  78.     {0, 0x00, 0x00, 0x00}
  79. };
  80. /****************************************************************************
  81.  *  getColorElement
  82.  *
  83.  *  parses a hex value from the string passed in.
  84.  */
  85. UINT8
  86. getColorElement(const char* pColorFrag, int len)
  87. {
  88.     UINT8 ucValue = 0;
  89.     char* pTmpBuf = new char[len+1];
  90.     strncpy(pTmpBuf, pColorFrag, len); /* Flawfinder: ignore */
  91.     pTmpBuf[len] = 0;
  92.     ucValue = (UINT8)strtol(pTmpBuf, 0, 16);
  93.     delete[] pTmpBuf;
  94.     return ucValue;
  95. }
  96. /****************************************************************************
  97.  *  HXParseColor
  98.  *
  99.  *  Parses a smil/html color string and returns its HXxColor value.  The
  100.  *  string should be in one of the following formats: "#RGB", "#RRGGBB",
  101.  *  or one of the pre-defined strings in the table at the top of this file.
  102.  */
  103. HX_RESULT
  104. HXParseColor(const char* pColorString, REF(HXxColor) theColor)
  105. {
  106.     HX_RESULT theErr = HXR_INVALID_PARAMETER;
  107.     theColor = 0;
  108.     UINT8 ucRed = 0;
  109.     UINT8 ucGreen = 0;
  110.     UINT8 ucBlue = 0;
  111.     if(pColorString[0] == '#')
  112.     {
  113. if(strlen(pColorString) == 4)
  114. {
  115.     /* #rgb, duplicate the numbers */
  116.     char tmpBuf[6]; /* Flawfinder: ignore */
  117.     tmpBuf[0] = tmpBuf[1] = pColorString[1];
  118.     tmpBuf[2] = tmpBuf[3] = pColorString[2];
  119.     tmpBuf[4] = tmpBuf[5] = pColorString[3];
  120.     ucRed = getColorElement(&tmpBuf[0], 2);
  121.     ucGreen = getColorElement(&tmpBuf[2], 2);
  122.     ucBlue = getColorElement(&tmpBuf[4], 2);
  123.     theErr = HXR_OK;
  124. }
  125. else if(strlen(pColorString) == 7)
  126. {
  127.     /* #rrggbb */
  128.     ucRed = getColorElement(&pColorString[1], 2);
  129.     ucGreen = getColorElement(&pColorString[3], 2);
  130.     ucBlue = getColorElement(&pColorString[5], 2);
  131.     theErr = HXR_OK;
  132. }
  133.     }
  134.     else if (!strncmp(pColorString, "rgb(", 4))
  135.     {
  136.         // This color is in the form rgb(0,128,255) or
  137.         // in the form rgb(0%,50%,100%)
  138.         //
  139.         // Make a copy of the string, since strtok
  140.         // is destructive
  141.         char* pCopy = new char [strlen(pColorString) + 1];
  142.         if (pCopy)
  143.         {
  144.             strcpy(pCopy, pColorString); /* Flawfinder: ignore */
  145.             // Get past the "rgb("
  146.             UINT32 ulTmp = 0;
  147.             char*  pStr  = strtok(pCopy, "(,)");
  148.             // Get the red string
  149.             pStr = strtok(NULL, "(,)");
  150.             if (pStr)
  151.             {
  152.                 // Use HXParseOpacity to parse the red component
  153.                 theErr = HXParseOpacity((const char*) pStr, ulTmp);
  154.                 if (SUCCEEDED(theErr))
  155.                 {
  156.                     // Assign the red component
  157.                     ucRed = (BYTE) ulTmp;
  158.                     // Get the green string
  159.                     pStr = strtok(NULL, "(,)");
  160.                     if (pStr)
  161.                     {
  162.                         // Use HXParseOpacity to parse the green component
  163.                         theErr = HXParseOpacity((const char*) pStr, ulTmp);
  164.                         if (SUCCEEDED(theErr))
  165.                         {
  166.                             // Assign the green component
  167.                             ucGreen = (BYTE) ulTmp;
  168.                             // Get the blue string
  169.                             pStr = strtok(NULL, "(,)");
  170.                             if (pStr)
  171.                             {
  172.                                 // Use HXParseOpacity to parse the blue component
  173.                                 theErr = HXParseOpacity((const char*) pStr, ulTmp);
  174.                                 if (SUCCEEDED(theErr))
  175.                                 {
  176.                                     // Assign the blue string
  177.                                     ucBlue = (BYTE) ulTmp;
  178.                                 }
  179.                             }
  180.                             else
  181.                             {
  182.                                 theErr = HXR_INVALID_PARAMETER;
  183.                             }
  184.                         }
  185.                     }
  186.                     else
  187.                     {
  188.                         theErr = HXR_INVALID_PARAMETER;
  189.                     }
  190.                 }
  191.             }
  192.         }
  193.         HX_VECTOR_DELETE(pCopy);
  194.     }
  195.     else
  196.     {
  197. // string, try to get it from the color table
  198. int i = 0;
  199. const char* pColorName = SmilColorTable[i].m_pColorName;
  200. while(pColorName)
  201. {
  202.     if(strcmp(pColorName, pColorString) == 0)
  203.     {
  204. ucRed = SmilColorTable[i].m_ucRed;
  205. ucBlue = SmilColorTable[i].m_ucBlue;
  206. ucGreen = SmilColorTable[i].m_ucGreen;
  207. theErr = HXR_OK;
  208. break;
  209.     }
  210.     pColorName = SmilColorTable[++i].m_pColorName;
  211. }
  212.     }
  213.     // Check and see if it's a system color definition.
  214.     // See http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
  215.     // for more info about these.
  216. #ifdef _WINDOWS
  217.     if (FAILED(theErr))
  218.     {
  219.         BOOL  bMatch = FALSE;
  220.         INT32 lIndex = 0;
  221.         if (!strcasecmp(pColorString, "ActiveBorder"))
  222.         {
  223.             lIndex = COLOR_ACTIVEBORDER;
  224.             bMatch = TRUE;
  225.         }
  226.         else if (!strcasecmp(pColorString, "ActiveCaption"))
  227.         {
  228.             lIndex = COLOR_ACTIVECAPTION;
  229.             bMatch = TRUE;
  230.         }
  231.         else if (!strcasecmp(pColorString, "AppWorkspace"))
  232.         {
  233.             lIndex = COLOR_APPWORKSPACE;
  234.             bMatch = TRUE;
  235.         }
  236.         else if (!strcasecmp(pColorString, "Background"))
  237.         {
  238.             lIndex = COLOR_BACKGROUND;
  239.             bMatch = TRUE;
  240.         }
  241.         else if (!strcasecmp(pColorString, "ButtonFace"))
  242.         {
  243.             lIndex = COLOR_BTNFACE;
  244.             bMatch = TRUE;
  245.         }
  246.         else if (!strcasecmp(pColorString, "ButtonHighlight"))
  247.         {
  248.             lIndex = COLOR_BTNHILIGHT;
  249.             bMatch = TRUE;
  250.         }
  251.         else if (!strcasecmp(pColorString, "ButtonShadow"))
  252.         {
  253.             lIndex = COLOR_BTNSHADOW;
  254.             bMatch = TRUE;
  255.         }
  256.         else if (!strcasecmp(pColorString, "ButtonText"))
  257.         {
  258.             lIndex = COLOR_BTNTEXT;
  259.             bMatch = TRUE;
  260.         }
  261.         else if (!strcasecmp(pColorString, "CaptionText"))
  262.         {
  263.             lIndex = COLOR_CAPTIONTEXT;
  264.             bMatch = TRUE;
  265.         }
  266.         else if (!strcasecmp(pColorString, "GrayText"))
  267.         {
  268.             lIndex = COLOR_GRAYTEXT;
  269.             bMatch = TRUE;
  270.         }
  271.         else if (!strcasecmp(pColorString, "Highlight"))
  272.         {
  273.             lIndex = COLOR_HIGHLIGHT;
  274.             bMatch = TRUE;
  275.         }
  276.         else if (!strcasecmp(pColorString, "HighlightText"))
  277.         {
  278.             lIndex = COLOR_HIGHLIGHTTEXT;
  279.             bMatch = TRUE;
  280.         }
  281.         else if (!strcasecmp(pColorString, "InactiveBorder"))
  282.         {
  283.             lIndex = COLOR_INACTIVEBORDER;
  284.             bMatch = TRUE;
  285.         }
  286.         else if (!strcasecmp(pColorString, "InactiveCaption"))
  287.         {
  288.             lIndex = COLOR_INACTIVECAPTION;
  289.             bMatch = TRUE;
  290.         }
  291.         else if (!strcasecmp(pColorString, "InactiveCaptionText"))
  292.         {
  293.             lIndex = COLOR_INACTIVECAPTIONTEXT;
  294.             bMatch = TRUE;
  295.         }
  296.         else if (!strcasecmp(pColorString, "InfoBackground"))
  297.         {
  298.             lIndex = COLOR_INFOBK;
  299.             bMatch = TRUE;
  300.         }
  301.         else if (!strcasecmp(pColorString, "InfoText"))
  302.         {
  303.             lIndex = COLOR_INFOTEXT;
  304.             bMatch = TRUE;
  305.         }
  306.         else if (!strcasecmp(pColorString, "Menu"))
  307.         {
  308.             lIndex = COLOR_MENU;
  309.             bMatch = TRUE;
  310.         }
  311.         else if (!strcasecmp(pColorString, "MenuText"))
  312.         {
  313.             lIndex = COLOR_MENUTEXT;
  314.             bMatch = TRUE;
  315.         }
  316.         else if (!strcasecmp(pColorString, "Scrollbar"))
  317.         {
  318.             lIndex = COLOR_SCROLLBAR;
  319.             bMatch = TRUE;
  320.         }
  321.         else if (!strcasecmp(pColorString, "ThreeDDarkShadow"))
  322.         {
  323.             lIndex = COLOR_3DDKSHADOW;
  324.             bMatch = TRUE;
  325.         }
  326.         else if (!strcasecmp(pColorString, "ThreeDFace"))
  327.         {
  328.             lIndex = COLOR_3DFACE;
  329.             bMatch = TRUE;
  330.         }
  331.         else if (!strcasecmp(pColorString, "ThreeDHighlight"))
  332.         {
  333.             lIndex = COLOR_3DHILIGHT;
  334.             bMatch = TRUE;
  335.         }
  336.         else if (!strcasecmp(pColorString, "ThreeDLightShadow"))
  337.         {
  338.             lIndex = COLOR_3DLIGHT;
  339.             bMatch = TRUE;
  340.         }
  341.         else if (!strcasecmp(pColorString, "ThreeDShadow"))
  342.         {
  343.             lIndex = COLOR_3DSHADOW;
  344.             bMatch = TRUE;
  345.         }
  346.         else if (!strcasecmp(pColorString, "Window"))
  347.         {
  348.             lIndex = COLOR_WINDOW;
  349.             bMatch = TRUE;
  350.         }
  351.         else if (!strcasecmp(pColorString, "WindowFrame"))
  352.         {
  353.             lIndex = COLOR_WINDOWFRAME;
  354.             bMatch = TRUE;
  355.         }
  356.         else if (!strcasecmp(pColorString, "WindowText"))
  357.         {
  358.             lIndex = COLOR_WINDOWTEXT;
  359.             bMatch = TRUE;
  360.         }
  361.         if (bMatch)
  362.         {
  363.             UINT32 ulColor = GetSysColor(lIndex);
  364.             ucRed          = GetRValue(ulColor);
  365.             ucGreen        = GetGValue(ulColor);
  366.             ucBlue         = GetBValue(ulColor);
  367.             theErr         = HXR_OK;
  368.         }
  369.     }
  370. #endif
  371. #ifdef _WINDOWS
  372.     theColor = (HXxColor)(RGB(ucRed, ucGreen, ucBlue));
  373. #else
  374.     theColor = (HXxColor)
  375.     (ucRed << 16 |
  376.     ucGreen << 8 |
  377.     ucBlue);
  378. #endif
  379.     return theErr;
  380. }
  381. HX_RESULT
  382. HXParseDigit(const char* pDigitString, REF(INT32) ulOut)
  383. {
  384.     // validate it first. ([whitespace][sign]digits)
  385.     HX_RESULT ret = HXR_OK;
  386.     const char* pBuf = pDigitString;
  387.     
  388.     // clear white space.
  389.     while (*pBuf && isspace(*pBuf))
  390.     {
  391. ++pBuf;
  392.     }
  393.     // check for sign
  394.     if (*pBuf == '+' || *pBuf == '-')
  395.     {
  396. ++pBuf;
  397.     }
  398.     // validate all else is a digit
  399.     while (*pBuf)
  400.     {
  401. if (!isdigit(*pBuf))
  402. {
  403.     ret = HXR_FAIL;
  404.     break;
  405. }
  406. ++pBuf;
  407.     }
  408.     // run the conversion anyway... just in case the user wants
  409.     // to ignor the error.
  410.     ulOut = atol(pDigitString);
  411.     return ret;
  412. }
  413. HX_RESULT
  414. HXParseDouble(const char* pDoubleString, REF(double) dOut)
  415. {
  416.     // validate it first. 
  417.     // ([whitespace][sign][digits][.digits][{d|D|e|E}[sign]digits])
  418.     HX_RESULT ret = HXR_OK;
  419.     const char* pBuf = pDoubleString;
  420.     // clear white space.
  421.     while (*pBuf && isspace(*pBuf))
  422.     {
  423. ++pBuf;
  424.     }
  425.     // check for sign
  426.     if (*pBuf == '+' || *pBuf == '-')
  427.     {
  428. ++pBuf;
  429.     }
  430.     while (isdigit(*pBuf))
  431.     {
  432. ++pBuf;
  433.     }
  434.     if (*pBuf == '.')
  435.     {
  436. ++pBuf;
  437.     }
  438.     while (isdigit(*pBuf))
  439.     {
  440. ++pBuf;
  441.     }
  442.     if (*pBuf == 'd' || *pBuf == 'D' || *pBuf == 'e' || *pBuf == 'E')
  443.     {
  444. ++pBuf;
  445. if (*pBuf == '+' || *pBuf == '-')
  446. {
  447.     ++pBuf;
  448. }
  449. while (isdigit(*pBuf))
  450. {
  451.     ++pBuf;
  452. }
  453.     }
  454.     
  455.     // we will allow whitespace at the end of the buffer,
  456.     while (isspace(*pBuf))
  457.     {
  458. ++pBuf;
  459.     }
  460.     // now if we are not at the NULL termination something is wrong with the
  461.     // string.
  462.     if (*pBuf != '')
  463.     {
  464. ret = HXR_INVALID_PARAMETER;
  465.     }
  466.     // run the conversion anyway...  The string might simply have junk at 
  467.     // the end of it, in which case the error *might* want to be ignored.
  468.     dOut = atof(pDoubleString);
  469.     return ret;
  470. }
  471. HX_RESULT HXParseColorUINT32(const char* pszStr, REF(UINT32) rulValue)
  472. {
  473.     HX_RESULT retVal = HXR_OK;
  474.     if (pszStr)
  475.     {
  476.         HXxColor cColor;
  477.         retVal = HXParseColor(pszStr, cColor);
  478.         if (SUCCEEDED(retVal))
  479.         {
  480.             rulValue = (UINT32) cColor;
  481. #if defined(_WINDOWS)
  482.             // HXParseColor produces 0x00BBGGRR on Windows - 
  483.             // do the swap back to 0x00RRGGBB
  484.             rulValue = ((rulValue & 0x00FF0000) >> 16)  |
  485.                         (rulValue & 0x0000FF00)         |
  486.                        ((rulValue & 0x000000FF) << 16);
  487. #endif
  488.         }
  489.     }
  490.     else
  491.     {
  492.         retVal = HXR_FAIL;
  493.     }
  494.     return retVal;
  495. }
  496. HX_RESULT HXParsePercent(const char* pszStr, REF(double) rdValue)
  497. {
  498.     HX_RESULT retVal = HXR_FAIL;
  499.     if (pszStr)
  500.     {
  501.         char*  pEndPtr = NULL;
  502.         double dVal    = strtod(pszStr, &pEndPtr);
  503.         if (pEndPtr && *pEndPtr == '%')
  504.         {
  505.             rdValue = dVal;
  506.             retVal  = HXR_OK;
  507.         }
  508.     }
  509.     return retVal;
  510. }
  511. HX_RESULT HXParseUINT32(const char* pszStr, REF(UINT32) rulValue)
  512. {
  513.     HX_RESULT retVal = HXR_OK;
  514.     if (pszStr)
  515.     {
  516.         INT32 lVal = 0;
  517.         retVal     = HXParseDigit(pszStr, lVal);
  518.         if (SUCCEEDED(retVal))
  519.         {
  520.             if (lVal >= 0)
  521.             {
  522.                 rulValue = (UINT32) lVal;
  523.             }
  524.             else
  525.             {
  526.                 retVal = HXR_FAIL;
  527.             }
  528.         }
  529.     }
  530.     else
  531.     {
  532.         retVal = HXR_FAIL;
  533.     }
  534.     return retVal;
  535. }
  536. HX_RESULT HXParseOpacity(const char* pszStr, REF(UINT32) rulValue)
  537. {
  538.     HX_RESULT retVal = HXR_OK;
  539.     if (pszStr)
  540.     {
  541.         // First attempt to parse as a percent
  542.         INT32  lValue   = 0;
  543.         double dPercent = 0.0;
  544.         retVal = HXParsePercent(pszStr, dPercent);
  545.         if (SUCCEEDED(retVal))
  546.         {
  547.             // Scale from 0-100% to 0-255 with rounding
  548.             lValue = (INT32) (dPercent * 255.0 / 100.0 + 0.5);
  549.         }
  550.         else
  551.         {
  552.             // It wasn't a percent, so try and parse as digits
  553.             retVal = HXParseDigit(pszStr, lValue);
  554.         }
  555.         if (SUCCEEDED(retVal))
  556.         {
  557.             // Clamp to 0-255
  558.             if (lValue < 0)   lValue = 0;
  559.             if (lValue > 255) lValue = 255;
  560.             // Assign the out parameter
  561.             rulValue = (UINT32) lValue;
  562.         }
  563.     }
  564.     else
  565.     {
  566.         retVal = HXR_FAIL;
  567.     }
  568.     return retVal;
  569. }