windows-nt/Source/XPSP1/NT/admin/wmi/wbem/winmgmt/wbemcomn/datepart.cpp
2020-09-26 16:20:57 +08:00

280 lines
4.6 KiB
C++

//***************************************************************************
//
// (c) 2000-2001 by Microsoft Corp. All Rights Reserved.
//
// datepart.cpp
//
// a-davcoo 28-Feb-00 Implements the SQL datepart operation.
//
//***************************************************************************
#include "precomp.h"
#include "datepart.h"
#include <stdio.h>
#include "wbemcli.h"
CDatePart::CDatePart ()
{
m_date=NULL;
}
CDatePart::~CDatePart (void)
{
delete m_date;
}
HRESULT CDatePart::SetDate (LPCWSTR lpDate)
{
HRESULT hr = 0;
delete m_date;
m_date=NULL;
m_date = new CDMTFParser(lpDate);
if (!m_date)
hr = WBEM_E_OUT_OF_MEMORY;
return hr;
}
HRESULT CDatePart::SetDate (LPCSTR lpDate)
{
HRESULT hr = 0;
delete m_date;
m_date=NULL;
wchar_t *pNew = new wchar_t [(strlen(lpDate)*4)+1];
if (pNew)
{
swprintf(pNew, L"%S", lpDate);
m_date = new CDMTFParser(pNew);
delete pNew;
}
if (!m_date)
hr = WBEM_E_OUT_OF_MEMORY;
return hr;
}
HRESULT CDatePart::GetPart (int datepart, int *value)
{
HRESULT hr=WBEM_S_NO_ERROR;
int part;
switch (datepart)
{
case DATEPART_YEAR:
{
part=CDMTFParser::YEAR;
break;
}
case DATEPART_MONTH:
{
part=CDMTFParser::MONTH;
break;
}
case DATEPART_DAY:
{
part=CDMTFParser::DAY;
break;
}
case DATEPART_HOUR:
{
part=CDMTFParser::HOUR;
break;
}
case DATEPART_MINUTE:
{
part=CDMTFParser::MINUTE;
break;
}
case DATEPART_SECOND:
{
part=CDMTFParser::SECOND;
break;
}
case DATEPART_MILLISECOND:
{
part=CDMTFParser::MICROSECOND;
break;
}
default:
{
hr=WBEM_E_NOT_AVAILABLE;
*value=0;
break;
}
}
if (SUCCEEDED(hr))
{
if (!m_date->IsValid())
{
hr=WBEM_E_INVALID_PARAMETER;
}
else if (!m_date->IsUsed (part) || m_date->IsWildcard (part))
{
hr=WBEM_E_NOT_AVAILABLE;
}
else
{
*value=m_date->GetValue (part);
if (datepart==DATEPART_MILLISECOND) *value/=1000;
}
}
return hr;
}
CDMTFParser::CDMTFParser (LPCWSTR date)
{
ParseDate (date);
}
CDMTFParser::~CDMTFParser (void)
{
}
void CDMTFParser::ParseDate (LPCWSTR date)
{
m_valid=true;
for (int index=0; index<NUMPARTS; index++)
{
m_status[index]=NOTUSED;
m_part[index]=0;
}
int length=wcslen (date);
if (length!=25 || date[14]!=L'.')
{
m_valid=false;
}
else
{
m_interval=!wcscmp (&date[21], L":000");
if (m_interval)
{
ParseInterval (date);
}
else
{
ParseAbsolute (date);
}
}
for (index=0; index<NUMPARTS; index++)
{
if (m_status[index]==INVALID)
{
m_valid=false;
break;
}
}
}
void CDMTFParser::ParseInterval (LPCWSTR date)
{
m_status[DAY]=ParsePart (date, 0, 8, &m_part[DAY], 0, 999999999);
m_status[HOUR]=ParsePart (date, 8, 2, &m_part[HOUR], 0, 23);
m_status[MINUTE]=ParsePart (date, 10, 2, &m_part[MINUTE], 0, 59);
m_status[SECOND]=ParsePart (date, 12, 2, &m_part[SECOND], 0, 59);
m_status[MICROSECOND]=ParsePart (date, 15, 6, &m_part[MICROSECOND], 0, 999999);
}
void CDMTFParser::ParseAbsolute (LPCWSTR date)
{
m_status[YEAR]=ParsePart (date, 0, 4, &m_part[YEAR], 0, 9999);
m_status[MONTH]=ParsePart (date, 4, 2, &m_part[MONTH], 1, 12);
m_status[DAY]=ParsePart (date, 6, 2, &m_part[DAY], 1, 31);
m_status[HOUR]=ParsePart (date, 8, 2, &m_part[HOUR], 0, 23);
m_status[MINUTE]=ParsePart (date, 10, 2, &m_part[MINUTE], 0, 59);
m_status[SECOND]=ParsePart (date, 12, 2, &m_part[SECOND], 0, 59);
m_status[MICROSECOND]=ParsePart (date, 15, 6, &m_part[MICROSECOND], 0, 999999);
m_status[OFFSET]=ParsePart (date, 22, 3, &m_part[OFFSET], 0, 999);
if (date[21]==L'-')
m_part[OFFSET]*=(-1);
else if (date[21]!=L'+')
m_status[OFFSET]=INVALID;
}
int CDMTFParser::ParsePart (LPCWSTR date, int pos, int length, int *result, int min, int max)
{
*result=0;
bool digits=false, wildcard=false;
for (int index=pos; index<pos+length; index++)
{
if (iswdigit (date[index]))
{
if (wildcard) return INVALID;
*result*=10;
*result+=date[index]-L'0';
digits=true;
}
else if (date[index]==L'*')
{
if (digits) return INVALID;
wildcard=true;
}
else
{
return INVALID;
}
}
if (!wildcard && (*result<min || *result>max)) return INVALID;
return VALID;
}
bool CDMTFParser::IsValid (void)
{
return m_valid;
}
bool CDMTFParser::IsInterval (void)
{
return m_interval;
}
bool CDMTFParser::IsUsed (int part)
{
return m_valid && !(m_status[part] & NOTUSED);
}
bool CDMTFParser::IsWildcard (int part)
{
return m_valid && (m_status[part] & NOTSUPPLIED);
}
int CDMTFParser::GetValue (int part)
{
return m_valid ? m_part[part] : 0;
}