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.

420 lines
11 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. spstring.c
  5. Abstract:
  6. This module contains functions to manipulate strings.
  7. These functions would ordinarily be performed by C Runtime routines
  8. except that we want to avoid linking this device driver with
  9. the kernel crt.
  10. Author:
  11. Ted Miller (tedm) 15-Jan-1994
  12. Revision History:
  13. --*/
  14. #include "spprecmp.h"
  15. #pragma hdrstop
  16. VOID
  17. SpStringToUpper(
  18. IN PWSTR String
  19. )
  20. {
  21. for( ; *String; String++) {
  22. *String = SpToUpper(*String);
  23. }
  24. }
  25. VOID
  26. SpStringToLower(
  27. IN PWSTR String
  28. )
  29. {
  30. for( ; *String; String++) {
  31. *String = SpToLower(*String);
  32. }
  33. }
  34. PWCHAR
  35. SpFindCharFromListInString(
  36. PWSTR String,
  37. PWSTR CharList
  38. )
  39. {
  40. PWSTR wcset;
  41. while(*String) {
  42. for(wcset=CharList; *wcset; wcset++) {
  43. if(*wcset == *String) {
  44. return(String);
  45. }
  46. }
  47. String++;
  48. }
  49. return(NULL);
  50. }
  51. unsigned
  52. SpMultiByteStringToUnsigned(
  53. IN PUCHAR String,
  54. OUT PUCHAR *CharThatStoppedScan OPTIONAL
  55. )
  56. {
  57. unsigned accum = 0;
  58. while(*String) {
  59. if(isdigit(*String)) {
  60. accum *= 10;
  61. accum += *String - '0';
  62. }
  63. String++;
  64. }
  65. if(CharThatStoppedScan) {
  66. *CharThatStoppedScan = String;
  67. }
  68. return(accum);
  69. }
  70. LONG
  71. SpStringToLong(
  72. IN PWSTR String,
  73. OUT PWCHAR *EndOfValue,
  74. IN unsigned Radix
  75. )
  76. {
  77. PWSTR p;
  78. BOOLEAN Negative;
  79. LONG Accum,v;
  80. WCHAR HighestDigitAllowed,HighestLetterAllowed;
  81. WCHAR c;
  82. //
  83. // Validate radix, 0 or 2-36.
  84. //
  85. if((Radix == 1) || (Radix > 36)) {
  86. if(EndOfValue) {
  87. *EndOfValue = String;
  88. }
  89. return(0);
  90. }
  91. p = String;
  92. //
  93. // Skip whitespace.
  94. //
  95. while(SpIsSpace(*p)) {
  96. p++;
  97. }
  98. //
  99. // First char may be a plus or minus.
  100. //
  101. Negative = FALSE;
  102. if(*p == L'-') {
  103. Negative = TRUE;
  104. p++;
  105. } else {
  106. if(*p == L'+') {
  107. p++;
  108. }
  109. }
  110. if(!Radix) {
  111. if(*p == L'0') {
  112. //
  113. // Octal number
  114. //
  115. Radix = 8;
  116. p++;
  117. if((*p == L'x') || (*p == L'X')) {
  118. //
  119. // hex number
  120. //
  121. Radix = 16;
  122. p++;
  123. }
  124. } else {
  125. Radix = 10;
  126. }
  127. }
  128. HighestDigitAllowed = (Radix < 10) ? L'0'+(WCHAR)(Radix-1) : L'9';
  129. HighestLetterAllowed = (Radix > 10) ? L'A'+(WCHAR)(Radix-11) : 0;
  130. Accum = 0;
  131. while(1) {
  132. c = *p;
  133. if((c >= L'0') && (c <= HighestDigitAllowed)) {
  134. v = c - L'0';
  135. } else {
  136. c = SpToUpper(c);
  137. if((c >= L'A') && (c <= HighestLetterAllowed)) {
  138. v = c - L'A' + 10;
  139. } else {
  140. break;
  141. }
  142. }
  143. Accum *= Radix;
  144. Accum += v;
  145. p++;
  146. }
  147. if(EndOfValue) {
  148. *EndOfValue = p;
  149. }
  150. return(Negative ? (0-Accum) : Accum);
  151. }
  152. PWCHAR
  153. SpConvertMultiSzStrToWstr(
  154. IN PCHAR Source,
  155. IN ULONG Length
  156. )
  157. {
  158. NTSTATUS status;
  159. PCHAR s, sourceEnd;
  160. PWCHAR dest, d;
  161. ANSI_STRING ansiString;
  162. UNICODE_STRING unicodeString;
  163. if (Length <= 2) {
  164. return NULL;
  165. }
  166. #if DBG
  167. for (s = Source; *s != '\0'; s += strlen(s) + 1) {
  168. }
  169. ASSERT(Length == (ULONG)(s - Source) + 1);
  170. #endif
  171. dest = SpMemAlloc(Length * sizeof(WCHAR));
  172. if (dest) {
  173. s = Source;
  174. for (sourceEnd = s + Length, d = dest;
  175. s < sourceEnd && *s != '\0';
  176. s += strlen(s) + 1) {
  177. RtlInitAnsiString(&ansiString, s);
  178. status = RtlAnsiStringToUnicodeString(&unicodeString, &ansiString, TRUE);
  179. if (!NT_SUCCESS(status)) {
  180. SpMemFree(dest);
  181. return NULL;
  182. }
  183. RtlCopyMemory(d, unicodeString.Buffer, unicodeString.Length + sizeof(UNICODE_NULL));
  184. d += (unicodeString.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR);
  185. RtlFreeUnicodeString(&unicodeString);
  186. }
  187. if (s < sourceEnd) {
  188. *d = UNICODE_NULL;
  189. }
  190. }
  191. return dest;
  192. }
  193. PCHAR
  194. SpConvertMultiSzWstrToStr(
  195. IN PWCHAR Source,
  196. IN ULONG Length
  197. )
  198. {
  199. NTSTATUS status;
  200. PWCHAR s, sourceEnd;
  201. PCHAR dest, d;
  202. ANSI_STRING ansiString;
  203. UNICODE_STRING unicodeString;
  204. if (Length <= 2) {
  205. return NULL;
  206. }
  207. #if DBG
  208. for (s = Source; *s != UNICODE_NULL; s += wcslen(s) + 1) {
  209. }
  210. ASSERT(Length == (ULONG)(s - Source) + 1);
  211. #endif
  212. dest = SpMemAlloc(Length * sizeof(CHAR));
  213. if (dest) {
  214. s = Source;
  215. for (sourceEnd = s + Length, d = dest;
  216. s < sourceEnd && *s != UNICODE_NULL;
  217. s += wcslen(s) + 1) {
  218. RtlInitUnicodeString(&unicodeString, s);
  219. status = RtlUnicodeStringToAnsiString(&ansiString, &unicodeString, TRUE);
  220. if (!NT_SUCCESS(status)) {
  221. SpMemFree(dest);
  222. return NULL;
  223. }
  224. RtlCopyMemory(d, ansiString.Buffer, ansiString.Length + 1);
  225. d += ansiString.Length + 1;
  226. RtlFreeAnsiString(&ansiString);
  227. }
  228. if (s < sourceEnd) {
  229. *d = '\0';
  230. }
  231. }
  232. return dest;
  233. }
  234. UCHAR _SpCharTypes[CTSIZE] = {
  235. _SP_NONE, /* 00 (NUL) */
  236. _SP_NONE, /* 01 (SOH) */
  237. _SP_NONE, /* 02 (STX) */
  238. _SP_NONE, /* 03 (ETX) */
  239. _SP_NONE, /* 04 (EOT) */
  240. _SP_NONE, /* 05 (ENQ) */
  241. _SP_NONE, /* 06 (ACK) */
  242. _SP_NONE, /* 07 (BEL) */
  243. _SP_NONE, /* 08 (BS) */
  244. _SP_SPACE, /* 09 (HT) */
  245. _SP_SPACE, /* 0A (LF) */
  246. _SP_SPACE, /* 0B (VT) */
  247. _SP_SPACE, /* 0C (FF) */
  248. _SP_SPACE, /* 0D (CR) */
  249. _SP_NONE, /* 0E (SI) */
  250. _SP_NONE, /* 0F (SO) */
  251. _SP_NONE, /* 10 (DLE) */
  252. _SP_NONE, /* 11 (DC1) */
  253. _SP_NONE, /* 12 (DC2) */
  254. _SP_NONE, /* 13 (DC3) */
  255. _SP_NONE, /* 14 (DC4) */
  256. _SP_NONE, /* 15 (NAK) */
  257. _SP_NONE, /* 16 (SYN) */
  258. _SP_NONE, /* 17 (ETB) */
  259. _SP_NONE, /* 18 (CAN) */
  260. _SP_NONE, /* 19 (EM) */
  261. _SP_NONE, /* 1A (SUB) */
  262. _SP_NONE, /* 1B (ESC) */
  263. _SP_NONE, /* 1C (FS) */
  264. _SP_NONE, /* 1D (GS) */
  265. _SP_NONE, /* 1E (RS) */
  266. _SP_NONE, /* 1F (US) */
  267. _SP_SPACE, /* 20 SPACE */
  268. _SP_NONE, /* 21 ! */
  269. _SP_NONE, /* 22 " */
  270. _SP_NONE, /* 23 # */
  271. _SP_NONE, /* 24 $ */
  272. _SP_NONE, /* 25 % */
  273. _SP_NONE, /* 26 & */
  274. _SP_NONE, /* 27 ' */
  275. _SP_NONE, /* 28 ( */
  276. _SP_NONE, /* 29 ) */
  277. _SP_NONE, /* 2A * */
  278. _SP_NONE, /* 2B + */
  279. _SP_NONE, /* 2C , */
  280. _SP_NONE, /* 2D - */
  281. _SP_NONE, /* 2E . */
  282. _SP_NONE, /* 2F / */
  283. _SP_DIGIT + _SP_XDIGIT, /* 30 0 */
  284. _SP_DIGIT + _SP_XDIGIT, /* 31 1 */
  285. _SP_DIGIT + _SP_XDIGIT, /* 32 2 */
  286. _SP_DIGIT + _SP_XDIGIT, /* 33 3 */
  287. _SP_DIGIT + _SP_XDIGIT, /* 34 4 */
  288. _SP_DIGIT + _SP_XDIGIT, /* 35 5 */
  289. _SP_DIGIT + _SP_XDIGIT, /* 36 6 */
  290. _SP_DIGIT + _SP_XDIGIT, /* 37 7 */
  291. _SP_DIGIT + _SP_XDIGIT, /* 38 8 */
  292. _SP_DIGIT + _SP_XDIGIT, /* 39 9 */
  293. _SP_NONE, /* 3A : */
  294. _SP_NONE, /* 3B ; */
  295. _SP_NONE, /* 3C < */
  296. _SP_NONE, /* 3D = */
  297. _SP_NONE, /* 3E > */
  298. _SP_NONE, /* 3F ? */
  299. _SP_NONE, /* 40 @ */
  300. _SP_UPPER + _SP_XDIGIT, /* 41 A */
  301. _SP_UPPER + _SP_XDIGIT, /* 42 B */
  302. _SP_UPPER + _SP_XDIGIT, /* 43 C */
  303. _SP_UPPER + _SP_XDIGIT, /* 44 D */
  304. _SP_UPPER + _SP_XDIGIT, /* 45 E */
  305. _SP_UPPER + _SP_XDIGIT, /* 46 F */
  306. _SP_UPPER, /* 47 G */
  307. _SP_UPPER, /* 48 H */
  308. _SP_UPPER, /* 49 I */
  309. _SP_UPPER, /* 4A J */
  310. _SP_UPPER, /* 4B K */
  311. _SP_UPPER, /* 4C L */
  312. _SP_UPPER, /* 4D M */
  313. _SP_UPPER, /* 4E N */
  314. _SP_UPPER, /* 4F O */
  315. _SP_UPPER, /* 50 P */
  316. _SP_UPPER, /* 51 Q */
  317. _SP_UPPER, /* 52 R */
  318. _SP_UPPER, /* 53 S */
  319. _SP_UPPER, /* 54 T */
  320. _SP_UPPER, /* 55 U */
  321. _SP_UPPER, /* 56 V */
  322. _SP_UPPER, /* 57 W */
  323. _SP_UPPER, /* 58 X */
  324. _SP_UPPER, /* 59 Y */
  325. _SP_UPPER, /* 5A Z */
  326. _SP_NONE, /* 5B [ */
  327. _SP_NONE, /* 5C \ */
  328. _SP_NONE, /* 5D ] */
  329. _SP_NONE, /* 5E ^ */
  330. _SP_NONE, /* 5F _ */
  331. _SP_NONE, /* 60 ` */
  332. _SP_LOWER + _SP_XDIGIT, /* 61 a */
  333. _SP_LOWER + _SP_XDIGIT, /* 62 b */
  334. _SP_LOWER + _SP_XDIGIT, /* 63 c */
  335. _SP_LOWER + _SP_XDIGIT, /* 64 d */
  336. _SP_LOWER + _SP_XDIGIT, /* 65 e */
  337. _SP_LOWER + _SP_XDIGIT, /* 66 f */
  338. _SP_LOWER, /* 67 g */
  339. _SP_LOWER, /* 68 h */
  340. _SP_LOWER, /* 69 i */
  341. _SP_LOWER, /* 6A j */
  342. _SP_LOWER, /* 6B k */
  343. _SP_LOWER, /* 6C l */
  344. _SP_LOWER, /* 6D m */
  345. _SP_LOWER, /* 6E n */
  346. _SP_LOWER, /* 6F o */
  347. _SP_LOWER, /* 70 p */
  348. _SP_LOWER, /* 71 q */
  349. _SP_LOWER, /* 72 r */
  350. _SP_LOWER, /* 73 s */
  351. _SP_LOWER, /* 74 t */
  352. _SP_LOWER, /* 75 u */
  353. _SP_LOWER, /* 76 v */
  354. _SP_LOWER, /* 77 w */
  355. _SP_LOWER, /* 78 x */
  356. _SP_LOWER, /* 79 y */
  357. _SP_LOWER /* 7A z */
  358. };