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.

253 lines
4.7 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Simple parameter string parsing.
  4. //
  5. // Copyright (C) Microsoft Corporation, 2000.
  6. //
  7. //----------------------------------------------------------------------------
  8. #include "pch.hpp"
  9. #include "pparse.hpp"
  10. //----------------------------------------------------------------------------
  11. //
  12. // ParameterStringParser.
  13. //
  14. //----------------------------------------------------------------------------
  15. ParameterStringParser::ParameterStringParser(void)
  16. {
  17. m_Name = NULL;
  18. }
  19. BOOL
  20. ParameterStringParser::ParseParameters(PCSTR ParamString)
  21. {
  22. if (ParamString == NULL)
  23. {
  24. // Nothing to parse.
  25. return TRUE;
  26. }
  27. PCSTR Scan = ParamString;
  28. // Skip <name>: if present.
  29. while (*Scan && *Scan != ':')
  30. {
  31. Scan++;
  32. }
  33. if (*Scan == ':')
  34. {
  35. Scan++;
  36. }
  37. else
  38. {
  39. Scan = ParamString;
  40. }
  41. //
  42. // Scan options string for comma-delimited parameters
  43. // and pass them into the parameter handling method.
  44. //
  45. char Param[MAX_PARAM_NAME];
  46. char Value[MAX_PARAM_VALUE];
  47. PSTR ValStr;
  48. PSTR Str;
  49. for (;;)
  50. {
  51. while (*Scan && isspace(*Scan))
  52. {
  53. *Scan++;
  54. }
  55. if (!*Scan)
  56. {
  57. break;
  58. }
  59. Str = Param;
  60. while (*Scan && *Scan != ',' && *Scan != '=' &&
  61. (Str - Param) < MAX_PARAM_NAME)
  62. {
  63. *Str++ = *Scan++;
  64. }
  65. if (Str >= Param + MAX_PARAM_NAME)
  66. {
  67. return FALSE;
  68. }
  69. // Terminate option name and default value to nothing.
  70. *Str++ = 0;
  71. ValStr = NULL;
  72. if (*Scan == '=')
  73. {
  74. // Parameter has a value, scan it.
  75. Scan++;
  76. while (*Scan && isspace(*Scan))
  77. {
  78. *Scan++;
  79. }
  80. Str = Value;
  81. while (*Scan && *Scan != ',' &&
  82. (Str - Value) < MAX_PARAM_VALUE)
  83. {
  84. *Str++ = *Scan++;
  85. }
  86. if (Str >= Value + MAX_PARAM_VALUE)
  87. {
  88. return FALSE;
  89. }
  90. *Str++ = 0;
  91. ValStr = Value;
  92. }
  93. if (*Scan)
  94. {
  95. // Skip comma for next iteration.
  96. Scan++;
  97. }
  98. // Set the value in the parser.
  99. if (!SetParameter(Param, ValStr))
  100. {
  101. return FALSE;
  102. }
  103. }
  104. return TRUE;
  105. }
  106. BOOL
  107. ParameterStringParser::GetParameters(PSTR Buffer, ULONG BufferSize)
  108. {
  109. ULONG Len;
  110. BOOL Ret = FALSE;
  111. // Reserve space for the terminator.
  112. if (BufferSize < 1)
  113. {
  114. return FALSE;
  115. }
  116. BufferSize--;
  117. if (m_Name != NULL)
  118. {
  119. Len = strlen(m_Name);
  120. if (BufferSize < Len + 1)
  121. {
  122. goto EH_Exit;
  123. }
  124. memcpy(Buffer, m_Name, Len);
  125. Buffer += Len;
  126. *Buffer++ = ':';
  127. BufferSize -= Len + 1;
  128. }
  129. ULONG Params;
  130. ULONG i;
  131. char Name[MAX_PARAM_NAME];
  132. char Value[MAX_PARAM_VALUE];
  133. BOOL NeedComma;
  134. Params = GetNumberParameters();
  135. NeedComma = FALSE;
  136. for (i = 0; i < Params; i++)
  137. {
  138. Name[0] = 0;
  139. Value[0] = 0;
  140. GetParameter(i, Name, Value);
  141. Len = strlen(Name);
  142. if (Len == 0)
  143. {
  144. continue;
  145. }
  146. if (BufferSize < Len)
  147. {
  148. goto EH_Exit;
  149. }
  150. if (NeedComma)
  151. {
  152. if (BufferSize < 1)
  153. {
  154. goto EH_Exit;
  155. }
  156. *Buffer++ = ',';
  157. BufferSize--;
  158. }
  159. memcpy(Buffer, Name, Len);
  160. Buffer += Len;
  161. BufferSize -= Len;
  162. NeedComma = TRUE;
  163. Len = strlen(Value);
  164. if (Len == 0)
  165. {
  166. continue;
  167. }
  168. if (BufferSize < Len + 1)
  169. {
  170. goto EH_Exit;
  171. }
  172. *Buffer++ = '=';
  173. memcpy(Buffer, Value, Len);
  174. Buffer += Len;
  175. BufferSize -= Len + 1;
  176. }
  177. Ret = TRUE;
  178. EH_Exit:
  179. *Buffer++ = 0;
  180. return Ret;
  181. }
  182. ULONG
  183. ParameterStringParser::GetParser(PCSTR ParamString,
  184. ULONG NumNames, PCSTR* Names)
  185. {
  186. if (ParamString == NULL)
  187. {
  188. return PARSER_INVALID;
  189. }
  190. //
  191. // Parse out <name>: and look up the name.
  192. //
  193. PCSTR Scan = ParamString;
  194. while (*Scan && *Scan != ':')
  195. {
  196. Scan++;
  197. }
  198. ULONG Len = (ULONG)(Scan - ParamString);
  199. if (*Scan != ':' || Len < 1)
  200. {
  201. return PARSER_INVALID;
  202. }
  203. ULONG i;
  204. for (i = 0; i < NumNames; i++)
  205. {
  206. if (strlen(Names[i]) == Len &&
  207. !_memicmp(Names[i], ParamString, Len))
  208. {
  209. return i;
  210. }
  211. }
  212. return PARSER_INVALID;
  213. }