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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: parseurl.cpp,v 1.1.26.1 2004/07/09 01:54:47 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. // From include
  50. #include <ctype.h>
  51. #include "hxtypes.h"
  52. #include "hxwintyp.h"
  53. #include "hxcom.h"
  54. #include "hxresult.h"
  55. #include "ihxpckts.h"
  56. #include "hxcomm.h"
  57. // From hxcont
  58. #include "hxstring.h"
  59. #include "chxpckts.h"
  60. // From hxmisc
  61. #include "hxurl.h"
  62. #include "unkimp.h"
  63. #include "baseobj.h"
  64. #include "hxparse.h"
  65. // From pxcomlib
  66. #include "gstring.h"
  67. #include "pxutil.h"
  68. #include "pxcolor.h"
  69. #include "pxrect.h"
  70. #include "pxeffect.h"
  71. #include "buffutil.h"
  72. #include "parseurl.h"
  73. #ifdef _MACINTOSH
  74. #include <ctype.h>  // For toupper on the Macintosh.
  75. #include <stdlib.h> // for atol
  76. #endif
  77. // hxdebug
  78. #include "hxheap.h"
  79. #ifdef _DEBUG
  80. #undef HX_THIS_FILE
  81. static char HX_THIS_FILE[] = __FILE__;
  82. #endif
  83. HX_RESULT ParseURLEncoding(IHXCommonClassFactory *pFactory, const char *pszURL, IHXValues **ppValues)
  84. {
  85.     // Check for input errors
  86.     if (!pFactory || !pszURL)
  87.     {
  88.         return HXR_FAIL;
  89.     }
  90.     // Create an IHXValues object
  91.     IHXValues *pValues = NULL;
  92.     HX_RESULT retVal    = pFactory->CreateInstance(CLSID_IHXValues, (void **) &pValues);
  93.     if (retVal != HXR_OK)
  94.     {
  95.         return retVal;
  96.     }
  97.     *ppValues = pValues;
  98.     // Get a string class with the URL in it
  99.     GString cURL = pszURL;
  100.     // Get the length
  101.     INT32 lURLLen = strlen(pszURL);
  102.     // Look for the beginning of the parameter string
  103.     INT32 lPos = cURL.find('?');
  104.     if (lPos < 0)
  105.     {
  106.         return HXR_OK;
  107.     }
  108.     // Now we go into a loop looking for attribute/value pairs
  109.     for(;;)
  110.     {
  111.         // Set the beginning of the attribute
  112.         INT32 lAttributeLeftPos = lPos + 1;
  113.         // Look for the end of the attribute
  114.         lPos = cURL.find('=', lPos);
  115.         if (lPos < 0)
  116.         {
  117.             break;
  118.         }
  119.         // Set the inclusive end of the attribute
  120.         INT32 lAttributeRightPos = lPos - 1;
  121.         INT32 lValueLeftPos      = lPos + 1;
  122.         INT32 lValueRightPos;
  123. // Make sure we don't have a situation like "foo.jpg?bitrate="
  124. if (lValueLeftPos >= lURLLen)
  125. {
  126.     break;
  127. }
  128.         // Now look for the separator
  129.         lPos = cURL.find('&', lPos);
  130.         if (lPos < 0)
  131.         {
  132.             // We didn't find the separator, so we assume the end of
  133.             // the string is the end of the value
  134.             lValueRightPos = cURL.length() - 1;
  135.             lPos           = lValueRightPos;
  136.         }
  137.         else
  138.         {
  139.             lValueRightPos = lPos - 1;
  140.         }
  141.         // Check to see if we have valid strings for our attribute and value
  142.         if (lAttributeRightPos >= lAttributeLeftPos &&
  143.             lValueRightPos     >= lValueLeftPos)
  144.         {
  145.             GString cAttribute = cURL.substr(lAttributeLeftPos, lAttributeRightPos);
  146.             GString cValue     = cURL.substr(lValueLeftPos,     lValueRightPos);
  147.             // Create an IHXBuffer
  148.             IHXBuffer *pBuffer = NULL;
  149.             retVal              = pFactory->CreateInstance(CLSID_IHXBuffer, (void **) &pBuffer);
  150.             if (retVal != HXR_OK)
  151.             {
  152.                 HX_RELEASE(pValues);
  153.                 *ppValues = NULL;
  154.                 return retVal;
  155.             }
  156.             // Set value string into the buffer
  157.             retVal = pBuffer->Set((const BYTE *) cValue.c_str(), cValue.length() + 1);
  158.             if (retVal != HXR_OK)
  159.             {
  160.                 HX_RELEASE(pBuffer);
  161.                 HX_RELEASE(pValues);
  162.                 *ppValues = NULL;
  163.                 return retVal;
  164.             }
  165.             // Set the attribute/value pair
  166.             retVal = pValues->SetPropertyCString(cAttribute.c_str(), pBuffer);
  167.             if (retVal != HXR_OK)
  168.             {
  169.                 HX_RELEASE(pBuffer);
  170.                 HX_RELEASE(pValues);
  171.                 *ppValues = NULL;
  172.                 return retVal;
  173.             }
  174.             // Release our reference on the buffer
  175.             HX_RELEASE(pBuffer);
  176.         }
  177.     }
  178.     return HXR_OK;
  179. }
  180. HX_RESULT ExtractValueTime(IHXValues *pValues, const char *pszAttr, UINT32 ulDefault, UINT32 &rulValue)
  181. {
  182.     IHXBuffer *pStringBuf = NULL;
  183.     HX_RESULT retVal = pValues->GetPropertyCString(pszAttr, pStringBuf);
  184.     if (retVal != HXR_OK)
  185.     {
  186.         // No attribute was specified, so take the default
  187.         rulValue = ulDefault;
  188.         return HXR_OK;
  189.     }
  190.     // An attribute was specified so use it
  191.     char   *pszStr   = (char *) pStringBuf->GetBuffer();
  192.     UINT32  ulStrLen = strlen(pszStr);
  193.     BOOL bRet        = ConvertTimeStringToULONG32(pszStr, ulStrLen, rulValue);
  194.     if (bRet == FALSE)
  195.     {
  196.         HX_RELEASE(pStringBuf);
  197.         return HXR_FAIL;
  198.     }
  199.     HX_RELEASE(pStringBuf);
  200.     return HXR_OK;
  201. }
  202. HX_RESULT ExtractValueUINT32(IHXValues *pValues, const char *pszAttr, UINT32 ulDefault, UINT32 &rulValue)
  203. {
  204.     IHXBuffer *pStringBuf = NULL;
  205.     HX_RESULT retVal = pValues->GetPropertyCString(pszAttr, pStringBuf);
  206.     if (retVal != HXR_OK)
  207.     {
  208.         // No attribute was specified, so take the default
  209.         rulValue = ulDefault;
  210.         return HXR_OK;
  211.     }
  212.     // An attribute was specified so use it
  213.     rulValue = (UINT32) atol((char *) pStringBuf->GetBuffer());
  214.     // Release the buffer
  215.     HX_RELEASE(pStringBuf);
  216.     return HXR_OK;
  217. }
  218. HX_RESULT ExtractValueBOOL(IHXValues *pValues, const char *pszAttr, BOOL bDefault, BOOL &rbValue)
  219. {
  220.     IHXBuffer *pStringBuf = NULL;
  221.     HX_RESULT   retVal     = pValues->GetPropertyCString(pszAttr, pStringBuf);
  222.     if (retVal != HXR_OK)
  223.     {
  224.         // No attribute was specified, so take the default
  225.         rbValue = bDefault;
  226.         return HXR_OK;
  227.     }
  228.     // An attribute was specified so use it
  229.     char *pVal = (char *) pStringBuf->GetBuffer();
  230.     if (!strcmp(pVal, "true"))
  231.     {
  232.         rbValue = TRUE;
  233.     }
  234.     else if (!strcmp(pVal, "false"))
  235.     {
  236.         rbValue = FALSE;
  237.     }
  238.     else
  239.     {
  240.         rbValue = bDefault;
  241.         HX_RELEASE(pStringBuf);
  242.         return HXR_FAIL;
  243.     }
  244.     // Release the buffer
  245.     HX_RELEASE(pStringBuf);
  246.     return HXR_OK;
  247. }
  248. HX_RESULT ExtractValueString(IHXValues *pValues, const char *pszAttr, const char *pszDefault, CHXString &rcValue)
  249. {
  250.     IHXBuffer* pStringBuf = NULL;
  251.     HX_RESULT retVal = pValues->GetPropertyCString(pszAttr, pStringBuf);
  252.     if (retVal != HXR_OK)
  253.     {
  254.         // No attribute was specified, so take the default
  255.         if (pszDefault)
  256.         {
  257.             rcValue = pszDefault;
  258.         }
  259.         return HXR_OK;
  260.     }
  261.     // An attribute was specified so use it
  262.     rcValue = (const char*) pStringBuf->GetBuffer();
  263.     // Release the value buffer
  264.     HX_RELEASE(pStringBuf);
  265.     return HXR_OK;
  266. }
  267. HX_RESULT ExtractValueString(IHXValues *pValues, const char *pszAttr, const char *pszDefault, GString &rcValue)
  268. {
  269.     IHXBuffer *pStringBuf = NULL;
  270.     HX_RESULT retVal = pValues->GetPropertyCString(pszAttr, pStringBuf);
  271.     if (retVal != HXR_OK)
  272.     {
  273.         // No attribute was specified, so take the default
  274.         if (pszDefault)
  275.         {
  276.             rcValue = pszDefault;
  277.         }
  278.         else
  279.         {
  280.             rcValue = "";
  281.         }
  282.         return HXR_OK;
  283.     }
  284.     // An attribute was specified so use it
  285.     rcValue.CopyN(pStringBuf->GetBuffer(), pStringBuf->GetSize());
  286.     // Release the value buffer
  287.     HX_RELEASE(pStringBuf);
  288.     return HXR_OK;
  289. }
  290. HX_RESULT ExtractValueColor(IHXValues *pValues, const char *pszAttr, const char *pszDefault, PXColor &rcValue)
  291. {
  292.     IHXBuffer *pStringBuf = NULL;
  293.     HX_RESULT   retVal = pValues->GetPropertyCString(pszAttr, pStringBuf);
  294.     GString     cColor;
  295.     if (retVal != HXR_OK)
  296.     {
  297.         cColor = pszDefault;
  298.     }
  299.     else
  300.     {
  301.         // An attribute was specified so use it
  302.         cColor.CopyN(pStringBuf->GetBuffer(), pStringBuf->GetSize());
  303.         // Release the value buffer
  304.         HX_RELEASE(pStringBuf);
  305.     }
  306.     // Now convert the color
  307.     retVal = rcValue.InitFromString(cColor.c_str());
  308.     if (retVal != HXR_OK)
  309.     {
  310.         return retVal;
  311.     }
  312.     return HXR_OK;
  313. }
  314. HX_RESULT ExtractValueColor(IHXValues *pValues, const char *pszAttr, UINT32 ulDefault, UINT32& rulValue)
  315. {
  316.     IHXBuffer* pStringBuf = NULL;
  317.     HX_RESULT   retVal = pValues->GetPropertyCString(pszAttr, pStringBuf);
  318.     if (retVal != HXR_OK)
  319.     {
  320.         rulValue = ulDefault;
  321.     }
  322.     else
  323.     {
  324.         UINT32 ulTmp = ulDefault;
  325.         retVal = HXParseColorUINT32((const char*) pStringBuf->GetBuffer(),
  326.                                     ulTmp);
  327.         if (SUCCEEDED(retVal))
  328.         {
  329.             rulValue = ulTmp;
  330.         }
  331.         else
  332.         {
  333.             rulValue = ulDefault;
  334.         }
  335.         // Release the value buffer
  336.         HX_RELEASE(pStringBuf);
  337.     }
  338.     return HXR_OK;
  339. }
  340. HX_RESULT ExtractValueOpacity(IHXValues *pValues, const char *pszAttr, UINT32 ulDefault, UINT32& rulValue)
  341. {
  342.     IHXBuffer *pStringBuf = NULL;
  343.     HX_RESULT retVal = pValues->GetPropertyCString(pszAttr, pStringBuf);
  344.     if (retVal != HXR_OK)
  345.     {
  346.         // No attribute was specified, so take the default
  347.         rulValue = ulDefault;
  348.         return HXR_OK;
  349.     }
  350.     // An attribute was specified so use it
  351.     INT32  lOpacity  = 0;
  352.     char*  pEndPtr   = NULL;
  353.     double dVal      = strtod((const char*) pStringBuf->GetBuffer(), &pEndPtr);
  354.     if (pEndPtr && *pEndPtr == '%')
  355.     {
  356.         // Value is a percent
  357.         lOpacity = (INT32) ((dVal * 255.0 / 100.0) + 0.5);
  358.     }
  359.     else
  360.     {
  361.         lOpacity = (INT32) (dVal + 0.5);
  362.     }
  363.     // Range check
  364.     if (lOpacity < 0)
  365.     {
  366.         lOpacity = 0;
  367.     }
  368.     if (lOpacity > 255)
  369.     {
  370.         lOpacity = 255;
  371.     }
  372.     // Assign the out parameter
  373.     rulValue = (UINT32) lOpacity;
  374.     // Release the buffer
  375.     HX_RELEASE(pStringBuf);
  376.     return HXR_OK;
  377. }
  378. BOOL ConvertTimeStringToULONG32(char *pTimeBuf, ULONG32 timeBufLen, ULONG32 &timeValInMillisec)
  379. {
  380.     char   *pTimeBuffer            = pTimeBuf;
  381.     ULONG32 timeBufferLen          = timeBufLen;
  382.     char    savedEndChar           = '';   //for restoring '"' char at end, if found.
  383.     LONG32  bufIndx                = 0L;
  384.     BOOL    bDotEncounteredAlready = FALSE;
  385.     LONG32  indexOfDot             = -1;
  386.     BOOL    endCharWasChanged      = FALSE;
  387.     ULONG32 days_;
  388.     ULONG32 hours_;
  389.     ULONG32 minutes_;
  390.     ULONG32 seconds_;
  391.     ULONG32 milliseconds_;
  392.     // Initialize
  393.     days_ = hours_ = minutes_ = seconds_ = milliseconds_ = 0L;
  394.     timeValInMillisec=0;
  395.     // Check for input error
  396.     if(!pTimeBuffer  ||  timeBufLen < MIN_TIMEBUFFERLENGTH)
  397.     {
  398.         return FALSE;
  399.     }
  400.     savedEndChar = pTimeBuffer[timeBufferLen-1];
  401.     //Get rid of start & terminating quotation mark, if they exist:
  402.     if(pTimeBuffer[0] == '"')
  403.     {
  404.         pTimeBuffer++;
  405.         timeBufferLen--;
  406.         //Added this check to kill bug if (pTimeBuffer==")
  407.         // and got shortened to an empty string:
  408.         if(!timeBufferLen)
  409.         {
  410.             return FALSE;
  411.         }
  412.     }
  413.     if(pTimeBuffer[timeBufferLen - 1] == '"')
  414.     {
  415.         pTimeBuffer[timeBufferLen - 1] = ''; //get rid of end '"'.
  416.         timeBufferLen--;
  417.         endCharWasChanged = TRUE;
  418.     }
  419.     
  420.     // Work from right to left, searching first for milliseconds and then for
  421.     // seconds (or seconds only if no '.' found):
  422.     BOOL bColonWasFound = FALSE;
  423.     for(bufIndx=timeBufferLen-1; 0L<=bufIndx; bufIndx--)
  424.     {
  425.         char ch = toupper(pTimeBuffer[bufIndx]);
  426.         if('0' > ch  ||  '9' < ch)
  427.         {
  428.             if(' '==ch  ||  't'==ch  ||  'n'==ch  ||  'r'==ch)
  429.             {
  430.                 //Added everything up to "break;" to
  431.                 // handle (valid) strings with leading space(s) like " 39":
  432.                 //previous found was seconds_, so translate into ULONG:
  433.                 seconds_ = atol(&pTimeBuffer[bufIndx+1L]);
  434.                 timeValInMillisec += seconds_*1000; //converts seconds to ms.
  435.                 break; //we're done; we found seconds only.
  436.             }
  437.             else if('.' == ch)
  438.             {
  439.                 if(bDotEncounteredAlready)
  440.                 {
  441.                     //Make sure pTimeBuffer is in original state:
  442.                     if(endCharWasChanged)
  443.                     {
  444.                         timeBufferLen++;
  445.                         pTimeBuffer[timeBufferLen-1] = savedEndChar;
  446.                     }
  447.                     if(indexOfDot >= 0)
  448.                     {
  449.                         pTimeBuffer[indexOfDot] = '.';
  450.                     }
  451.                     //this second '.' is unexpected, so return with
  452.                     //  timeValInMillisec set to whatever was read so far:
  453.                     return FALSE;
  454.                 }
  455.                 bDotEncounteredAlready = TRUE;
  456.                 indexOfDot = bufIndx;
  457.                 pTimeBuffer[bufIndx] = ''; //end the buffr at the '.' .
  458.                 //previously-read #'s are milliseconds, so count them:
  459.                 //added "-1" to fix bug if buf ends with ".":
  460.                 if(1L > timeBufferLen-bufIndx - 1)
  461.                 {
  462.                     milliseconds_ = 0L;
  463.                 }
  464.                 else
  465.                 {
  466.                     //Now, make sure that more than three digits (base 10)
  467.                     //  are not present, e.g., reduce "46371" to "463" since
  468.                     //  we only allow millisecond precision (3 digits past
  469.                     //  the decimal point:
  470.                     char    chTmp = '';
  471.                     ULONG32 ulNumDecimalDigitsFound = timeBufferLen-1 - bufIndx;
  472.                     if(NUM_DECIMAL_DIGITS_OF_SECONDS < ulNumDecimalDigitsFound)
  473.                     {
  474.                         chTmp                                                = pTimeBuffer[bufIndx + 1L];
  475.                         pTimeBuffer[bufIndx+NUM_DECIMAL_DIGITS_OF_SECONDS+1] = '';
  476.                     }
  477.                     milliseconds_ = atol(&pTimeBuffer[bufIndx+1L]);
  478.                     //Added this to fix "y.x" being converted
  479.                     // to y00x instead of yx00 milliseconds:
  480.                     if(ulNumDecimalDigitsFound < NUM_DECIMAL_DIGITS_OF_SECONDS)
  481.                     {
  482.                         for(ULONG32 ulDiff= NUM_DECIMAL_DIGITS_OF_SECONDS - ulNumDecimalDigitsFound; ulDiff > 0; ulDiff--)
  483.                         {
  484.                             milliseconds_ *= 10;
  485.                         }
  486.                     }
  487.                     if(NUM_DECIMAL_DIGITS_OF_SECONDS < ulNumDecimalDigitsFound)
  488.                     {
  489.                         //restore the changed char in the pTimeBuffer:
  490.                         pTimeBuffer[bufIndx+ NUM_DECIMAL_DIGITS_OF_SECONDS + 1] = chTmp;
  491.                     }
  492.                 }
  493.         
  494.                 timeValInMillisec = milliseconds_;
  495.             }
  496.             else if(':' == ch)
  497.             {
  498.                 bColonWasFound = TRUE;
  499.                 //previous found was seconds_, so translate into ULONG:
  500.                 seconds_           = atol(&pTimeBuffer[bufIndx + 1L]);
  501.                 timeValInMillisec += seconds_ * 1000; //converts seconds to ms.
  502.                 break; //done with "seconds_[.milliseconds_]" part.
  503.             }
  504.             else  //unexpected char found, so quit parsing:
  505.             {
  506.                 //Make sure pTimeBuffer is in original state:
  507.                 if(endCharWasChanged)
  508.                 {
  509.                     timeBufferLen++;
  510.                     pTimeBuffer[timeBufferLen - 1] = savedEndChar;
  511.                 }
  512.                 if(indexOfDot >= 0)
  513.                 {
  514.                     pTimeBuffer[indexOfDot] = '.';
  515.                 }
  516.                 //this char is unexpected, so return FALSE with
  517.                 //  timeValInMillisec set to whatever was read so far:
  518.                 return FALSE;
  519.             }
  520.         }
  521.         else if(0L == bufIndx) //we're done with the buffer:
  522.         {
  523.             //previous found was seconds_, so translate into ULONG:
  524.             seconds_           = atol(pTimeBuffer);
  525.             timeValInMillisec += seconds_*1000; //converts seconds to ms.
  526.             break; //done with "seconds_[.milliseconds_]" part.
  527.         }
  528.     }
  529.     if(bColonWasFound) //then get the "minutes" part:
  530.     {
  531.         bColonWasFound = FALSE;
  532.         // We've got the ":seconds.msecs" part, so lets get the hours part:
  533.         for(bufIndx--; 0L<=bufIndx; bufIndx--)
  534.         {
  535.             char ch = toupper(pTimeBuffer[bufIndx]);
  536.             if('0' > ch  ||  '9' < ch)
  537.             {
  538.                 if(' ' == ch  ||  '.' == ch)
  539.                 {
  540.                     break;
  541.                 }
  542.                 else if(':' == ch)
  543.                 {
  544.                     bColonWasFound = TRUE;
  545.                     //previous found was seconds_, so translate into ULONG:
  546.                     // (Note: this will do atol("min:sec") which ignores
  547.                     // everything at & beyond the first non-num (":") char):
  548.                     minutes_           = atol(&pTimeBuffer[bufIndx+1L]);
  549.                     timeValInMillisec += minutes_*60000; //minutes to msec
  550.                     break; //done w/ "minutes_:seconds_[milliseconds_]" part.
  551.                 }
  552.                 else  //unexpected char found, so quit parsing:
  553.                 {
  554.                     //Make sure pTimeBuffer is in original state:
  555.                     if(endCharWasChanged)
  556.                     {
  557.                         timeBufferLen++;
  558.                         pTimeBuffer[timeBufferLen-1] = savedEndChar;
  559.                     }
  560.                     if(indexOfDot >= 0)
  561.                     {
  562.                         pTimeBuffer[indexOfDot] = '.';
  563.                     }
  564.                     //this char is unexpected, so return FALSE with
  565.                     //  timeValInMillisec set to whatever was read so far:
  566.                     return FALSE;
  567.                 }
  568.             }
  569.             else if(0L == bufIndx) //we're done with the buffer:
  570.             {
  571.                 //previous found was seconds_, so translate into ULONG:
  572.                 minutes_           = atol(pTimeBuffer);
  573.                 timeValInMillisec += minutes_*60000; //minutes to msec
  574.                 break; //done w/ "minutes_:seconds_[milliseconds_]" part.
  575.             }
  576.         }
  577.     }
  578.     if(bColonWasFound) //then get the "hours" part:
  579.     {
  580.         bColonWasFound = FALSE;
  581.         //We've got the ":minutes.seconds.msec" part, so lets get the hours:
  582.         for(bufIndx--; 0L <= bufIndx; bufIndx--)
  583.         {
  584.             char ch = toupper(pTimeBuffer[bufIndx]);
  585.             if('0' > ch  ||  '9' < ch)
  586.             {
  587.                 if(' ' == ch  ||  '.' == ch)
  588.                 {
  589.                     break;
  590.                 }
  591.                 else if(':' == ch)
  592.                 {
  593.                     bColonWasFound = TRUE;
  594.                     //previous found was minutes_, so translate into ULONG:
  595.                     // (Note: this will do atol("hrs:min:sec") which ignores
  596.                     // everything at & beyond the first non-num (":") char):
  597.                     hours_             = atol(&pTimeBuffer[bufIndx + 1L]);
  598.                     timeValInMillisec += hours_ * 3600000; //hours to msec
  599.                     break;//done w/ "hours_:minutes_:seconds_[milliseconds_]"
  600.                 }
  601.                 else  //unexpected char found, so quit parsing:
  602.                 {
  603.                     //Make sure pTimeBuffer is in original state:
  604.                     if(endCharWasChanged)
  605.                     {
  606.                         timeBufferLen++;
  607.                         pTimeBuffer[timeBufferLen-1] = savedEndChar;
  608.                     }
  609.                     if(indexOfDot >= 0)
  610.                     {
  611.                         pTimeBuffer[indexOfDot] = '.';
  612.                     }
  613.                     //this char is unexpected, so return FALSE with
  614.                     //  timeValInMillisec set to whatever was read so far:
  615.                     return FALSE;
  616.                 }
  617.             }
  618.             else if(0L == bufIndx) //we're done with the buffer:
  619.             {
  620.                 //previous found was seconds_, so translate into ULONG:
  621.                 hours_             = atol(pTimeBuffer);
  622.                 timeValInMillisec += hours_ * 3600000; //hours to msec
  623.                 break; //done w/ "hours_:minutes_:seconds_[milliseconds_]".
  624.             }
  625.         }
  626.     }
  627.     if(bColonWasFound) //then get the "days" part:
  628.     {
  629.         bColonWasFound = FALSE;
  630.         //We've got the "hours:minutes.seconds.msec" part, so lets get the days:
  631.         for(bufIndx--; 0L <= bufIndx; bufIndx--)
  632.         {
  633.             char ch = toupper(pTimeBuffer[bufIndx]);
  634.             if('0' > ch  ||  '9' < ch)
  635.             {
  636.                 if(' ' == ch  ||  '.' == ch)
  637.                 {
  638.                     break;
  639.                 }
  640.                 else if(':' == ch)
  641.                 {
  642.                     bColonWasFound = TRUE;
  643.                     //previous found was minutes_, so translate into ULONG:
  644.                     // (Note: this will do atol("hrs:min:sec") which ignores
  645.                     // everything at & beyond the first non-num (":") char):
  646.                     days_              = atol(&pTimeBuffer[bufIndx+1L]);
  647.                     timeValInMillisec += days_ * 86400000; //days to msec
  648.                     break;//done w/ "days_:hours_:minutes_:seconds_[msecs_]"
  649.                 }
  650.                 else  //unexpected char found, so quit parsing:
  651.                 {
  652.                     //Make sure pTimeBuffer is in original state:
  653.                     if(endCharWasChanged)
  654.                     {
  655.                         timeBufferLen++;
  656.                         pTimeBuffer[timeBufferLen - 1] = savedEndChar;
  657.                     }
  658.                     if(indexOfDot >= 0)
  659.                     {
  660.                         pTimeBuffer[indexOfDot] = '.';
  661.                     }
  662.                     //this char is unexpected, so return FALSE with
  663.                     //  timeValInMillisec set to whatever was read so far:
  664.                     return FALSE;
  665.                 }
  666.             }
  667.             else if(0L == bufIndx) //we're done with the buffer:
  668.             {
  669.                 //previous found was seconds_, so translate into ULONG:
  670.                 hours_             = atol(pTimeBuffer);
  671.                 timeValInMillisec += hours_ * 86400000; //days to msec
  672.                 break; //done w/ "days_:hours_:minutes_:seconds_[msec_]".
  673.             }
  674.         }
  675.     }
  676.     if(endCharWasChanged)
  677.     {
  678.         timeBufferLen++;
  679.         //Restore the orignial pTimeBuffer, in case end quote char was removed:
  680.         pTimeBuffer[timeBufferLen - 1] = savedEndChar;
  681.     }
  682.     if(indexOfDot >= 0)
  683.     {
  684.         pTimeBuffer[indexOfDot] = '.';
  685.     }
  686.     return TRUE;
  687. }
  688. BOOL IsURLRelative(const char* pszURL)
  689. {
  690.     BOOL   bRelative = TRUE;
  691.     CHXURL cFullURL(pszURL);
  692.     if (cFullURL.GetLastError() == HXR_OK)
  693.     {
  694.         IHXValues* pHeader = cFullURL.GetProperties();
  695.         if (pHeader)
  696.         {
  697.             IHXBuffer *pDummy = NULL;
  698.             HX_RESULT   retVal = pHeader->GetPropertyBuffer(PROPERTY_SCHEME, pDummy);
  699.             if (retVal != HXR_OK)
  700.             {
  701.                 // If we do NOT have a PROPERTY_SCHEME property, then we are relative.
  702.                 bRelative = TRUE;
  703.             }
  704.             else
  705.             {
  706.                 bRelative = FALSE;
  707.             }
  708.             HX_RELEASE(pDummy);
  709.         }
  710.         HX_RELEASE(pHeader);
  711.     }
  712.     return bRelative;
  713. }
  714. HX_RESULT MakeAbsoluteURL(const CHXString& rOrigURL, const CHXString& rRelURL, CHXString& rAbsURL)
  715. {
  716.     // Create the CHXURL object
  717.     CHXURL     cURLObj((const char*) rOrigURL);
  718.     IHXValues* pHeader = cURLObj.GetProperties();
  719.     if(!pHeader)
  720.     {
  721.         return HXR_FAIL;
  722.     }
  723.     // Initialize the output string
  724.     rAbsURL.Empty();
  725.     // Get the scheme
  726.     IHXBuffer* pBuffer = NULL;
  727.     HX_RESULT   retVal = pHeader->GetPropertyBuffer(PROPERTY_SCHEME, pBuffer);
  728.     if (retVal == HXR_OK)
  729.     {
  730.         rAbsURL = (const char*) pBuffer->GetBuffer();
  731.         rAbsURL += "://";
  732.         HX_RELEASE(pBuffer);
  733.     }
  734.     // Get the host
  735.     BOOL bHasHost = FALSE;
  736.     retVal        = pHeader->GetPropertyBuffer(PROPERTY_HOST, pBuffer);
  737.     if (retVal == HXR_OK)
  738.     {
  739.         rAbsURL += (const char*) pBuffer->GetBuffer();
  740.         HX_RELEASE(pBuffer);
  741.         bHasHost = TRUE;
  742.     }
  743.     
  744.     // Get the port
  745.     UINT32 ulPort;
  746.     retVal = pHeader->GetPropertyULONG32(PROPERTY_PORT, ulPort);
  747.     if (retVal == HXR_OK)
  748.     {
  749.         char szTemp[16]; /* Flawfinder: ignore */
  750.         sprintf(szTemp, ":%d", (UINT16) ulPort); /* Flawfinder: ignore */
  751.         rAbsURL += szTemp;
  752.     }
  753.     if(bHasHost)
  754.     {
  755.         rAbsURL += "/";
  756.     }
  757.     retVal = pHeader->GetPropertyBuffer(PROPERTY_RESOURCE, pBuffer);
  758.     if (retVal == HXR_OK)
  759.     {
  760.         const char* pResource   = (const char*)pBuffer->GetBuffer();
  761.         const char  cDelimiter1 = '/';
  762.         const char  cDelimiter2 = '\';
  763.         CHXString   strURLWork = pResource; 
  764.         char*       pFirstChar = strURLWork.GetBuffer(strURLWork.GetLength());
  765.         char*       pLastChar  = NULL;
  766.         char*       pOptions   = NULL;
  767.         char*       pFragment  = NULL;
  768.         pOptions = strchr(pFirstChar, '?');
  769.         if (pOptions)
  770.         {
  771.             pLastChar = pOptions - 1;
  772.         }
  773.         else
  774.         {
  775.             pLastChar = pFirstChar + strlen(pFirstChar) - 1;
  776.         }
  777.         while ((pLastChar > pFirstChar) && (*pLastChar != cDelimiter1) && (*pLastChar != cDelimiter2))
  778.         {
  779.             pLastChar--;
  780.         }
  781.         // If we hit a delimiter before hitting the end, back up one character!
  782.         if(pLastChar > pFirstChar) 
  783.         {
  784.             *(++pLastChar) = '';
  785.             rAbsURL += pFirstChar;
  786.         }
  787.         HX_RELEASE(pBuffer);
  788.     }
  789.     HX_RELEASE(pHeader);
  790.     // Now tack on the relative URL
  791.     rAbsURL += rRelURL;
  792.     return HXR_OK;
  793. }
  794. HX_RESULT AddURLOrRequestParam(IHXRequest* pRequest, const char* pszParamName,
  795.                                IUnknown* pContext, IHXValues* pValues)
  796. {
  797.     HX_RESULT retVal = HXR_OK;
  798.     if (pRequest && pszParamName && pValues)
  799.     {
  800.         IHXBuffer* pBuf = NULL;
  801.         HX_RESULT rv = PXUtilities::GetURLOrRequestParam(pRequest, FALSE, pContext,
  802.                                                          pszParamName, pBuf);
  803.         if (SUCCEEDED(rv))
  804.         {
  805.             retVal = pValues->SetPropertyCString(pszParamName, pBuf);
  806.         }
  807.         HX_RELEASE(pBuf);
  808.     }
  809.     else
  810.     {
  811.         retVal = HXR_FAIL;
  812.     }
  813.     return retVal;
  814. }