parseurl.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:29k
- /* ***** BEGIN LICENSE BLOCK *****
- * Source last modified: $Id: parseurl.cpp,v 1.1.26.1 2004/07/09 01:54:47 hubbe Exp $
- *
- * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file,
- * are subject to the current version of the RealNetworks Public
- * Source License (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the current version of the RealNetworks Community
- * Source License (the "RCSL") available at
- * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
- * will apply. You may also obtain the license terms directly from
- * RealNetworks. You may not use this file except in compliance with
- * the RPSL or, if you have a valid RCSL with RealNetworks applicable
- * to this file, the RCSL. Please see the applicable RPSL or RCSL for
- * the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL") in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your version of
- * this file only under the terms of the GPL, and not to allow others
- * to use your version of this file under the terms of either the RPSL
- * or RCSL, indicate your decision by deleting the provisions above
- * and replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient may
- * use your version of this file under the terms of any one of the
- * RPSL, the RCSL or the GPL.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the
- * portions it created.
- *
- * This file, and the files included with this file, is distributed
- * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
- * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
- * ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- // From include
- #include <ctype.h>
- #include "hxtypes.h"
- #include "hxwintyp.h"
- #include "hxcom.h"
- #include "hxresult.h"
- #include "ihxpckts.h"
- #include "hxcomm.h"
- // From hxcont
- #include "hxstring.h"
- #include "chxpckts.h"
- // From hxmisc
- #include "hxurl.h"
- #include "unkimp.h"
- #include "baseobj.h"
- #include "hxparse.h"
- // From pxcomlib
- #include "gstring.h"
- #include "pxutil.h"
- #include "pxcolor.h"
- #include "pxrect.h"
- #include "pxeffect.h"
- #include "buffutil.h"
- #include "parseurl.h"
- #ifdef _MACINTOSH
- #include <ctype.h> // For toupper on the Macintosh.
- #include <stdlib.h> // for atol
- #endif
- // hxdebug
- #include "hxheap.h"
- #ifdef _DEBUG
- #undef HX_THIS_FILE
- static char HX_THIS_FILE[] = __FILE__;
- #endif
- HX_RESULT ParseURLEncoding(IHXCommonClassFactory *pFactory, const char *pszURL, IHXValues **ppValues)
- {
- // Check for input errors
- if (!pFactory || !pszURL)
- {
- return HXR_FAIL;
- }
- // Create an IHXValues object
- IHXValues *pValues = NULL;
- HX_RESULT retVal = pFactory->CreateInstance(CLSID_IHXValues, (void **) &pValues);
- if (retVal != HXR_OK)
- {
- return retVal;
- }
- *ppValues = pValues;
- // Get a string class with the URL in it
- GString cURL = pszURL;
- // Get the length
- INT32 lURLLen = strlen(pszURL);
- // Look for the beginning of the parameter string
- INT32 lPos = cURL.find('?');
- if (lPos < 0)
- {
- return HXR_OK;
- }
- // Now we go into a loop looking for attribute/value pairs
- for(;;)
- {
- // Set the beginning of the attribute
- INT32 lAttributeLeftPos = lPos + 1;
- // Look for the end of the attribute
- lPos = cURL.find('=', lPos);
- if (lPos < 0)
- {
- break;
- }
- // Set the inclusive end of the attribute
- INT32 lAttributeRightPos = lPos - 1;
- INT32 lValueLeftPos = lPos + 1;
- INT32 lValueRightPos;
- // Make sure we don't have a situation like "foo.jpg?bitrate="
- if (lValueLeftPos >= lURLLen)
- {
- break;
- }
- // Now look for the separator
- lPos = cURL.find('&', lPos);
- if (lPos < 0)
- {
- // We didn't find the separator, so we assume the end of
- // the string is the end of the value
- lValueRightPos = cURL.length() - 1;
- lPos = lValueRightPos;
- }
- else
- {
- lValueRightPos = lPos - 1;
- }
- // Check to see if we have valid strings for our attribute and value
- if (lAttributeRightPos >= lAttributeLeftPos &&
- lValueRightPos >= lValueLeftPos)
- {
- GString cAttribute = cURL.substr(lAttributeLeftPos, lAttributeRightPos);
- GString cValue = cURL.substr(lValueLeftPos, lValueRightPos);
- // Create an IHXBuffer
- IHXBuffer *pBuffer = NULL;
- retVal = pFactory->CreateInstance(CLSID_IHXBuffer, (void **) &pBuffer);
- if (retVal != HXR_OK)
- {
- HX_RELEASE(pValues);
- *ppValues = NULL;
- return retVal;
- }
- // Set value string into the buffer
- retVal = pBuffer->Set((const BYTE *) cValue.c_str(), cValue.length() + 1);
- if (retVal != HXR_OK)
- {
- HX_RELEASE(pBuffer);
- HX_RELEASE(pValues);
- *ppValues = NULL;
- return retVal;
- }
- // Set the attribute/value pair
- retVal = pValues->SetPropertyCString(cAttribute.c_str(), pBuffer);
- if (retVal != HXR_OK)
- {
- HX_RELEASE(pBuffer);
- HX_RELEASE(pValues);
- *ppValues = NULL;
- return retVal;
- }
- // Release our reference on the buffer
- HX_RELEASE(pBuffer);
- }
- }
- return HXR_OK;
- }
- HX_RESULT ExtractValueTime(IHXValues *pValues, const char *pszAttr, UINT32 ulDefault, UINT32 &rulValue)
- {
- IHXBuffer *pStringBuf = NULL;
- HX_RESULT retVal = pValues->GetPropertyCString(pszAttr, pStringBuf);
- if (retVal != HXR_OK)
- {
- // No attribute was specified, so take the default
- rulValue = ulDefault;
- return HXR_OK;
- }
- // An attribute was specified so use it
- char *pszStr = (char *) pStringBuf->GetBuffer();
- UINT32 ulStrLen = strlen(pszStr);
- BOOL bRet = ConvertTimeStringToULONG32(pszStr, ulStrLen, rulValue);
- if (bRet == FALSE)
- {
- HX_RELEASE(pStringBuf);
- return HXR_FAIL;
- }
- HX_RELEASE(pStringBuf);
- return HXR_OK;
- }
- HX_RESULT ExtractValueUINT32(IHXValues *pValues, const char *pszAttr, UINT32 ulDefault, UINT32 &rulValue)
- {
- IHXBuffer *pStringBuf = NULL;
- HX_RESULT retVal = pValues->GetPropertyCString(pszAttr, pStringBuf);
- if (retVal != HXR_OK)
- {
- // No attribute was specified, so take the default
- rulValue = ulDefault;
- return HXR_OK;
- }
- // An attribute was specified so use it
- rulValue = (UINT32) atol((char *) pStringBuf->GetBuffer());
- // Release the buffer
- HX_RELEASE(pStringBuf);
- return HXR_OK;
- }
- HX_RESULT ExtractValueBOOL(IHXValues *pValues, const char *pszAttr, BOOL bDefault, BOOL &rbValue)
- {
- IHXBuffer *pStringBuf = NULL;
- HX_RESULT retVal = pValues->GetPropertyCString(pszAttr, pStringBuf);
- if (retVal != HXR_OK)
- {
- // No attribute was specified, so take the default
- rbValue = bDefault;
- return HXR_OK;
- }
- // An attribute was specified so use it
- char *pVal = (char *) pStringBuf->GetBuffer();
- if (!strcmp(pVal, "true"))
- {
- rbValue = TRUE;
- }
- else if (!strcmp(pVal, "false"))
- {
- rbValue = FALSE;
- }
- else
- {
- rbValue = bDefault;
- HX_RELEASE(pStringBuf);
- return HXR_FAIL;
- }
- // Release the buffer
- HX_RELEASE(pStringBuf);
- return HXR_OK;
- }
- HX_RESULT ExtractValueString(IHXValues *pValues, const char *pszAttr, const char *pszDefault, CHXString &rcValue)
- {
- IHXBuffer* pStringBuf = NULL;
- HX_RESULT retVal = pValues->GetPropertyCString(pszAttr, pStringBuf);
- if (retVal != HXR_OK)
- {
- // No attribute was specified, so take the default
- if (pszDefault)
- {
- rcValue = pszDefault;
- }
- return HXR_OK;
- }
- // An attribute was specified so use it
- rcValue = (const char*) pStringBuf->GetBuffer();
- // Release the value buffer
- HX_RELEASE(pStringBuf);
- return HXR_OK;
- }
- HX_RESULT ExtractValueString(IHXValues *pValues, const char *pszAttr, const char *pszDefault, GString &rcValue)
- {
- IHXBuffer *pStringBuf = NULL;
- HX_RESULT retVal = pValues->GetPropertyCString(pszAttr, pStringBuf);
- if (retVal != HXR_OK)
- {
- // No attribute was specified, so take the default
- if (pszDefault)
- {
- rcValue = pszDefault;
- }
- else
- {
- rcValue = "";
- }
- return HXR_OK;
- }
- // An attribute was specified so use it
- rcValue.CopyN(pStringBuf->GetBuffer(), pStringBuf->GetSize());
- // Release the value buffer
- HX_RELEASE(pStringBuf);
- return HXR_OK;
- }
- HX_RESULT ExtractValueColor(IHXValues *pValues, const char *pszAttr, const char *pszDefault, PXColor &rcValue)
- {
- IHXBuffer *pStringBuf = NULL;
- HX_RESULT retVal = pValues->GetPropertyCString(pszAttr, pStringBuf);
- GString cColor;
- if (retVal != HXR_OK)
- {
- cColor = pszDefault;
- }
- else
- {
- // An attribute was specified so use it
- cColor.CopyN(pStringBuf->GetBuffer(), pStringBuf->GetSize());
- // Release the value buffer
- HX_RELEASE(pStringBuf);
- }
- // Now convert the color
- retVal = rcValue.InitFromString(cColor.c_str());
- if (retVal != HXR_OK)
- {
- return retVal;
- }
- return HXR_OK;
- }
- HX_RESULT ExtractValueColor(IHXValues *pValues, const char *pszAttr, UINT32 ulDefault, UINT32& rulValue)
- {
- IHXBuffer* pStringBuf = NULL;
- HX_RESULT retVal = pValues->GetPropertyCString(pszAttr, pStringBuf);
- if (retVal != HXR_OK)
- {
- rulValue = ulDefault;
- }
- else
- {
- UINT32 ulTmp = ulDefault;
- retVal = HXParseColorUINT32((const char*) pStringBuf->GetBuffer(),
- ulTmp);
- if (SUCCEEDED(retVal))
- {
- rulValue = ulTmp;
- }
- else
- {
- rulValue = ulDefault;
- }
- // Release the value buffer
- HX_RELEASE(pStringBuf);
- }
- return HXR_OK;
- }
- HX_RESULT ExtractValueOpacity(IHXValues *pValues, const char *pszAttr, UINT32 ulDefault, UINT32& rulValue)
- {
- IHXBuffer *pStringBuf = NULL;
- HX_RESULT retVal = pValues->GetPropertyCString(pszAttr, pStringBuf);
- if (retVal != HXR_OK)
- {
- // No attribute was specified, so take the default
- rulValue = ulDefault;
- return HXR_OK;
- }
- // An attribute was specified so use it
- INT32 lOpacity = 0;
- char* pEndPtr = NULL;
- double dVal = strtod((const char*) pStringBuf->GetBuffer(), &pEndPtr);
- if (pEndPtr && *pEndPtr == '%')
- {
- // Value is a percent
- lOpacity = (INT32) ((dVal * 255.0 / 100.0) + 0.5);
- }
- else
- {
- lOpacity = (INT32) (dVal + 0.5);
- }
- // Range check
- if (lOpacity < 0)
- {
- lOpacity = 0;
- }
- if (lOpacity > 255)
- {
- lOpacity = 255;
- }
- // Assign the out parameter
- rulValue = (UINT32) lOpacity;
- // Release the buffer
- HX_RELEASE(pStringBuf);
- return HXR_OK;
- }
- BOOL ConvertTimeStringToULONG32(char *pTimeBuf, ULONG32 timeBufLen, ULONG32 &timeValInMillisec)
- {
- char *pTimeBuffer = pTimeBuf;
- ULONG32 timeBufferLen = timeBufLen;
- char savedEndChar = ' '; //for restoring '"' char at end, if found.
- LONG32 bufIndx = 0L;
- BOOL bDotEncounteredAlready = FALSE;
- LONG32 indexOfDot = -1;
- BOOL endCharWasChanged = FALSE;
- ULONG32 days_;
- ULONG32 hours_;
- ULONG32 minutes_;
- ULONG32 seconds_;
- ULONG32 milliseconds_;
- // Initialize
- days_ = hours_ = minutes_ = seconds_ = milliseconds_ = 0L;
- timeValInMillisec=0;
- // Check for input error
- if(!pTimeBuffer || timeBufLen < MIN_TIMEBUFFERLENGTH)
- {
- return FALSE;
- }
- savedEndChar = pTimeBuffer[timeBufferLen-1];
- //Get rid of start & terminating quotation mark, if they exist:
- if(pTimeBuffer[0] == '"')
- {
- pTimeBuffer++;
- timeBufferLen--;
- //Added this check to kill bug if (pTimeBuffer==")
- // and got shortened to an empty string:
- if(!timeBufferLen)
- {
- return FALSE;
- }
- }
- if(pTimeBuffer[timeBufferLen - 1] == '"')
- {
- pTimeBuffer[timeBufferLen - 1] = ' '; //get rid of end '"'.
- timeBufferLen--;
- endCharWasChanged = TRUE;
- }
-
- // Work from right to left, searching first for milliseconds and then for
- // seconds (or seconds only if no '.' found):
- BOOL bColonWasFound = FALSE;
- for(bufIndx=timeBufferLen-1; 0L<=bufIndx; bufIndx--)
- {
- char ch = toupper(pTimeBuffer[bufIndx]);
- if('0' > ch || '9' < ch)
- {
- if(' '==ch || 't'==ch || 'n'==ch || 'r'==ch)
- {
- //Added everything up to "break;" to
- // handle (valid) strings with leading space(s) like " 39":
- //previous found was seconds_, so translate into ULONG:
- seconds_ = atol(&pTimeBuffer[bufIndx+1L]);
- timeValInMillisec += seconds_*1000; //converts seconds to ms.
- break; //we're done; we found seconds only.
- }
- else if('.' == ch)
- {
- if(bDotEncounteredAlready)
- {
- //Make sure pTimeBuffer is in original state:
- if(endCharWasChanged)
- {
- timeBufferLen++;
- pTimeBuffer[timeBufferLen-1] = savedEndChar;
- }
- if(indexOfDot >= 0)
- {
- pTimeBuffer[indexOfDot] = '.';
- }
- //this second '.' is unexpected, so return with
- // timeValInMillisec set to whatever was read so far:
- return FALSE;
- }
- bDotEncounteredAlready = TRUE;
- indexOfDot = bufIndx;
- pTimeBuffer[bufIndx] = ' '; //end the buffr at the '.' .
- //previously-read #'s are milliseconds, so count them:
- //added "-1" to fix bug if buf ends with ".":
- if(1L > timeBufferLen-bufIndx - 1)
- {
- milliseconds_ = 0L;
- }
- else
- {
- //Now, make sure that more than three digits (base 10)
- // are not present, e.g., reduce "46371" to "463" since
- // we only allow millisecond precision (3 digits past
- // the decimal point:
- char chTmp = ' ';
- ULONG32 ulNumDecimalDigitsFound = timeBufferLen-1 - bufIndx;
- if(NUM_DECIMAL_DIGITS_OF_SECONDS < ulNumDecimalDigitsFound)
- {
- chTmp = pTimeBuffer[bufIndx + 1L];
- pTimeBuffer[bufIndx+NUM_DECIMAL_DIGITS_OF_SECONDS+1] = ' ';
- }
- milliseconds_ = atol(&pTimeBuffer[bufIndx+1L]);
- //Added this to fix "y.x" being converted
- // to y00x instead of yx00 milliseconds:
- if(ulNumDecimalDigitsFound < NUM_DECIMAL_DIGITS_OF_SECONDS)
- {
- for(ULONG32 ulDiff= NUM_DECIMAL_DIGITS_OF_SECONDS - ulNumDecimalDigitsFound; ulDiff > 0; ulDiff--)
- {
- milliseconds_ *= 10;
- }
- }
- if(NUM_DECIMAL_DIGITS_OF_SECONDS < ulNumDecimalDigitsFound)
- {
- //restore the changed char in the pTimeBuffer:
- pTimeBuffer[bufIndx+ NUM_DECIMAL_DIGITS_OF_SECONDS + 1] = chTmp;
- }
- }
-
- timeValInMillisec = milliseconds_;
- }
- else if(':' == ch)
- {
- bColonWasFound = TRUE;
- //previous found was seconds_, so translate into ULONG:
- seconds_ = atol(&pTimeBuffer[bufIndx + 1L]);
- timeValInMillisec += seconds_ * 1000; //converts seconds to ms.
- break; //done with "seconds_[.milliseconds_]" part.
- }
- else //unexpected char found, so quit parsing:
- {
- //Make sure pTimeBuffer is in original state:
- if(endCharWasChanged)
- {
- timeBufferLen++;
- pTimeBuffer[timeBufferLen - 1] = savedEndChar;
- }
- if(indexOfDot >= 0)
- {
- pTimeBuffer[indexOfDot] = '.';
- }
- //this char is unexpected, so return FALSE with
- // timeValInMillisec set to whatever was read so far:
- return FALSE;
- }
- }
- else if(0L == bufIndx) //we're done with the buffer:
- {
- //previous found was seconds_, so translate into ULONG:
- seconds_ = atol(pTimeBuffer);
- timeValInMillisec += seconds_*1000; //converts seconds to ms.
- break; //done with "seconds_[.milliseconds_]" part.
- }
- }
- if(bColonWasFound) //then get the "minutes" part:
- {
- bColonWasFound = FALSE;
- // We've got the ":seconds.msecs" part, so lets get the hours part:
- for(bufIndx--; 0L<=bufIndx; bufIndx--)
- {
- char ch = toupper(pTimeBuffer[bufIndx]);
- if('0' > ch || '9' < ch)
- {
- if(' ' == ch || '.' == ch)
- {
- break;
- }
- else if(':' == ch)
- {
- bColonWasFound = TRUE;
- //previous found was seconds_, so translate into ULONG:
- // (Note: this will do atol("min:sec") which ignores
- // everything at & beyond the first non-num (":") char):
- minutes_ = atol(&pTimeBuffer[bufIndx+1L]);
- timeValInMillisec += minutes_*60000; //minutes to msec
- break; //done w/ "minutes_:seconds_[milliseconds_]" part.
- }
- else //unexpected char found, so quit parsing:
- {
- //Make sure pTimeBuffer is in original state:
- if(endCharWasChanged)
- {
- timeBufferLen++;
- pTimeBuffer[timeBufferLen-1] = savedEndChar;
- }
- if(indexOfDot >= 0)
- {
- pTimeBuffer[indexOfDot] = '.';
- }
- //this char is unexpected, so return FALSE with
- // timeValInMillisec set to whatever was read so far:
- return FALSE;
- }
- }
- else if(0L == bufIndx) //we're done with the buffer:
- {
- //previous found was seconds_, so translate into ULONG:
- minutes_ = atol(pTimeBuffer);
- timeValInMillisec += minutes_*60000; //minutes to msec
- break; //done w/ "minutes_:seconds_[milliseconds_]" part.
- }
- }
- }
- if(bColonWasFound) //then get the "hours" part:
- {
- bColonWasFound = FALSE;
- //We've got the ":minutes.seconds.msec" part, so lets get the hours:
- for(bufIndx--; 0L <= bufIndx; bufIndx--)
- {
- char ch = toupper(pTimeBuffer[bufIndx]);
- if('0' > ch || '9' < ch)
- {
- if(' ' == ch || '.' == ch)
- {
- break;
- }
- else if(':' == ch)
- {
- bColonWasFound = TRUE;
- //previous found was minutes_, so translate into ULONG:
- // (Note: this will do atol("hrs:min:sec") which ignores
- // everything at & beyond the first non-num (":") char):
- hours_ = atol(&pTimeBuffer[bufIndx + 1L]);
- timeValInMillisec += hours_ * 3600000; //hours to msec
- break;//done w/ "hours_:minutes_:seconds_[milliseconds_]"
- }
- else //unexpected char found, so quit parsing:
- {
- //Make sure pTimeBuffer is in original state:
- if(endCharWasChanged)
- {
- timeBufferLen++;
- pTimeBuffer[timeBufferLen-1] = savedEndChar;
- }
- if(indexOfDot >= 0)
- {
- pTimeBuffer[indexOfDot] = '.';
- }
- //this char is unexpected, so return FALSE with
- // timeValInMillisec set to whatever was read so far:
- return FALSE;
- }
- }
- else if(0L == bufIndx) //we're done with the buffer:
- {
- //previous found was seconds_, so translate into ULONG:
- hours_ = atol(pTimeBuffer);
- timeValInMillisec += hours_ * 3600000; //hours to msec
- break; //done w/ "hours_:minutes_:seconds_[milliseconds_]".
- }
- }
- }
- if(bColonWasFound) //then get the "days" part:
- {
- bColonWasFound = FALSE;
- //We've got the "hours:minutes.seconds.msec" part, so lets get the days:
- for(bufIndx--; 0L <= bufIndx; bufIndx--)
- {
- char ch = toupper(pTimeBuffer[bufIndx]);
- if('0' > ch || '9' < ch)
- {
- if(' ' == ch || '.' == ch)
- {
- break;
- }
- else if(':' == ch)
- {
- bColonWasFound = TRUE;
- //previous found was minutes_, so translate into ULONG:
- // (Note: this will do atol("hrs:min:sec") which ignores
- // everything at & beyond the first non-num (":") char):
- days_ = atol(&pTimeBuffer[bufIndx+1L]);
- timeValInMillisec += days_ * 86400000; //days to msec
- break;//done w/ "days_:hours_:minutes_:seconds_[msecs_]"
- }
- else //unexpected char found, so quit parsing:
- {
- //Make sure pTimeBuffer is in original state:
- if(endCharWasChanged)
- {
- timeBufferLen++;
- pTimeBuffer[timeBufferLen - 1] = savedEndChar;
- }
- if(indexOfDot >= 0)
- {
- pTimeBuffer[indexOfDot] = '.';
- }
- //this char is unexpected, so return FALSE with
- // timeValInMillisec set to whatever was read so far:
- return FALSE;
- }
- }
- else if(0L == bufIndx) //we're done with the buffer:
- {
- //previous found was seconds_, so translate into ULONG:
- hours_ = atol(pTimeBuffer);
- timeValInMillisec += hours_ * 86400000; //days to msec
- break; //done w/ "days_:hours_:minutes_:seconds_[msec_]".
- }
- }
- }
- if(endCharWasChanged)
- {
- timeBufferLen++;
- //Restore the orignial pTimeBuffer, in case end quote char was removed:
- pTimeBuffer[timeBufferLen - 1] = savedEndChar;
- }
- if(indexOfDot >= 0)
- {
- pTimeBuffer[indexOfDot] = '.';
- }
- return TRUE;
- }
- BOOL IsURLRelative(const char* pszURL)
- {
- BOOL bRelative = TRUE;
- CHXURL cFullURL(pszURL);
- if (cFullURL.GetLastError() == HXR_OK)
- {
- IHXValues* pHeader = cFullURL.GetProperties();
- if (pHeader)
- {
- IHXBuffer *pDummy = NULL;
- HX_RESULT retVal = pHeader->GetPropertyBuffer(PROPERTY_SCHEME, pDummy);
- if (retVal != HXR_OK)
- {
- // If we do NOT have a PROPERTY_SCHEME property, then we are relative.
- bRelative = TRUE;
- }
- else
- {
- bRelative = FALSE;
- }
- HX_RELEASE(pDummy);
- }
- HX_RELEASE(pHeader);
- }
- return bRelative;
- }
- HX_RESULT MakeAbsoluteURL(const CHXString& rOrigURL, const CHXString& rRelURL, CHXString& rAbsURL)
- {
- // Create the CHXURL object
- CHXURL cURLObj((const char*) rOrigURL);
- IHXValues* pHeader = cURLObj.GetProperties();
- if(!pHeader)
- {
- return HXR_FAIL;
- }
- // Initialize the output string
- rAbsURL.Empty();
- // Get the scheme
- IHXBuffer* pBuffer = NULL;
- HX_RESULT retVal = pHeader->GetPropertyBuffer(PROPERTY_SCHEME, pBuffer);
- if (retVal == HXR_OK)
- {
- rAbsURL = (const char*) pBuffer->GetBuffer();
- rAbsURL += "://";
- HX_RELEASE(pBuffer);
- }
- // Get the host
- BOOL bHasHost = FALSE;
- retVal = pHeader->GetPropertyBuffer(PROPERTY_HOST, pBuffer);
- if (retVal == HXR_OK)
- {
- rAbsURL += (const char*) pBuffer->GetBuffer();
- HX_RELEASE(pBuffer);
- bHasHost = TRUE;
- }
-
- // Get the port
- UINT32 ulPort;
- retVal = pHeader->GetPropertyULONG32(PROPERTY_PORT, ulPort);
- if (retVal == HXR_OK)
- {
- char szTemp[16]; /* Flawfinder: ignore */
- sprintf(szTemp, ":%d", (UINT16) ulPort); /* Flawfinder: ignore */
- rAbsURL += szTemp;
- }
- if(bHasHost)
- {
- rAbsURL += "/";
- }
- retVal = pHeader->GetPropertyBuffer(PROPERTY_RESOURCE, pBuffer);
- if (retVal == HXR_OK)
- {
- const char* pResource = (const char*)pBuffer->GetBuffer();
- const char cDelimiter1 = '/';
- const char cDelimiter2 = '\';
- CHXString strURLWork = pResource;
- char* pFirstChar = strURLWork.GetBuffer(strURLWork.GetLength());
- char* pLastChar = NULL;
- char* pOptions = NULL;
- char* pFragment = NULL;
- pOptions = strchr(pFirstChar, '?');
- if (pOptions)
- {
- pLastChar = pOptions - 1;
- }
- else
- {
- pLastChar = pFirstChar + strlen(pFirstChar) - 1;
- }
- while ((pLastChar > pFirstChar) && (*pLastChar != cDelimiter1) && (*pLastChar != cDelimiter2))
- {
- pLastChar--;
- }
- // If we hit a delimiter before hitting the end, back up one character!
- if(pLastChar > pFirstChar)
- {
- *(++pLastChar) = ' ';
- rAbsURL += pFirstChar;
- }
- HX_RELEASE(pBuffer);
- }
- HX_RELEASE(pHeader);
- // Now tack on the relative URL
- rAbsURL += rRelURL;
- return HXR_OK;
- }
- HX_RESULT AddURLOrRequestParam(IHXRequest* pRequest, const char* pszParamName,
- IUnknown* pContext, IHXValues* pValues)
- {
- HX_RESULT retVal = HXR_OK;
- if (pRequest && pszParamName && pValues)
- {
- IHXBuffer* pBuf = NULL;
- HX_RESULT rv = PXUtilities::GetURLOrRequestParam(pRequest, FALSE, pContext,
- pszParamName, pBuf);
- if (SUCCEEDED(rv))
- {
- retVal = pValues->SetPropertyCString(pszParamName, pBuf);
- }
- HX_RELEASE(pBuf);
- }
- else
- {
- retVal = HXR_FAIL;
- }
- return retVal;
- }