Source code of Windows XP (NT5)
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.

279 lines
4.6 KiB

  1. //***************************************************************************
  2. //
  3. // (c) 2000-2001 by Microsoft Corp. All Rights Reserved.
  4. //
  5. // datepart.cpp
  6. //
  7. // a-davcoo 28-Feb-00 Implements the SQL datepart operation.
  8. //
  9. //***************************************************************************
  10. #include "precomp.h"
  11. #include "datepart.h"
  12. #include <stdio.h>
  13. #include "wbemcli.h"
  14. CDatePart::CDatePart ()
  15. {
  16. m_date=NULL;
  17. }
  18. CDatePart::~CDatePart (void)
  19. {
  20. delete m_date;
  21. }
  22. HRESULT CDatePart::SetDate (LPCWSTR lpDate)
  23. {
  24. HRESULT hr = 0;
  25. delete m_date;
  26. m_date=NULL;
  27. m_date = new CDMTFParser(lpDate);
  28. if (!m_date)
  29. hr = WBEM_E_OUT_OF_MEMORY;
  30. return hr;
  31. }
  32. HRESULT CDatePart::SetDate (LPCSTR lpDate)
  33. {
  34. HRESULT hr = 0;
  35. delete m_date;
  36. m_date=NULL;
  37. wchar_t *pNew = new wchar_t [(strlen(lpDate)*4)+1];
  38. if (pNew)
  39. {
  40. swprintf(pNew, L"%S", lpDate);
  41. m_date = new CDMTFParser(pNew);
  42. delete pNew;
  43. }
  44. if (!m_date)
  45. hr = WBEM_E_OUT_OF_MEMORY;
  46. return hr;
  47. }
  48. HRESULT CDatePart::GetPart (int datepart, int *value)
  49. {
  50. HRESULT hr=WBEM_S_NO_ERROR;
  51. int part;
  52. switch (datepart)
  53. {
  54. case DATEPART_YEAR:
  55. {
  56. part=CDMTFParser::YEAR;
  57. break;
  58. }
  59. case DATEPART_MONTH:
  60. {
  61. part=CDMTFParser::MONTH;
  62. break;
  63. }
  64. case DATEPART_DAY:
  65. {
  66. part=CDMTFParser::DAY;
  67. break;
  68. }
  69. case DATEPART_HOUR:
  70. {
  71. part=CDMTFParser::HOUR;
  72. break;
  73. }
  74. case DATEPART_MINUTE:
  75. {
  76. part=CDMTFParser::MINUTE;
  77. break;
  78. }
  79. case DATEPART_SECOND:
  80. {
  81. part=CDMTFParser::SECOND;
  82. break;
  83. }
  84. case DATEPART_MILLISECOND:
  85. {
  86. part=CDMTFParser::MICROSECOND;
  87. break;
  88. }
  89. default:
  90. {
  91. hr=WBEM_E_NOT_AVAILABLE;
  92. *value=0;
  93. break;
  94. }
  95. }
  96. if (SUCCEEDED(hr))
  97. {
  98. if (!m_date->IsValid())
  99. {
  100. hr=WBEM_E_INVALID_PARAMETER;
  101. }
  102. else if (!m_date->IsUsed (part) || m_date->IsWildcard (part))
  103. {
  104. hr=WBEM_E_NOT_AVAILABLE;
  105. }
  106. else
  107. {
  108. *value=m_date->GetValue (part);
  109. if (datepart==DATEPART_MILLISECOND) *value/=1000;
  110. }
  111. }
  112. return hr;
  113. }
  114. CDMTFParser::CDMTFParser (LPCWSTR date)
  115. {
  116. ParseDate (date);
  117. }
  118. CDMTFParser::~CDMTFParser (void)
  119. {
  120. }
  121. void CDMTFParser::ParseDate (LPCWSTR date)
  122. {
  123. m_valid=true;
  124. for (int index=0; index<NUMPARTS; index++)
  125. {
  126. m_status[index]=NOTUSED;
  127. m_part[index]=0;
  128. }
  129. int length=wcslen (date);
  130. if (length!=25 || date[14]!=L'.')
  131. {
  132. m_valid=false;
  133. }
  134. else
  135. {
  136. m_interval=!wcscmp (&date[21], L":000");
  137. if (m_interval)
  138. {
  139. ParseInterval (date);
  140. }
  141. else
  142. {
  143. ParseAbsolute (date);
  144. }
  145. }
  146. for (index=0; index<NUMPARTS; index++)
  147. {
  148. if (m_status[index]==INVALID)
  149. {
  150. m_valid=false;
  151. break;
  152. }
  153. }
  154. }
  155. void CDMTFParser::ParseInterval (LPCWSTR date)
  156. {
  157. m_status[DAY]=ParsePart (date, 0, 8, &m_part[DAY], 0, 999999999);
  158. m_status[HOUR]=ParsePart (date, 8, 2, &m_part[HOUR], 0, 23);
  159. m_status[MINUTE]=ParsePart (date, 10, 2, &m_part[MINUTE], 0, 59);
  160. m_status[SECOND]=ParsePart (date, 12, 2, &m_part[SECOND], 0, 59);
  161. m_status[MICROSECOND]=ParsePart (date, 15, 6, &m_part[MICROSECOND], 0, 999999);
  162. }
  163. void CDMTFParser::ParseAbsolute (LPCWSTR date)
  164. {
  165. m_status[YEAR]=ParsePart (date, 0, 4, &m_part[YEAR], 0, 9999);
  166. m_status[MONTH]=ParsePart (date, 4, 2, &m_part[MONTH], 1, 12);
  167. m_status[DAY]=ParsePart (date, 6, 2, &m_part[DAY], 1, 31);
  168. m_status[HOUR]=ParsePart (date, 8, 2, &m_part[HOUR], 0, 23);
  169. m_status[MINUTE]=ParsePart (date, 10, 2, &m_part[MINUTE], 0, 59);
  170. m_status[SECOND]=ParsePart (date, 12, 2, &m_part[SECOND], 0, 59);
  171. m_status[MICROSECOND]=ParsePart (date, 15, 6, &m_part[MICROSECOND], 0, 999999);
  172. m_status[OFFSET]=ParsePart (date, 22, 3, &m_part[OFFSET], 0, 999);
  173. if (date[21]==L'-')
  174. m_part[OFFSET]*=(-1);
  175. else if (date[21]!=L'+')
  176. m_status[OFFSET]=INVALID;
  177. }
  178. int CDMTFParser::ParsePart (LPCWSTR date, int pos, int length, int *result, int min, int max)
  179. {
  180. *result=0;
  181. bool digits=false, wildcard=false;
  182. for (int index=pos; index<pos+length; index++)
  183. {
  184. if (iswdigit (date[index]))
  185. {
  186. if (wildcard) return INVALID;
  187. *result*=10;
  188. *result+=date[index]-L'0';
  189. digits=true;
  190. }
  191. else if (date[index]==L'*')
  192. {
  193. if (digits) return INVALID;
  194. wildcard=true;
  195. }
  196. else
  197. {
  198. return INVALID;
  199. }
  200. }
  201. if (!wildcard && (*result<min || *result>max)) return INVALID;
  202. return VALID;
  203. }
  204. bool CDMTFParser::IsValid (void)
  205. {
  206. return m_valid;
  207. }
  208. bool CDMTFParser::IsInterval (void)
  209. {
  210. return m_interval;
  211. }
  212. bool CDMTFParser::IsUsed (int part)
  213. {
  214. return m_valid && !(m_status[part] & NOTUSED);
  215. }
  216. bool CDMTFParser::IsWildcard (int part)
  217. {
  218. return m_valid && (m_status[part] & NOTSUPPLIED);
  219. }
  220. int CDMTFParser::GetValue (int part)
  221. {
  222. return m_valid ? m_part[part] : 0;
  223. }