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.

473 lines
9.7 KiB

  1. /*
  2. Copyright (c) 1997-1999 Microsoft Corporation
  3. */
  4. #ifndef __SDP_FIELD__
  5. #define __SDP_FIELD__
  6. #include <strstrea.h>
  7. #include "sdpcommo.h"
  8. #include "sdpdef.h"
  9. #include "sdpgen.h"
  10. class _DllDecl SDP_FIELD
  11. {
  12. public:
  13. virtual void Reset() = 0;
  14. virtual BOOL IsValid() const = 0;
  15. virtual BOOL IsModified() const = 0;
  16. virtual void IsModified(
  17. IN BOOL ModifiedFlag
  18. ) = 0;
  19. virtual DWORD GetCharacterStringSize() = 0;
  20. virtual BOOL PrintField(
  21. OUT ostrstream &OutputStream
  22. ) = 0;
  23. virtual BOOL ParseToken(
  24. IN CHAR *Token
  25. ) = 0;
  26. virtual ~SDP_FIELD()
  27. {}
  28. };
  29. class _DllDecl SDP_SINGLE_FIELD : public SDP_FIELD
  30. {
  31. public:
  32. inline SDP_SINGLE_FIELD(
  33. IN DWORD BufferSize,
  34. IN CHAR *Buffer
  35. );
  36. // SDP_VALUE instances use an inline Reset method which calls a virtual InternalReset method.
  37. // this is possible because unlike the SDP_FIELD inheritance tree, SDP_VALUE and SDP_VALUE_LIST
  38. // do not share a common base class. This combined with the fact that the SDP_VALUE inheriance
  39. // tree is quite shallow and has fewer instances (than SDP_FIELD) makes the scheme appropriate
  40. // it as it reduces the number of Reset related calls to 1 and the inline code is not repeated
  41. // to often.
  42. // For the SDP_FIELD inheritance tree, the appropriate Reset calling sequence is a series of
  43. // Reset calls starting with the top most virtual Reset body followed by the
  44. // base class Reset method (recursively). This is appropriate because, the number of calls
  45. // would not decrease if the InternalReset scheme is adopted (virtual Reset()) and that the
  46. // inheritance tree is much deeper
  47. virtual void Reset();
  48. // the IsValid and IsModified methods are virtual only because the base
  49. // class is virtual. It is required that none of the classes derived
  50. // from this class over-ride these methods.
  51. virtual BOOL IsValid() const;
  52. virtual BOOL IsModified() const;
  53. virtual void IsModified(
  54. IN BOOL ModifiedFlag
  55. );
  56. virtual DWORD GetCharacterStringSize();
  57. virtual BOOL PrintField(
  58. OUT ostrstream &OutputStream
  59. );
  60. virtual BOOL ParseToken(
  61. IN CHAR *Token
  62. );
  63. virtual ~SDP_SINGLE_FIELD()
  64. {}
  65. protected:
  66. // flag - tells whether the type value is valid (parsed in / added later etc.)
  67. BOOL m_IsValid;
  68. BOOL m_IsModified;
  69. // this should be const, but cannot be because ostrstream does not take
  70. // const length for parameter
  71. DWORD m_PrintBufferSize;
  72. CHAR *m_PrintBuffer;
  73. DWORD m_PrintLength;
  74. void IsValid(
  75. IN BOOL ValidFlag
  76. );
  77. virtual DWORD CalcCharacterStringSize();
  78. virtual BOOL CopyField(
  79. OUT ostrstream &OutputStream
  80. );
  81. virtual BOOL InternalParseToken(
  82. IN CHAR *Token
  83. ) = 0;
  84. inline void RemoveWhiteSpaces(
  85. IN OUT CHAR *&Token
  86. );
  87. inline BOOL IsWhiteSpaces(
  88. IN CHAR *Token,
  89. IN DWORD ErrorCode
  90. );
  91. virtual BOOL PrintData(
  92. OUT ostrstream &OutputStream
  93. ) = 0;
  94. };
  95. inline
  96. SDP_SINGLE_FIELD::SDP_SINGLE_FIELD(
  97. IN DWORD BufferSize,
  98. IN CHAR *Buffer
  99. )
  100. : m_IsValid(FALSE),
  101. m_IsModified(FALSE),
  102. m_PrintBufferSize(BufferSize),
  103. m_PrintBuffer(Buffer),
  104. m_PrintLength(0)
  105. {
  106. }
  107. inline void
  108. SDP_SINGLE_FIELD::RemoveWhiteSpaces(
  109. IN OUT CHAR *&Token
  110. )
  111. {
  112. // use of line terminator ensures that the token ptr cannot be null
  113. ASSERT(NULL != Token);
  114. while ( EOS != *Token )
  115. {
  116. if ( (CHAR_BLANK == *Token)
  117. || (CHAR_TAB == *Token)
  118. || (CHAR_RETURN == *Token) )
  119. {
  120. Token++;
  121. }
  122. else
  123. {
  124. return;
  125. }
  126. }
  127. }
  128. inline BOOL
  129. SDP_SINGLE_FIELD::IsWhiteSpaces(
  130. IN CHAR *Token,
  131. IN DWORD ErrorCode
  132. )
  133. {
  134. while ( EOS != *Token )
  135. {
  136. if ( (CHAR_BLANK == *Token)
  137. || (CHAR_TAB == *Token)
  138. || (CHAR_RETURN == *Token) )
  139. {
  140. Token++;
  141. }
  142. else
  143. {
  144. SetLastError(ErrorCode);
  145. return FALSE;
  146. }
  147. }
  148. return TRUE;
  149. }
  150. class _DllDecl SDP_FIELD_LIST : public SDP_POINTER_ARRAY<SDP_FIELD *>,
  151. public SDP_FIELD
  152. {
  153. public:
  154. inline SDP_FIELD_LIST(
  155. IN CHAR SeparatorChar = CHAR_BLANK
  156. );
  157. virtual void Reset();
  158. virtual BOOL IsValid() const;
  159. virtual BOOL IsModified() const;
  160. virtual void IsModified(
  161. IN BOOL ModifiedFlag
  162. );
  163. virtual DWORD GetCharacterStringSize();
  164. virtual BOOL PrintField(
  165. OUT ostrstream &OutputStream
  166. );
  167. virtual BOOL ParseToken(
  168. IN CHAR *Token
  169. );
  170. protected:
  171. const CHAR m_SeparatorChar;
  172. virtual SDP_FIELD *CreateElement() = 0;
  173. };
  174. inline
  175. SDP_FIELD_LIST::SDP_FIELD_LIST(
  176. IN CHAR SeparatorChar
  177. )
  178. : m_SeparatorChar(SeparatorChar)
  179. {
  180. }
  181. // for reading unsigned integral base type values largest of which may
  182. // be a ULONG
  183. // no Reset method to set the value member to 0 again (as its not really required and it saves
  184. // one call per instance)
  185. template <class T>
  186. class _DllDecl SDP_UNSIGNED_INTEGRAL_BASE_TYPE : public SDP_SINGLE_FIELD
  187. {
  188. public:
  189. inline SDP_UNSIGNED_INTEGRAL_BASE_TYPE();
  190. inline HRESULT GetValue(
  191. IN T &Value
  192. );
  193. inline T GetValue() const;
  194. inline void SetValue(
  195. IN T Value
  196. );
  197. inline void SetValueAndFlag(
  198. IN T Value
  199. );
  200. protected:
  201. T m_Value;
  202. CHAR m_NumericalValueBuffer[25];
  203. virtual BOOL InternalParseToken(
  204. IN CHAR *Token
  205. );
  206. virtual BOOL PrintData(
  207. OUT ostrstream &OutputStream
  208. );
  209. };
  210. template <class T>
  211. inline
  212. SDP_UNSIGNED_INTEGRAL_BASE_TYPE<T>::SDP_UNSIGNED_INTEGRAL_BASE_TYPE(
  213. )
  214. : SDP_SINGLE_FIELD(sizeof(m_NumericalValueBuffer), m_NumericalValueBuffer),
  215. m_Value(0)
  216. {
  217. }
  218. template <class T>
  219. inline HRESULT
  220. SDP_UNSIGNED_INTEGRAL_BASE_TYPE<T>::GetValue(
  221. IN T &Value
  222. )
  223. {
  224. if ( !IsValid() )
  225. {
  226. return HRESULT_FROM_ERROR_CODE(ERROR_INVALID_DATA);
  227. }
  228. Value = m_Value;
  229. return S_OK;
  230. }
  231. template <class T>
  232. inline T
  233. SDP_UNSIGNED_INTEGRAL_BASE_TYPE<T>::GetValue(
  234. ) const
  235. {
  236. return m_Value;
  237. }
  238. template <class T>
  239. inline void
  240. SDP_UNSIGNED_INTEGRAL_BASE_TYPE<T>::SetValue(
  241. IN T Value
  242. )
  243. {
  244. m_Value = Value;
  245. }
  246. template <class T>
  247. inline void
  248. SDP_UNSIGNED_INTEGRAL_BASE_TYPE<T>::SetValueAndFlag(
  249. IN T Value
  250. )
  251. {
  252. m_Value = Value;
  253. IsValid(TRUE);
  254. IsModified(TRUE);
  255. }
  256. template <class T>
  257. inline BOOL
  258. SDP_UNSIGNED_INTEGRAL_BASE_TYPE<T>::InternalParseToken(
  259. IN CHAR *Token
  260. )
  261. {
  262. CHAR *Current = Token;
  263. // remove preceding white spaces
  264. RemoveWhiteSpaces(Current);
  265. // check that the first character is a digit (to weed out -ve values)
  266. if ( !isdigit(*Current) )
  267. {
  268. SetLastError(SDP_INVALID_NUMERICAL_VALUE);
  269. return FALSE;
  270. }
  271. // since T is UNSIGNED, max value will contain all 1's - the
  272. // maximum value it can store
  273. const T MaxValue = -1;
  274. // ensure that T is unsigned
  275. // since such an error will be detected during debugging, no need
  276. // for if ( ! ... ) code
  277. ASSERT(MaxValue > 0);
  278. CHAR *RestOfToken = NULL;
  279. ULONG TokenValue = strtoul(Current, &RestOfToken, 10);
  280. if ( (ULONG_MAX == TokenValue) || (MaxValue < TokenValue) )
  281. {
  282. SetLastError(SDP_INVALID_NUMERICAL_VALUE);
  283. return FALSE;
  284. }
  285. // ensure that rest of the string is white spaces
  286. if ( !IsWhiteSpaces(RestOfToken, SDP_INVALID_NUMERICAL_VALUE) )
  287. {
  288. return FALSE;
  289. }
  290. m_Value = (T)TokenValue;
  291. return TRUE;
  292. }
  293. template <class T>
  294. inline BOOL
  295. SDP_UNSIGNED_INTEGRAL_BASE_TYPE<T>::PrintData(
  296. OUT ostrstream &OutputStream
  297. )
  298. {
  299. OutputStream << (ULONG)m_Value;
  300. if ( OutputStream.fail() )
  301. {
  302. SetLastError(SDP_OUTPUT_ERROR);
  303. return FALSE;
  304. }
  305. return TRUE;
  306. }
  307. class _DllDecl SDP_ULONG : public SDP_UNSIGNED_INTEGRAL_BASE_TYPE<ULONG>
  308. {
  309. };
  310. class _DllDecl SDP_USHORT : public SDP_UNSIGNED_INTEGRAL_BASE_TYPE<USHORT>
  311. {
  312. };
  313. class _DllDecl SDP_BYTE : public SDP_UNSIGNED_INTEGRAL_BASE_TYPE<BYTE>
  314. {
  315. };
  316. class SDP_BYTE_LIST : public SDP_FIELD_LIST
  317. {
  318. public:
  319. virtual SDP_FIELD *CreateElement()
  320. {
  321. SDP_BYTE *SdpByte;
  322. try
  323. {
  324. SdpByte = new SDP_BYTE();
  325. }
  326. catch(...)
  327. {
  328. SdpByte = NULL;
  329. }
  330. return SdpByte;
  331. }
  332. };
  333. class SDP_ULONG_LIST : public SDP_FIELD_LIST
  334. {
  335. public:
  336. virtual SDP_FIELD *CreateElement()
  337. {
  338. SDP_ULONG *SdpULong;
  339. try
  340. {
  341. SdpULong = new SDP_ULONG();
  342. }
  343. catch(...)
  344. {
  345. SdpULong = NULL;
  346. }
  347. return SdpULong;
  348. }
  349. };
  350. #endif // __SDP_FIELD__