📄 strlist.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*--
Module Name: strlist.cpp
Abstract: Helper for dict class
--*/
#include "aspmain.h"
/////////////////////////////////////////////////////////////////////////////
// CRequestStrList
CRequestStrList::CRequestStrList()
{
m_pszPath = m_pszDomain = NULL;
m_pwszArray = NULL;
m_pASPState = 0;
m_wszData = 0;
m_nEntries = 0;
m_dictType = QUERY_STRING_TYPE;
m_dateExpires = 0;
}
CRequestStrList * CreateCRequestStrList(CASPState *pASPState,
WCHAR *wszInitialString, DICT_TYPE dt)
{
CRequestStrList *pStrList = NULL;
if (FAILED (CoCreateInstance(CLSID_RequestStrList,NULL,CLSCTX_INPROC_SERVER,IID_IRequestStrList,(void**) &pStrList)))
return NULL;
pStrList->m_wszData = wszInitialString;
pStrList->m_nEntries = wszInitialString ? 1 : 0;
pStrList->m_pASPState = pASPState;
pStrList->m_dictType = dt;
return pStrList;
}
CRequestStrList::~CRequestStrList()
{
int i;
MyFree(m_wszData);
if (m_nEntries > 1)
{
for (i = 0; i < m_nEntries; i++)
MyFree(m_pwszArray[i]);
MyFree(m_pwszArray);
}
MyFree(m_pszDomain);
MyFree(m_pszPath);
}
// This is called for sub-indexed values. For instance,
// on Request.Form("Foo")(1), the Request.Form("Foo") will return a CRequestStrList
// object, which will be called with the argument (1) in this fcn.
STDMETHODIMP CRequestStrList::get_Item(VARIANT varKey, VARIANT* pvarReturn)
{
DEBUG_CODE_INIT;
VARIANT *pvarKey = &varKey;
BSTR bstr = NULL; // LATER -- remove
WCHAR *wszTempBuf = NULL;
WCHAR *wszTrav = NULL;
HRESULT ret = DISP_E_EXCEPTION;
DWORD vt;
LONG lCodePage = (m_dictType == REQUEST_COOKIE_TYPE) ? CP_ACP : m_pASPState->m_lCodePage;
VariantInit(pvarReturn);
// Use VariantResolveDispatch which will:
//
// * Copy BYREF variants for us using VariantCopyInd
// * handle E_OUTOFMEMORY for us
// * get the default value from an IDispatch, which seems
// like an appropriate conversion.
//
VARIANT varKeyCopy;
VariantInit(&varKeyCopy);
vt = V_VT(pvarKey);
if ((vt != VT_BSTR) && (vt != VT_I2) && (vt != VT_I4))
{
if (FAILED(VariantResolveDispatch(&varKeyCopy, &varKey)))
{
ASP_ERR(IDS_E_PARSER);
myleave(811);
}
pvarKey = &varKeyCopy;
}
vt = V_VT(pvarKey);
switch (vt)
{
case VT_I1: case VT_I2: case VT_I8:
case VT_UI1: case VT_UI2: case VT_UI4: case VT_UI8:
case VT_R4: case VT_R8:
// Coerce all integral types to VT_I4
if (FAILED(VariantChangeTypeEx(pvarKey, pvarKey, lCodePage, 0, VT_I4)))
myleave(821);
vt = VT_I4;
}
// Access the string data itself if vt == VT_ERROR.
// If there are multiple fields of the same name, print them out in a
// comma separated list. IE if Request.Post("Names") that had N fields,
// return as output "Name1, Name2, ..., NameN"
if ( VT_ERROR == vt)
{
if (m_nEntries == 0) // do nothing, empty string
;
else if (m_nEntries == 1) // just one entry in this object
{
if (NULL == (bstr = SysAllocString(m_wszData)))
{
ASP_ERR(IDS_E_NOMEM);
myleave(822);
}
}
else // create the comma separated list
{
int i;
int iOutput = 0;
// Finds out how big a buffer we need.
for (i = 0; i < m_nEntries; i++)
{
iOutput += wcslen(m_pwszArray[i]) + 2;
}
// put into an ANSI string first
if (NULL == (wszTempBuf = MyRgAllocNZ(WCHAR, iOutput)))
{
ASP_ERR(IDS_E_NOMEM);
myleave(823);
}
wszTrav = wszTempBuf;
// run through the list, copying string over.
for (i = 0; i < m_nEntries; i++)
{
wcscpy(wszTrav,m_pwszArray[i]);
wszTrav += wcslen(m_pwszArray[i]);
// Put the sepearating ", " in the string on all but last elem in list
if (i != m_nEntries - 1)
{
wszTrav[0] = L',';
wszTrav[1] = L' ';
wszTrav += 2;
}
}
if (NULL == (bstr = SysAllocString(wszTempBuf)))
{
ASP_ERR(IDS_E_NOMEM);
myleave(824);
}
}
V_VT(pvarReturn) = VT_BSTR;
V_BSTR(pvarReturn) = bstr;
} // VT_NULL
// In this case we get just 1 string if possible, ie
// Request.Form("Names")(j) returns "NameJ"
else if ( VT_I4 == vt)
{
int iIndex = V_I4(pvarKey);
if (iIndex <= 0 ||
iIndex > m_nEntries)
{
ASP_ERR(IDS_E_BAD_INDEX);
myleave(825);
}
if (m_nEntries == 1)
{
if (NULL == (bstr = SysAllocString(m_wszData)))
{
ASP_ERR(IDS_E_NOMEM);
myleave(826);
}
}
else
{
if (NULL == (bstr = SysAllocString(m_pwszArray[iIndex - 1])))
{
ASP_ERR(IDS_E_NOMEM);
myleave(827);
}
}
V_VT(pvarReturn) = VT_BSTR;
V_BSTR(pvarReturn) = bstr;
}
// NOTE: this could with vt = VT_BSTR in the case:
// variable = Response.Cookies("Value")("Index").
// IIS ASP does support this Cookies collections only. CE does not, in order to keep code smaller.
else
{
ASP_ERR(IDS_E_BAD_SUBINDEX);
myleave(828);
}
ret = S_OK;
done:
DEBUGMSG_ERR(ZONE_ERROR,(L"ASP: CRequestStrList::get_Item failed, err = %d, GLE=%X\r\n",
err, GetLastError()));
VariantClear(&varKeyCopy);
MyFree(wszTempBuf);
return ret;
}
// NOTE. this could with vt = VT_BSTR in the case:
// Response.Cookies("Value")("Index") = "Value".
// IIS ASP does support this Cookies collections only. WinCE does not to keep code smaller.
STDMETHODIMP CRequestStrList::put_Item(VARIANT varKey, BSTR bstrValue)
{
ASP_ERR(IDS_E_BAD_SUBINDEX);
return DISP_E_EXCEPTION;
}
// Note: Unlike IIS, WinCE does not have support for enumeration on ASP collection objects.
STDMETHODIMP CRequestStrList::get__NewEnum(IUnknown** ppEnumReturn)
{
ASP_ERR(IDS_E_NOT_IMPL);
return DISP_E_EXCEPTION;
}
STDMETHODIMP CRequestStrList::get_Key(VARIANT VarKey, VARIANT* pvar)
{
ASP_ERR(IDS_E_NOT_IMPL);
return DISP_E_EXCEPTION;
}
STDMETHODIMP CRequestStrList::get_Count(int* cStrRet)
{
*cStrRet = m_nEntries;
return S_OK;
}
// AddStringToArray -
// For case x=a&x=b coming from POST or QueryString data this keeps values in
// an array with entries "a" and "b"
// We don't check for repeated entries, ie x=a&x=a, each of them get a separate
// entry in the array.
BOOL CRequestStrList::AddStringToArray(WCHAR *wszData)
{
// We only store 1 value with Cookies. Overwrite value if one exists already.
// (or if this is first element being put into array, use m_wszData
// rather than allocating an array)
if (m_dictType == RESPONSE_COOKIE_TYPE ||
m_dictType == REQUEST_COOKIE_TYPE ||
0 == m_nEntries)
{
MyFree(m_wszData);
m_wszData = wszData;
m_nEntries = 1;
return TRUE;
}
// If exactly 1 element in the array, adding a 2nd requires to do initial
// allocation of the array.
if (m_nEntries == 1)
{
m_pwszArray = MyRgAllocZ(WCHAR *,VALUE_GROW_SIZE);
if (NULL == m_pwszArray)
{
ASP_ERR(IDS_E_NOMEM);
return FALSE;
}
m_pwszArray[0] = m_wszData;
m_wszData = NULL; // so we know which one to dealloc
}
// time to reallocate memory.
if (m_nEntries % VALUE_GROW_SIZE == 0)
{
m_pwszArray = MyRgReAlloc(PWSTR, m_pwszArray,m_nEntries,VALUE_GROW_SIZE + m_nEntries);
if (NULL == m_pwszArray)
{
ASP_ERR(IDS_E_NOMEM);
return FALSE;
}
}
m_pwszArray[m_nEntries] = wszData;
m_nEntries++;
return TRUE;
}
STDMETHODIMP CRequestStrList::get_HasKeys(VARIANT_BOOL *pfHasKeys)
{
*pfHasKeys = (m_nEntries >= 1);
return S_OK;
}
STDMETHODIMP CRequestStrList::put_Expires(DATE dtExpires)
{
if ( RESPONSE_COOKIE_TYPE != m_dictType )
{
ASP_ERR(IDS_E_READ_ONLY)
return DISP_E_EXCEPTION;
}
m_dateExpires = dtExpires;
return S_OK;
}
STDMETHODIMP CRequestStrList::put_Domain( BSTR bstrDomain)
{
if ( RESPONSE_COOKIE_TYPE != m_dictType )
{
ASP_ERR(IDS_E_READ_ONLY)
return DISP_E_EXCEPTION;
}
// Codepage note: Since this is an http header we convert into an ANSI, not DBCS
MyFree(m_pszDomain);
if ( NULL == (m_pszDomain = MySzDupWtoA(bstrDomain)))
{
ASP_ERR(IDS_E_NOMEM);
return DISP_E_EXCEPTION;
}
return S_OK;
}
STDMETHODIMP CRequestStrList::put_Path( BSTR bstrPath)
{
if ( RESPONSE_COOKIE_TYPE != m_dictType )
{
ASP_ERR(IDS_E_READ_ONLY)
return DISP_E_EXCEPTION;
}
// Codepage note: Since this is an http header we convert into an ANSI, not DBCS
MyFree(m_pszPath);
if ( NULL == (m_pszPath = MySzDupWtoA(bstrPath)))
{
ASP_ERR(IDS_E_NOMEM);
return DISP_E_EXCEPTION;
}
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -