Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

457 lines
9.4 KiB

/*
* V A R . C P P
*
* XML document processing
*
* Copyright 1986-1997 Microsoft Corporation, All Rights Reserved
*/
#include "_xml.h"
// ScVariantTypeFromString()
//
// Returns the variant type associated with a dav datatype string
//
SCODE
ScVariantTypeFromString (LPCWSTR pwszType, USHORT& vt)
{
SCODE sc = S_OK;
// NULL, "string" and "uri"
//
if (!pwszType ||
!_wcsicmp (pwszType, gc_wszDavType_String) ||
!_wcsicmp (pwszType, gc_wszUri))
{
vt = VT_LPWSTR;
}
// integer
//
else if (!_wcsicmp (pwszType, gc_wszDavType_Int))
{
vt = VT_I4;
}
// boolean.tf
//
else if (!_wcsicmp (pwszType, gc_wszDavType_Boolean))
{
vt = VT_BOOL;
}
// float (Floating/Reals)
//
else if (!_wcsicmp (pwszType, gc_wszDavType_Float))
{
vt = VT_R8;
}
// date.iso8601
//
else if (!_wcsicmp (pwszType, gc_wszDavType_Date_ISO8601))
{
vt = VT_FILETIME;
}
else
{
DebugTrace ("ScVariantTypeFromString(): unknown type");
vt = VT_LPWSTR;
sc = S_OK;
}
return sc;
}
// ScVariantValueFromString() ------------------------------------------------
//
// Sets the value of a PROPVARIANT
//
SCODE
ScVariantValueFromString (PROPVARIANT& var, LPCWSTR pwszValue)
{
SCODE sc = S_OK;
LPWSTR pwsz;
SYSTEMTIME st;
switch (var.vt)
{
case VT_LPWSTR:
if (pwszValue)
{
pwsz = static_cast<LPWSTR>(CoTaskMemAlloc(CbSizeWsz(wcslen(pwszValue))));
if (NULL == pwsz)
{
DebugTrace ("ScVariantValueFromString() - CoTaskMemAlloc() failed to allocate %d bytes\n", CbSizeWsz(wcslen(pwszValue)));
sc = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
goto ret;
}
wcscpy (pwsz, pwszValue);
var.pwszVal = pwsz;
}
else
var.pwszVal = NULL;
break;
case VT_I4:
Assert (pwszValue);
var.lVal = _wtoi (pwszValue);
break;
case VT_BOOL:
#pragma warning(disable:4310) // wtypes.h is broken
Assert (pwszValue);
if (!_wcsnicmp (pwszValue, gc_wsz1, 1))
var.boolVal = VARIANT_TRUE;
else if (!_wcsnicmp (pwszValue, gc_wsz0, 1))
var.boolVal = VARIANT_FALSE;
else
{
sc = E_INVALIDARG;
goto ret;
}
break;
#pragma warning(default:4310) // wtypes.h is broken
case VT_R8:
Assert (pwszValue);
var.dblVal = wcstod (pwszValue, NULL);
break;
case VT_FILETIME:
Assert (pwszValue);
memset (&var.filetime, 0, sizeof(FILETIME));
if (!FGetSystimeFromDateIso8601 (pwszValue, &st))
{
sc = E_INVALIDARG;
goto ret;
}
SystemTimeToFileTime (&st, &var.filetime);
break;
default:
Assert (pwszValue);
TrapSz ("ScVariantValueFromString() unknown type");
sc = E_INVALIDARG;
goto ret;
}
ret:
return sc;
}
// ScEmitFromVariant() ------------------------------------------------
//
SCODE
ScEmitFromVariant (CXMLEmitter& emitter,
CEmitterNode& enParent,
LPCWSTR pwszTag,
PROPVARIANT& var)
{
CEmitterNode en;
CStackBuffer<CHAR,110> szBuf;
CStackBuffer<WCHAR,128> wszBuf;
LPCWSTR pwszType = NULL;
LPWSTR pwszValue = NULL;
SCODE sc = S_OK;
SYSTEMTIME st;
UINT cch;
UINT i;
VARIANT* pvarTrue = reinterpret_cast<VARIANT*>(&var);
switch (var.vt)
{
case VT_NULL:
case VT_EMPTY:
break;
case VT_BSTR:
pwszValue = static_cast<LPWSTR>(var.bstrVal);
break;
case VT_LPWSTR:
pwszValue = var.pwszVal;
break;
case VT_LPSTR:
if (!var.pszVal)
break;
cch = static_cast<UINT>(strlen (var.pszVal));
pwszValue = wszBuf.resize(CbSizeWsz(cch));
if (NULL == pwszValue)
{
sc = E_OUTOFMEMORY;
goto ret;
}
// We know that the numbers are in ASCII codepage and we know
// that the buffer size is big enough.
//
cch = MultiByteToWideChar (CP_ACP,
MB_ERR_INVALID_CHARS,
var.pszVal,
cch + 1,
pwszValue,
wszBuf.celems());
if (0 == cch)
{
sc = HRESULT_FROM_WIN32(GetLastError());
Assert(FAILED(sc));
goto ret;
}
break;
case VT_I1:
pwszType = gc_wszDavType_Int;
_itow (pvarTrue->cVal, wszBuf.get(), 10);
pwszValue = wszBuf.get();
break;
case VT_UI1:
pwszType = gc_wszDavType_Int;
_ultow (var.bVal, wszBuf.get(), 10);
pwszValue = wszBuf.get();
break;
case VT_I2:
pwszType = gc_wszDavType_Int;
_itow (var.iVal, wszBuf.get(), 10);
pwszValue = wszBuf.get();
break;
case VT_UI2:
pwszType = gc_wszDavType_Int;
_ultow (var.uiVal, wszBuf.get(), 10);
pwszValue = wszBuf.get();
break;
case VT_I4:
pwszType = gc_wszDavType_Int;
_ltow (var.lVal, wszBuf.get(), 10);
pwszValue = wszBuf.get();
break;
case VT_UI4:
pwszType = gc_wszDavType_Int;
_ultow (var.ulVal, wszBuf.get(), 10);
pwszValue = wszBuf.get();
break;
case VT_I8:
pwszType = gc_wszDavType_Int;
//$ REVIEW: negative values of _int64 seem to have problems in
// the __i64tow() API. Handle those cases ourselves by using the wrapper
// function Int64ToPwsz.
//
Int64ToPwsz (&var.hVal.QuadPart, wszBuf.get(), wszBuf.size());
//
//$ REVIEW: end
pwszValue = wszBuf.get();
break;
case VT_UI8:
pwszType = gc_wszDavType_Int;
_ui64tow (var.uhVal.QuadPart, wszBuf.get(), 10);
pwszValue = wszBuf.get();
break;
case VT_INT:
pwszType = gc_wszDavType_Int;
_itow (pvarTrue->intVal, wszBuf.get(), 10);
pwszValue = wszBuf.get();
break;
case VT_UINT:
pwszType = gc_wszDavType_Int;
_ultow (pvarTrue->uintVal, wszBuf.get(), 10);
pwszValue = wszBuf.get();
break;
case VT_BOOL:
pwszType = gc_wszDavType_Boolean;
_itow (!(VARIANT_FALSE == var.boolVal), wszBuf.get(), 10);
pwszValue = wszBuf.get();
break;
case VT_R4:
// _gcvt could add 8 extra chars then the number of digits asked
// for example -3.1415e+019, '-','.' "e+019", plus the terminating
// NULL doesn't count in digits asked. so we have to reserve
// enough space in the provided buffer. using 11 to make sure
// we are absolutely safe.
//
_gcvt (var.fltVal, szBuf.celems() - 11, szBuf.get());
cch = static_cast<UINT>(strlen(szBuf.get()));
pwszValue = wszBuf.resize(CbSizeWsz(cch));
if (NULL == pwszValue)
{
sc = E_OUTOFMEMORY;
goto ret;
}
// We know that the numbers are in ASCII codepage and we know
// that the buffer size is big enough.
//
cch = MultiByteToWideChar(CP_ACP,
MB_ERR_INVALID_CHARS,
szBuf.get(),
cch + 1,
wszBuf.get(),
wszBuf.celems());
if (0 == cch)
{
sc = HRESULT_FROM_WIN32(GetLastError());
Assert(FAILED(sc));
goto ret;
}
pwszType = gc_wszDavType_R4;
break;
case VT_R8:
// _gcvt could add 8 extra chars then the number of digits asked
// for example -3.1415e+019, '-','.' "e+019", plus the terminating
// NULL doesn't count in digits asked. so we have to reserve
// enough space in the provided buffer. using 11 to make sure
// we are absolutely safe.
//
_gcvt (var.dblVal, szBuf.celems() - 11, szBuf.get());
cch = static_cast<UINT>(strlen(szBuf.get()));
pwszValue = wszBuf.resize(CbSizeWsz(cch));
if (NULL == pwszValue)
{
sc = E_OUTOFMEMORY;
goto ret;
}
// We know that the numbers are in ASCII codepage and we know
// that the buffer size is big enough.
//
cch = MultiByteToWideChar(CP_ACP,
MB_ERR_INVALID_CHARS,
szBuf.get(),
cch + 1,
wszBuf.get(),
wszBuf.celems());
if (0 == cch)
{
sc = HRESULT_FROM_WIN32(GetLastError());
Assert(FAILED(sc));
goto ret;
}
pwszType = gc_wszDavType_Float;
break;
case VT_FILETIME:
if (!FileTimeToSystemTime (&var.filetime, &st))
{
// In case the filetime is invalid, default to zero
//
FILETIME ftDefault = {0};
FileTimeToSystemTime (&ftDefault, &st);
}
if (!FGetDateIso8601FromSystime(&st, wszBuf.get(), wszBuf.celems()))
return E_INVALIDARG;
pwszType = gc_wszDavType_Date_ISO8601;
pwszValue = wszBuf.get();
break;
case VT_VECTOR | VT_LPWSTR:
{
// Create the emitter node;
//
sc = en.ScConstructNode (emitter,
enParent.Pxn(),
pwszTag,
NULL,
gc_wszDavType_Mvstring);
if (FAILED (sc))
goto ret;
// Add the values
//
for (i = 0; i < var.calpwstr.cElems; i++)
{
CEmitterNode enSub;
sc = en.ScAddNode (gc_wszXml_V,
enSub,
var.calpwstr.pElems[i]);
if (FAILED (sc))
goto ret;
}
// In this case we have built up the node ourselves. We do not
// want to fall into recreating the node.
//
return S_OK;
}
case VT_CY:
case VT_DATE:
case VT_DISPATCH:
case VT_ERROR:
case VT_VARIANT:
case VT_UNKNOWN:
case VT_DECIMAL:
case VT_RECORD:
case VT_BLOB:
case VT_STREAM:
case VT_STORAGE:
case VT_STREAMED_OBJECT:
case VT_STORED_OBJECT:
case VT_BLOB_OBJECT:
case VT_CF:
case VT_CLSID:
default:
TrapSz ("ScEmitterNodeFromVariant() unknown type");
return E_UNEXPECTED;
break;
}
// Create the emitter node
//
sc = en.ScConstructNode (emitter,
enParent.Pxn(),
pwszTag,
pwszValue,
pwszType);
if (FAILED (sc))
goto ret;
ret:
return sc;
}