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.

170 lines
3.5 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // textmap.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // This file defines functions for converting Time of Day restriction
  12. // hour maps to and from a textual representation.
  13. //
  14. // MODIFICATION HISTORY
  15. //
  16. // 02/05/1998 Original version.
  17. // 04/06/1998 Sunday is day zero again.
  18. //
  19. ///////////////////////////////////////////////////////////////////////////////
  20. #include <ias.h>
  21. #include <Parser.h>
  22. #include <textmap.h>
  23. //////////
  24. // Definition of whitespace.
  25. //////////
  26. #define WSP L" "
  27. //////////
  28. // Valid delimiters for days.
  29. //////////
  30. #define DELIM L",;|"
  31. ///////////////////////////////////////////////////////////////////////////////
  32. //
  33. // CLASS
  34. //
  35. // TimeOfDayParser
  36. //
  37. // DESCRIPTION
  38. //
  39. // This class extends Parser to extract hour maps from a string.
  40. //
  41. ///////////////////////////////////////////////////////////////////////////////
  42. class TimeOfDayParser : public Parser
  43. {
  44. public:
  45. TimeOfDayParser(PWSTR source) throw ()
  46. : Parser(source) { }
  47. // Extract time of day in the format hh:mm.
  48. void extractTime(ULONG* hour, ULONG* minute) throw (ParseError)
  49. {
  50. *hour = extractUnsignedLong();
  51. skip(WSP);
  52. // Minutes are optional.
  53. if (*current == L':')
  54. {
  55. ++current;
  56. *minute = extractUnsignedLong();
  57. }
  58. else
  59. {
  60. *minute = 0;
  61. }
  62. if (*hour > 24 || *minute > 59 || (*hour == 24 && *minute != 0))
  63. {
  64. throw ParseError();
  65. }
  66. }
  67. // Extracts a single day's hour map.
  68. void extractDay(PBYTE hourMap) throw (ParseError)
  69. {
  70. // Get the day of week (an integer from 0-6).
  71. ULONG dayOfWeek = extractUnsignedLong();
  72. skip(WSP);
  73. if (dayOfWeek > 6) { throw ParseError(); }
  74. do
  75. {
  76. // Get the start time of the range.
  77. ULONG startHour, startMinute;
  78. extractTime(&startHour, &startMinute);
  79. skip(WSP);
  80. ignore(L'-');
  81. // Get the end time of the range.
  82. ULONG endHour, endMinute;
  83. extractTime(&endHour, &endMinute);
  84. skip(WSP);
  85. // Make sure the values are legit.
  86. if (startHour * 60 + startMinute > endHour * 60 + endMinute)
  87. {
  88. throw ParseError();
  89. }
  90. // Set all bits in the range.
  91. for (size_t i=startHour; i<endHour; ++i)
  92. {
  93. hourMap[dayOfWeek * 3 + i / 8] |= 0x80 >> (i % 8);
  94. }
  95. } while (more());
  96. }
  97. };
  98. ///////////////////////////////////////////////////////////////////////////////
  99. //
  100. // FUNCTION
  101. //
  102. // IASTextToHourMap
  103. //
  104. ///////////////////////////////////////////////////////////////////////////////
  105. DWORD
  106. WINAPI
  107. IASHourMapFromText(
  108. IN PCWSTR szText,
  109. OUT PBYTE pHourMap
  110. )
  111. {
  112. if (szText == NULL || pHourMap == NULL)
  113. {
  114. return ERROR_INVALID_PARAMETER;
  115. }
  116. memset(pHourMap, 0, IAS_HOUR_MAP_LENGTH);
  117. //////////
  118. // Make a local copy so we can modify the text.
  119. //////////
  120. PWSTR copy = (PWSTR)_alloca((wcslen(szText) + 1) * sizeof(WCHAR));
  121. wcscpy(copy, szText);
  122. //////////
  123. // Parse the text.
  124. //////////
  125. try
  126. {
  127. // Each day should be separated by a comma or semicolon.
  128. PWSTR token = wcstok(copy, DELIM);
  129. while (token)
  130. {
  131. TimeOfDayParser parser(token);
  132. parser.extractDay(pHourMap);
  133. token = wcstok(NULL, DELIM);
  134. }
  135. }
  136. catch (Parser::ParseError)
  137. {
  138. return ERROR_INVALID_DATA;
  139. }
  140. return NO_ERROR;
  141. }