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.

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