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.

660 lines
12 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. icstring.hxx
  5. Abstract:
  6. Contains ICSTRING class methods. Split from ICSTRING.HXX (inline methods)
  7. Contents:
  8. ICSTRING::ICSTRING(ICSTRING&)
  9. ICSTRING::~ICSTRING()
  10. ICSTRING::operator=(LPSTR)
  11. ICSTRING::operator=(ICSTRING&)
  12. ICSTRING::operator+=(LPSTR)
  13. ICSTRING::operator+=(char)
  14. ICSTRING::strncat(LPVOID, DWORD)
  15. ICSTRING::CreateStringBuffer(LPVOID, DWORD, DWORD)
  16. ICSTRING::CreateOffsetString(DWORD, DWORD)
  17. ICSTRING::CopyTo(LPSTR)
  18. ICSTRING::CopyTo(LPSTR, LPSTR)
  19. ICSTRING::CopyTo(LPSTR, DWORD)
  20. ICSTRING::CopyTo(LPSTR, LPDWORD)
  21. Author:
  22. Richard L Firth (rfirth) 18-Dec-1995
  23. Revision History:
  24. 18-Dec-1995 rfirth
  25. Created
  26. --*/
  27. #include <wininetp.h>
  28. //
  29. // methods
  30. //
  31. //
  32. //ICSTRING::ICSTRING(
  33. // IN ICSTRING& String
  34. // )
  35. //
  36. ///*++
  37. //
  38. //Routine Description:
  39. //
  40. // copy constructor. We now create an entirely new string (used to be just a
  41. // reference of the rvalue)
  42. //
  43. //Arguments:
  44. //
  45. // String - to copy
  46. //
  47. //Return Value:
  48. //
  49. // None.
  50. //
  51. //--*/
  52. //
  53. //{
  54. // //
  55. // // can't already have string in lvalue, & rvalue mustn't be an offset string
  56. // //
  57. //
  58. // INET_ASSERT(!HaveString());
  59. // INET_ASSERT(!String.IsOffset());
  60. // INET_ASSERT(!String.IsError());
  61. //
  62. // *this = String.StringAddress();
  63. //}
  64. ICSTRING::~ICSTRING(
  65. VOID
  66. )
  67. /*++
  68. Routine Description:
  69. destructor
  70. Arguments:
  71. None.
  72. Return Value:
  73. None.
  74. --*/
  75. {
  76. //
  77. // can only free the string if it is not a reference. Offset type
  78. // implies reference
  79. //
  80. if (!IsReference() && (_String != NULL)) {
  81. INET_ASSERT(!IsOffset());
  82. (VOID)ResizeBuffer((HLOCAL)_String, 0, FALSE);
  83. }
  84. }
  85. ICSTRING&
  86. ICSTRING::operator=(
  87. IN LPSTR String
  88. )
  89. /*++
  90. Routine Description:
  91. Copy/assigment. Copies a string to this object. If NULL, frees up the
  92. current buffer
  93. Arguments:
  94. String - to be assigned
  95. Return Value:
  96. ICSTRING&
  97. --*/
  98. {
  99. //
  100. // if this is an offset string then there's not much to do
  101. //
  102. if (IsOffset()) {
  103. Initialize();
  104. return *this;
  105. }
  106. //
  107. // string MUST NOT be a copy (we'll free the real string pointer, owned
  108. // by another object) and SHOULD NOT be copied itself (the objects with
  109. // copies of the string will potentially have a bad pointer)
  110. //
  111. INET_ASSERT((String == NULL) ? TRUE : !IsReference());
  112. INET_ASSERT(!IsReferenced());
  113. //
  114. // if the pointer is NULL or the string is empty then we are freeing the
  115. // string pointer
  116. //
  117. DWORD len;
  118. if (String == NULL) {
  119. len = 0;
  120. } else {
  121. len = ::strlen(String);
  122. if (len != 0) {
  123. INET_ASSERT(len < 0xffffffff);
  124. ++len;
  125. }
  126. }
  127. //
  128. // free or grow the buffer, depending on requirements
  129. //
  130. if ((len > _BufferLength) || ((len == 0) && (_String != NULL))) {
  131. _String = (LPSTR)ResizeBuffer((HLOCAL)_String, len, FALSE);
  132. _BufferLength = (_String != NULL) ? len : 0;
  133. }
  134. if (_String != NULL) {
  135. INET_ASSERT(len != 0);
  136. memcpy((LPVOID)_String, (LPVOID)String, len);
  137. _StringLength = len - 1;
  138. SetHaveString(TRUE);
  139. SetError(FALSE);
  140. } else {
  141. _StringLength = 0;
  142. SetHaveString(FALSE);
  143. SetError(len != 0); // an error might have occurred
  144. }
  145. return *this;
  146. }
  147. ICSTRING&
  148. ICSTRING::operator=(
  149. IN ICSTRING& String
  150. )
  151. /*++
  152. Routine Description:
  153. Copy/assignment. Makes new copy of object (used to just make a reference)
  154. Arguments:
  155. String - ICSTRING object to be assigned
  156. Return Value:
  157. ICSTRING&
  158. --*/
  159. {
  160. INET_ASSERT(!IsReferenced());
  161. INET_ASSERT(!String.IsReferenced());
  162. INET_ASSERT(!String.IsError());
  163. //
  164. // if we're copying an offset, make sure that any string we may already
  165. // have is freed
  166. //
  167. if (String.IsOffset()) {
  168. if (_String != NULL) {
  169. ResizeBuffer(_String, 0, FALSE);
  170. }
  171. _String = String._String;
  172. _StringLength = String._StringLength;
  173. _BufferLength = String._BufferLength;
  174. _Union.Dword = String._Union.Dword;
  175. } else {
  176. INET_ASSERT(!IsOffset() && !String.IsOffset());
  177. //
  178. // use string assignment to correctly setup this object
  179. //
  180. *this = String.StringAddress();
  181. }
  182. return *this;
  183. }
  184. VOID
  185. ICSTRING::operator+=(
  186. IN LPSTR String
  187. )
  188. /*++
  189. Routine Description:
  190. Concatenates a string to the buffer. Reallocates it if necessary. String
  191. CANNOT be NULL
  192. Arguments:
  193. String - to concatenate
  194. Return Value:
  195. None.
  196. --*/
  197. {
  198. INET_ASSERT(!IsReference());
  199. INET_ASSERT(!IsReferenced());
  200. INET_ASSERT(!IsOffset());
  201. INET_ASSERT(String != NULL);
  202. if (IsError()) {
  203. return;
  204. }
  205. if (*String == '\0') {
  206. return;
  207. }
  208. DWORD len = ::strlen(String);
  209. DWORD newlen = _StringLength + len + 1;
  210. INET_ASSERT ((newlen > _StringLength) && (newlen > len));
  211. if (_BufferLength < newlen) {
  212. _String = (LPSTR)ResizeBuffer((HLOCAL)_String, newlen, FALSE);
  213. INET_ASSERT((_String == NULL) ? (newlen == 0) : TRUE);
  214. _BufferLength = newlen;
  215. }
  216. if (_String != NULL) {
  217. memcpy((LPVOID)((LPBYTE)_String + _StringLength),
  218. (LPVOID)String,
  219. len + 1
  220. );
  221. _StringLength += len;
  222. } else {
  223. _StringLength = 0;
  224. _BufferLength = 0;
  225. SetError(TRUE);
  226. }
  227. }
  228. VOID
  229. ICSTRING::operator+=(
  230. IN char Ch
  231. )
  232. /*++
  233. Routine Description:
  234. Concatenates a character to the buffer. Reallocates it if necessary. Ch
  235. CAN be '\0'
  236. Arguments:
  237. Ch - to concatenate
  238. Return Value:
  239. None.
  240. --*/
  241. {
  242. INET_ASSERT(!IsReference());
  243. INET_ASSERT(!IsReferenced());
  244. INET_ASSERT(!IsOffset());
  245. if (IsError()) {
  246. return;
  247. }
  248. DWORD newlen = _StringLength + 2;
  249. INET_ASSERT (newlen > _StringLength);
  250. if (_BufferLength < newlen) {
  251. _String = (LPSTR)ResizeBuffer((HLOCAL)_String, newlen, FALSE);
  252. INET_ASSERT((_String == NULL) ? (newlen == 0) : TRUE);
  253. _BufferLength = newlen;
  254. }
  255. if (_String != NULL) {
  256. _String[_StringLength] = Ch;
  257. ++_StringLength;
  258. _String[_StringLength] = '\0';
  259. } else {
  260. _StringLength = 0;
  261. _BufferLength = 0;
  262. SetError(TRUE);
  263. }
  264. }
  265. VOID
  266. ICSTRING::Strncat(
  267. IN LPVOID Pointer,
  268. IN DWORD Length
  269. )
  270. /*++
  271. Routine Description:
  272. Copies Length characters from Pointer to the end of _String
  273. Arguments:
  274. Pointer - place to copy from
  275. Length - number of characters to copy
  276. Return Value:
  277. None.
  278. --*/
  279. {
  280. if (IsError()) {
  281. return;
  282. }
  283. INET_ASSERT(Pointer != NULL);
  284. INET_ASSERT(Length != 0);
  285. INET_ASSERT(_String != NULL);
  286. INET_ASSERT(!IsReference());
  287. INET_ASSERT(!IsReferenced());
  288. DWORD newLength;
  289. newLength = _StringLength + Length + 1;
  290. INET_ASSERT ((newLength > _StringLength) && (newLength > Length));
  291. if (_BufferLength < newLength) {
  292. _String = (LPSTR)ResizeBuffer((HLOCAL)_String, newLength, FALSE);
  293. _BufferLength = newLength;
  294. }
  295. if (_String != NULL) {
  296. memcpy((LPVOID)&_String[_StringLength], Pointer, Length);
  297. _StringLength += Length;
  298. INET_ASSERT(_StringLength < _BufferLength);
  299. _String[_StringLength] = '\0';
  300. } else {
  301. _StringLength = 0;
  302. _BufferLength = 0;
  303. SetError(TRUE);
  304. }
  305. }
  306. VOID
  307. ICSTRING::CreateStringBuffer(
  308. IN LPVOID Pointer,
  309. IN DWORD StringLength,
  310. IN DWORD BufferLength
  311. )
  312. /*++
  313. Routine Description:
  314. In order to avoid reallocations, if we know the size of the buffer we
  315. want for several strcat()'s, e.g., we can allocate it once, copy the
  316. initial string here, then perform multiple concatenate operations (+=)
  317. Arguments:
  318. Pointer - place to start copying from
  319. StringLength - length of string
  320. BufferLength - length of buffer required
  321. Return Value:
  322. None.
  323. --*/
  324. {
  325. INET_ASSERT(Pointer != NULL);
  326. INET_ASSERT(BufferLength > StringLength);
  327. INET_ASSERT(BufferLength != 0);
  328. //
  329. // if we currently have an offset string then initialize to a non-offset
  330. //
  331. if (IsOffset()) {
  332. Initialize();
  333. }
  334. _String = (LPSTR)ResizeBuffer(_String, BufferLength, FALSE);
  335. if (_String != NULL) {
  336. _StringLength = StringLength;
  337. _BufferLength = BufferLength;
  338. memcpy((LPVOID)_String, Pointer, _StringLength);
  339. _String[_StringLength] = '\0';
  340. SetHaveString(TRUE);
  341. SetReference(FALSE);
  342. SetReferenced(FALSE);
  343. SetOffset(FALSE);
  344. SetError(FALSE);
  345. } else {
  346. SetError(TRUE);
  347. }
  348. }
  349. VOID
  350. ICSTRING::CreateOffsetString(
  351. IN DWORD Offset,
  352. IN DWORD Length
  353. )
  354. /*++
  355. Routine Description:
  356. Create a reference ICSTRING that is an offset within another buffer
  357. Arguments:
  358. Offset - offset into buffer
  359. Length - of string
  360. Return Value:
  361. None.
  362. --*/
  363. {
  364. _String = (LPSTR)(DWORD_PTR)Offset;
  365. _StringLength = Length;
  366. _BufferLength = Length;
  367. ZapFlags();
  368. SetHaveString(TRUE); // ICSTRING initialized with non-NULL
  369. SetReference(TRUE); // reference to another string buffer
  370. SetOffset(TRUE); // offset from base
  371. SetError(FALSE);
  372. }
  373. VOID
  374. ICSTRING::CopyTo(
  375. IN LPSTR Buffer
  376. )
  377. /*++
  378. Routine Description:
  379. Copies source _String to destination Buffer
  380. Arguments:
  381. Buffer - place to copy to
  382. Return Value:
  383. None.
  384. --*/
  385. {
  386. INET_ASSERT(Buffer != NULL);
  387. INET_ASSERT(!IsOffset());
  388. memcpy((LPVOID)Buffer, (LPVOID)_String, _StringLength);
  389. Buffer[_StringLength] = '\0';
  390. }
  391. VOID
  392. ICSTRING::CopyTo(
  393. IN LPSTR Base,
  394. IN LPSTR Buffer
  395. )
  396. /*++
  397. Routine Description:
  398. Copies a based (offset) string from source Base + _String to destination
  399. Buffer
  400. Arguments:
  401. Base - value for base
  402. Buffer - place to write string
  403. Return Value:
  404. None.
  405. --*/
  406. {
  407. INET_ASSERT(Buffer != NULL);
  408. //INET_ASSERT(IsOffset() ? (Base != NULL) : (Base == NULL));
  409. memcpy((LPVOID)Buffer,
  410. IsOffset() ? (Base + (DWORD_PTR)_String) : _String,
  411. _StringLength
  412. );
  413. Buffer[_StringLength] = '\0';
  414. }
  415. VOID
  416. ICSTRING::CopyTo(
  417. IN LPSTR Buffer,
  418. IN DWORD Length
  419. )
  420. /*++
  421. Routine Description:
  422. Copies at most Length characters from source _String to destination
  423. Buffer
  424. Arguments:
  425. Buffer - place to write string
  426. Length - number of characters to copy
  427. Return Value:
  428. None.
  429. --*/
  430. {
  431. INET_ASSERT(Buffer != NULL);
  432. INET_ASSERT(!IsOffset());
  433. DWORD length = min(Length - 1, _StringLength);
  434. memcpy((LPVOID)Buffer, (LPVOID)_String, length);
  435. Buffer[length] = '\0';
  436. }
  437. VOID
  438. ICSTRING::CopyTo(
  439. IN LPSTR Buffer,
  440. IN OUT LPDWORD Length
  441. )
  442. /*++
  443. Routine Description:
  444. Copies at most *Length characters from source _String to destination
  445. Buffer. Updates *Length to be number of characters copied, not including
  446. terminating NUL
  447. Arguments:
  448. Buffer - place to write string
  449. Length - IN: length of buffer
  450. OUT: number of characters copied
  451. Return Value:
  452. None.
  453. --*/
  454. {
  455. INET_ASSERT(Buffer != NULL);
  456. INET_ASSERT(!IsOffset());
  457. DWORD length = min(*Length - 1, _StringLength);
  458. memcpy((LPVOID)Buffer, (LPVOID)_String, length);
  459. Buffer[length] = '\0';
  460. *Length = length;
  461. }