1
0

wstring.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444
  1. /*++
  2. Copyright (c) 2013 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. wstring.c
  9. Abstract:
  10. This module implements string and memory manipulation routines for the C
  11. library.
  12. Author:
  13. Evan Green 28-Aug-2012
  14. Environment:
  15. User Mode C Library
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include "libcp.h"
  21. #include <assert.h>
  22. #include <ctype.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <wchar.h>
  26. #include <wctype.h>
  27. //
  28. // ---------------------------------------------------------------- Definitions
  29. //
  30. //
  31. // ------------------------------------------------------ Data Type Definitions
  32. //
  33. //
  34. // ----------------------------------------------- Internal Function Prototypes
  35. //
  36. //
  37. // -------------------------------------------------------------------- Globals
  38. //
  39. //
  40. // ------------------------------------------------------------------ Functions
  41. //
  42. LIBC_API
  43. wchar_t *
  44. wmemchr (
  45. const wchar_t *Buffer,
  46. wchar_t Character,
  47. size_t Size
  48. )
  49. /*++
  50. Routine Description:
  51. This routine attempts to locate the first occurrence of the given character
  52. within the given buffer.
  53. Arguments:
  54. Buffer - Supplies a pointer to the buffer of wide characters.
  55. Character - Supplies the wide character to locate.
  56. Size - Supplies the size of the buffer, in characters.
  57. Return Value:
  58. Returns a pointer to the first occurrence of the character within the
  59. buffer on success.
  60. NULL on failure.
  61. --*/
  62. {
  63. while (Size != 0) {
  64. if (*Buffer == Character) {
  65. return (wchar_t *)Buffer;
  66. }
  67. Buffer += 1;
  68. Size -= 1;
  69. }
  70. return NULL;
  71. }
  72. LIBC_API
  73. int
  74. wmemcmp (
  75. const wchar_t *Left,
  76. const wchar_t *Right,
  77. size_t Size
  78. )
  79. /*++
  80. Routine Description:
  81. This routine compares two wide strings of memory byte for byte. The null
  82. wide character is not treated specially here.
  83. Arguments:
  84. Left - Supplies the first wide string of the comparison.
  85. Right - Supplies the second wide string of the comparison.
  86. Size - Supplies the maximum number of characters to compare.
  87. Return Value:
  88. >0 if Left > Right.
  89. 0 is Left == Right.
  90. <0 if Left <= Right.
  91. --*/
  92. {
  93. wchar_t Difference;
  94. size_t Index;
  95. for (Index = 0; Index < Size; Index += 1) {
  96. Difference = *Left - *Right;
  97. if (Difference != 0) {
  98. return Difference;
  99. }
  100. Left += 1;
  101. Left += 1;
  102. }
  103. return 0;
  104. }
  105. LIBC_API
  106. wchar_t *
  107. wmemcpy (
  108. wchar_t *Destination,
  109. const wchar_t *Source,
  110. size_t CharacterCount
  111. )
  112. /*++
  113. Routine Description:
  114. This routine copies characters directly between buffers. The null wide
  115. character is not treated specially here.
  116. Arguments:
  117. Destination - Supplies a pointer to the destination of the copy.
  118. Source - Supplies a pointer to the source data to copy.
  119. CharacterCount - Supplies the number of characters to copy.
  120. Return Value:
  121. Returns the destination parameter.
  122. --*/
  123. {
  124. wchar_t *Result;
  125. Result = RtlCopyMemory(Destination,
  126. (PVOID)Source,
  127. CharacterCount * sizeof(wchar_t));
  128. return Result;
  129. }
  130. LIBC_API
  131. wchar_t *
  132. wmemmove (
  133. wchar_t *Destination,
  134. const wchar_t *Source,
  135. size_t CharacterCount
  136. )
  137. /*++
  138. Routine Description:
  139. This routine copies bytes between buffers. Copying takes place as if the
  140. bytes are first copied into a temporary buffer that does not overlap the
  141. two buffers, and then are copied to the destination.
  142. Arguments:
  143. Destination - Supplies a pointer to the destination of the copy.
  144. Source - Supplies a pointer to the source data to copy.
  145. CharacterCount - Supplies the number of characters to copy.
  146. Return Value:
  147. Returns the destination parameter.
  148. --*/
  149. {
  150. PWCHAR DestinationBytes;
  151. PWCHAR SourceBytes;
  152. //
  153. // Copy the bytes backwards if the source begins before the destination
  154. // and overlaps.
  155. //
  156. if ((Source < Destination) && (Source + CharacterCount > Destination)) {
  157. DestinationBytes = Destination;
  158. SourceBytes = (PWCHAR)Source;
  159. while (CharacterCount != 0) {
  160. DestinationBytes[CharacterCount - 1] =
  161. SourceBytes[CharacterCount - 1];
  162. CharacterCount -= 1;
  163. }
  164. } else {
  165. RtlCopyMemory(Destination,
  166. (PVOID)Source,
  167. CharacterCount * sizeof(wchar_t));
  168. }
  169. return Destination;
  170. }
  171. LIBC_API
  172. wchar_t *
  173. wmemset (
  174. wchar_t *Destination,
  175. wchar_t Character,
  176. size_t CharacterCount
  177. )
  178. /*++
  179. Routine Description:
  180. This routine copies the given character repeatedly into the given buffer.
  181. Arguments:
  182. Destination - Supplies a pointer to the destination of the copy.
  183. Character - Supplies a character (it will be cast down to a character) to
  184. fill the buffer with.
  185. CharacterCount - Supplies the number of characters to set.
  186. Return Value:
  187. Returns the destination parameter.
  188. --*/
  189. {
  190. size_t Index;
  191. for (Index = 0; Index < CharacterCount; Index += 1) {
  192. Destination[Index] = Character;
  193. }
  194. return Destination;
  195. }
  196. LIBC_API
  197. wchar_t *
  198. wcschr (
  199. const wchar_t *String,
  200. wchar_t Character
  201. )
  202. /*++
  203. Routine Description:
  204. This routine finds the first instance of the given character (converted to
  205. a char) in the given wide string.
  206. Arguments:
  207. String - Supplies a pointer to the string to search for the character in.
  208. Character - Supplies the character to search for.
  209. Return Value:
  210. Returns a pointer to the first occurrence of the character in the given
  211. string, or NULL if the character doesn't exist in the string.
  212. --*/
  213. {
  214. while (TRUE) {
  215. if (*String == Character) {
  216. return (wchar_t *)String;
  217. }
  218. if (*String == L'\0') {
  219. break;
  220. }
  221. String += 1;
  222. }
  223. return NULL;
  224. }
  225. LIBC_API
  226. wchar_t *
  227. wcsrchr (
  228. const wchar_t *String,
  229. wchar_t Character
  230. )
  231. /*++
  232. Routine Description:
  233. This routine finds the last occurrence of the given character (converted to
  234. a char) in the given wide string.
  235. Arguments:
  236. String - Supplies a pointer to the wide string to search for the character
  237. in.
  238. Character - Supplies the character to search for.
  239. Return Value:
  240. Returns a pointer to the last occurrence of the character in the given
  241. string, or NULL if the character doesn't exist in the string.
  242. --*/
  243. {
  244. wchar_t *LastOccurrence;
  245. LastOccurrence = NULL;
  246. while (TRUE) {
  247. if (*String == Character) {
  248. LastOccurrence = (wchar_t *)String;
  249. }
  250. if (*String == L'\0') {
  251. break;
  252. }
  253. String += 1;
  254. }
  255. return LastOccurrence;
  256. }
  257. LIBC_API
  258. size_t
  259. wcslen (
  260. const wchar_t *String
  261. )
  262. /*++
  263. Routine Description:
  264. This routine computes the length of the given string, not including the
  265. null terminator.
  266. Arguments:
  267. String - Supplies a pointer to the string whose length should be computed.
  268. Return Value:
  269. Returns the length of the string, not including the null terminator.
  270. --*/
  271. {
  272. return RtlStringLengthWide((PWSTR)String);
  273. }
  274. LIBC_API
  275. int
  276. wcswidth (
  277. const wchar_t *String,
  278. size_t Size
  279. )
  280. /*++
  281. Routine Description:
  282. This routine computes the display width of the given string.
  283. Arguments:
  284. String - Supplies a pointer to the string whose display width should be
  285. computed.
  286. Size - Supplies the size of the string in characters.
  287. Return Value:
  288. Returns the number of columns the given string occupies.
  289. -1 if one of the characters is invalid.
  290. --*/
  291. {
  292. int Total;
  293. int Width;
  294. Total = 0;
  295. while ((*String != L'\0') && (Size != 0)) {
  296. Width = wcwidth(*String);
  297. if (Width < 0) {
  298. return -1;
  299. }
  300. Total += Width;
  301. String += 1;
  302. Size -= 1;
  303. }
  304. return Total;
  305. }
  306. LIBC_API
  307. wchar_t *
  308. wcscpy (
  309. wchar_t *DestinationString,
  310. const wchar_t *SourceString
  311. )
  312. /*++
  313. Routine Description:
  314. This routine copies the given source wide string over the given destination
  315. string. This routine should be avoided if at all possible as it can be the
  316. cause of buffer overflow problems. Use functions like wcsncpy that place
  317. explicit bounds on the destination buffer.
  318. Arguments:
  319. DestinationString - Supplies a pointer where the source string will be
  320. copied to.
  321. SourceString - Supplies the string that will be copied.
  322. Return Value:
  323. Returns the destination string.
  324. --*/
  325. {
  326. wchar_t *OriginalDestination;
  327. OriginalDestination = DestinationString;
  328. while (*SourceString != L'\0') {
  329. *DestinationString = *SourceString;
  330. SourceString += 1;
  331. DestinationString += 1;
  332. }
  333. *DestinationString = L'\0';
  334. return OriginalDestination;
  335. }
  336. LIBC_API
  337. wchar_t *
  338. wcsncpy (
  339. wchar_t *DestinationString,
  340. const wchar_t *SourceString,
  341. size_t CharacterCount
  342. )
  343. /*++
  344. Routine Description:
  345. This routine copies the given source string over the given destination
  346. string.
  347. Arguments:
  348. DestinationString - Supplies a pointer where the source string will be
  349. copied to.
  350. SourceString - Supplies the string that will be copied.
  351. CharacterCount - Supplies the maximum number of characters to copy. If the
  352. source string is shorter than this value, then only characters up to
  353. and including the null terminator will be copied. The remaining
  354. characters in the destination string will be zeroed out. If the source
  355. string is longer than this value, then the destination string will not
  356. be null terminated.
  357. Return Value:
  358. Returns the destination string.
  359. --*/
  360. {
  361. size_t ByteIndex;
  362. wchar_t *OriginalDestination;
  363. OriginalDestination = DestinationString;
  364. for (ByteIndex = 0; ByteIndex < CharacterCount; ByteIndex += 1) {
  365. *DestinationString = *SourceString;
  366. if (*SourceString == L'\0') {
  367. break;
  368. }
  369. DestinationString += 1;
  370. SourceString += 1;
  371. }
  372. while (ByteIndex < CharacterCount) {
  373. *DestinationString = L'\0';
  374. DestinationString += 1;
  375. ByteIndex += 1;
  376. }
  377. return OriginalDestination;
  378. }
  379. LIBC_API
  380. wchar_t *
  381. wcscat (
  382. wchar_t *DestinationString,
  383. const wchar_t *SourceString
  384. )
  385. /*++
  386. Routine Description:
  387. This routine appends bytes to the end of the given wide string. The
  388. destination string will always be returned with a null terminator.
  389. Arguments:
  390. DestinationString - Supplies a pointer containing the string that will be
  391. appended to.
  392. SourceString - Supplies a pointer to the string to append.
  393. Return Value:
  394. Returns the destination string.
  395. --*/
  396. {
  397. return wcsncat(DestinationString, SourceString, MAX_ULONG);
  398. }
  399. LIBC_API
  400. wchar_t *
  401. wcsncat (
  402. wchar_t *DestinationString,
  403. const wchar_t *SourceString,
  404. size_t CharactersToAppend
  405. )
  406. /*++
  407. Routine Description:
  408. This routine appends characters to the end of the given wide string. The
  409. destination string will always be returned with a wide null terminator.
  410. Arguments:
  411. DestinationString - Supplies a pointer containing the string that will be
  412. appended to.
  413. SourceString - Supplies a pointer to the string to append.
  414. CharactersToAppend - Supplies the number of bytes of the source string to
  415. append to the destination, NOT including the null terminator. This
  416. means that the destination string buffer must be at least large enough
  417. to take this number plus one bytes on the end of the existing string. If
  418. the source string is shorter than this value, this routine will stop at
  419. the terminator.
  420. Return Value:
  421. Returns the destination string.
  422. --*/
  423. {
  424. size_t ByteIndex;
  425. wchar_t *OriginalDestination;
  426. OriginalDestination = DestinationString;
  427. //
  428. // First find the end of the string.
  429. //
  430. while (*DestinationString != L'\0') {
  431. DestinationString += 1;
  432. }
  433. //
  434. // Now copy as many bytes as are requested over.
  435. //
  436. for (ByteIndex = 0; ByteIndex < CharactersToAppend; ByteIndex += 1) {
  437. //
  438. // Stop if the source ended.
  439. //
  440. if (*SourceString == L'\0') {
  441. break;
  442. }
  443. *DestinationString = *SourceString;
  444. DestinationString += 1;
  445. SourceString += 1;
  446. }
  447. //
  448. // Always null terminate the destination.
  449. //
  450. *DestinationString = L'\0';
  451. return OriginalDestination;
  452. }
  453. LIBC_API
  454. int
  455. wcscmp (
  456. const wchar_t *String1,
  457. const wchar_t *String2
  458. )
  459. /*++
  460. Routine Description:
  461. This routine compares two wide strings for equality.
  462. Arguments:
  463. String1 - Supplies the first wide string to compare.
  464. String2 - Supplies the second wide string to compare.
  465. Return Value:
  466. 0 if the strings are equal all the way through their null terminators.
  467. Non-zero if the strings are different. The sign of the return value will be
  468. determined by the sign of the difference between the values of the first
  469. pair of bytes (both interpreted as type unsigned char) that differ in the
  470. strings being compared.
  471. --*/
  472. {
  473. return wcsncmp(String1, String2, (size_t)-1);
  474. }
  475. LIBC_API
  476. int
  477. wcsicmp (
  478. const wchar_t *String1,
  479. const wchar_t *String2
  480. )
  481. /*++
  482. Routine Description:
  483. This routine compares two wide strings for equality, ignoring case.
  484. Arguments:
  485. String1 - Supplies the first wide string to compare.
  486. String2 - Supplies the second wide string to compare.
  487. Return Value:
  488. 0 if the strings are equal all the way through their null terminators.
  489. Non-zero if the strings are different. The sign of the return value will be
  490. determined by the sign of the difference between the values of the first
  491. pair of bytes (both interpreted as type unsigned char) that differ in the
  492. strings being compared.
  493. --*/
  494. {
  495. return wcsncasecmp(String1, String2, (size_t)-1);
  496. }
  497. LIBC_API
  498. int
  499. wcsncmp (
  500. const wchar_t *String1,
  501. const wchar_t *String2,
  502. size_t CharacterCount
  503. )
  504. /*++
  505. Routine Description:
  506. This routine compares two wide strings for equality, up to a bounded amount.
  507. Arguments:
  508. String1 - Supplies the first wide string to compare.
  509. String2 - Supplies the second wide string to compare.
  510. CharacterCount - Supplies the maximum number of characters to compare.
  511. Characters after a null terminator in either string are not compared.
  512. Return Value:
  513. 0 if the strings are equal all the way through their null terminators or
  514. character count.
  515. Non-zero if the strings are different. The sign of the return value will be
  516. determined by the sign of the difference between the values of the first
  517. pair of bytes (both interpreted as type unsigned char) that differ in the
  518. strings being compared.
  519. --*/
  520. {
  521. while (CharacterCount != 0) {
  522. if (*String1 != *String2) {
  523. return *String1 - *String2;
  524. }
  525. if (*String1 == L'\0') {
  526. break;
  527. }
  528. String1 += 1;
  529. String2 += 1;
  530. CharacterCount -= 1;
  531. }
  532. return 0;
  533. }
  534. LIBC_API
  535. int
  536. wcsnicmp (
  537. const wchar_t *String1,
  538. const wchar_t *String2,
  539. size_t CharacterCount
  540. )
  541. /*++
  542. Routine Description:
  543. This routine compares two wide strings for equality, ignoring case, up to a
  544. bounded amount.
  545. Arguments:
  546. String1 - Supplies the first wide string to compare.
  547. String2 - Supplies the second wide string to compare.
  548. CharacterCount - Supplies the maximum number of characters to compare.
  549. Characters after a null terminator in either string are not compared.
  550. Return Value:
  551. 0 if the strings are equal all the way through their null terminators or
  552. character count.
  553. Non-zero if the strings are different. The sign of the return value will be
  554. determined by the sign of the difference between the values of the first
  555. pair of bytes (both interpreted as type unsigned char) that differ in the
  556. strings being compared.
  557. --*/
  558. {
  559. return wcsncasecmp(String1, String2, CharacterCount);
  560. }
  561. LIBC_API
  562. int
  563. wcscasecmp (
  564. const wchar_t *String1,
  565. const wchar_t *String2
  566. )
  567. /*++
  568. Routine Description:
  569. This routine compares two wide strings for equality, ignoring case. This
  570. routine will act for the purposes of comparison like all characters are
  571. converted to lowercase.
  572. Arguments:
  573. String1 - Supplies the first wide string to compare.
  574. String2 - Supplies the second wide string to compare.
  575. Return Value:
  576. 0 if the strings are equal all the way through their null terminators.
  577. Non-zero if the strings are different. The sign of the return value will be
  578. determined by the sign of the difference between the values of the first
  579. pair of bytes (both interpreted as type unsigned char) that differ in the
  580. strings being compared.
  581. --*/
  582. {
  583. return wcsncasecmp(String1, String2, -1);
  584. }
  585. LIBC_API
  586. int
  587. wcsncasecmp (
  588. const wchar_t *String1,
  589. const wchar_t *String2,
  590. size_t CharacterCount
  591. )
  592. /*++
  593. Routine Description:
  594. This routine compares two wide strings for equality, ignoring case, up to a
  595. bounded amount. This routine will act for the purposes of comparison like
  596. all characters are converted to lowercase.
  597. Arguments:
  598. String1 - Supplies the wide first string to compare.
  599. String2 - Supplies the wide second string to compare.
  600. CharacterCount - Supplies the maximum number of characters to compare.
  601. Characters after a null terminator in either string are not compared.
  602. Return Value:
  603. 0 if the strings are equal all the way through their null terminators or
  604. character count.
  605. Non-zero if the strings are different. The sign of the return value will be
  606. determined by the sign of the difference between the values of the first
  607. pair of bytes (both interpreted as type unsigned char) that differ in the
  608. strings being compared.
  609. --*/
  610. {
  611. wchar_t Character1;
  612. wchar_t Character2;
  613. while (CharacterCount != 0) {
  614. Character1 = towlower(*String1);
  615. Character2 = towlower(*String2);
  616. if (Character1 != Character2) {
  617. return Character1 - Character2;
  618. }
  619. if (Character1 == L'\0') {
  620. break;
  621. }
  622. String1 += 1;
  623. String2 += 1;
  624. CharacterCount -= 1;
  625. }
  626. return 0;
  627. }
  628. LIBC_API
  629. int
  630. wcscoll (
  631. const wchar_t *String1,
  632. const wchar_t *String2
  633. )
  634. /*++
  635. Routine Description:
  636. This routine compares two wide strings, both interpreted as appropriate to
  637. the LC_COLLATE category of the current locale.
  638. Arguments:
  639. String1 - Supplies a pointer to the first wide string.
  640. String2 - Supplies a pointer to the second wide string.
  641. Return Value:
  642. >0 if the first string is greater than the second string.
  643. 0 if the first string is equal to the second string.
  644. <0 if the first string is less than the second string.
  645. --*/
  646. {
  647. //
  648. // TODO: Implement collating stuff.
  649. //
  650. return wcscmp(String1, String2);
  651. }
  652. LIBC_API
  653. wchar_t *
  654. wcsdup (
  655. const wchar_t *String
  656. )
  657. /*++
  658. Routine Description:
  659. This routine returns a pointer to a newly allocated wide string which is a
  660. duplicate of the given input wide string. This returned pointer must be
  661. passed to the free function when the caller is done with it.
  662. Arguments:
  663. String - Supplies a pointer to the wide string to duplicate.
  664. Return Value:
  665. Returns a pointer to the newly allocated duplicate wide string on success.
  666. NULL on failure.
  667. --*/
  668. {
  669. size_t Length;
  670. wchar_t *NewString;
  671. if (String == NULL) {
  672. Length = 1;
  673. } else {
  674. Length = wcslen(String) + 1;
  675. }
  676. NewString = malloc(Length * sizeof(wchar_t));
  677. if (NewString == NULL) {
  678. return NULL;
  679. }
  680. wcscpy(NewString, String);
  681. return NewString;
  682. }
  683. LIBC_API
  684. wchar_t *
  685. wcspbrk (
  686. const wchar_t *String,
  687. const wchar_t *Characters
  688. )
  689. /*++
  690. Routine Description:
  691. This routine locates the first occurrence in the given wide string of any
  692. character from the given character set.
  693. Arguments:
  694. String - Supplies a pointer to the wide string to search.
  695. Characters - Supplies a pointer to a null terminated wide string containing
  696. the acceptable set of characters.
  697. Return Value:
  698. Returns a pointer within the given string to the first character in the
  699. requested set.
  700. NULL if no bytes from the set occur in the given string.
  701. --*/
  702. {
  703. const wchar_t *CurrentCharacter;
  704. while (*String != L'\0') {
  705. CurrentCharacter = Characters;
  706. while (*CurrentCharacter != L'\0') {
  707. if (*String == *CurrentCharacter) {
  708. return (wchar_t *)String;
  709. }
  710. }
  711. String += 1;
  712. }
  713. return NULL;
  714. }
  715. LIBC_API
  716. size_t
  717. wcscspn (
  718. const wchar_t *Input,
  719. const wchar_t *Characters
  720. )
  721. /*++
  722. Routine Description:
  723. This routine computes the length in bytes of the initial portion of the
  724. given input that's made up only of characters not in the given set. For
  725. example, an input of "abc123" and a set of "0123456789" would return a value
  726. of 3.
  727. Arguments:
  728. Input - Supplies a pointer to a null terminated wide string containing the
  729. string to query.
  730. Characters - Supplies a pointer to a null terminated wide string containing
  731. the set of characters.
  732. Return Value:
  733. Returns the count of initial characters in the string not in the given
  734. set.
  735. --*/
  736. {
  737. size_t Count;
  738. const wchar_t *CurrentCharacter;
  739. Count = 0;
  740. while (*Input != L'\0') {
  741. CurrentCharacter = Characters;
  742. while (*CurrentCharacter != L'\0') {
  743. if (*Input == *CurrentCharacter) {
  744. break;
  745. }
  746. CurrentCharacter += 1;
  747. }
  748. if (*CurrentCharacter != L'\0') {
  749. break;
  750. }
  751. Count += 1;
  752. Input += 1;
  753. }
  754. return Count;
  755. }
  756. LIBC_API
  757. size_t
  758. wcsspn (
  759. const wchar_t *Input,
  760. const wchar_t *Characters
  761. )
  762. /*++
  763. Routine Description:
  764. This routine computes the length in bytes of the initial portion of the
  765. given input that's made up only of characters from the given set. For
  766. example, an input of "129th" and a set of "0123456789" would return a value
  767. of 3.
  768. Arguments:
  769. Input - Supplies a pointer to a null terminated wide string containing the
  770. string to query.
  771. Characters - Supplies a pointer to a null terminated wide string containing
  772. the acceptable set of characters.
  773. Return Value:
  774. Returns the count of initial characters in the string in the given set.
  775. --*/
  776. {
  777. size_t Count;
  778. const wchar_t *CurrentCharacter;
  779. Count = 0;
  780. while (*Input != L'\0') {
  781. CurrentCharacter = Characters;
  782. while (*CurrentCharacter != L'\0') {
  783. if (*Input == *CurrentCharacter) {
  784. break;
  785. }
  786. CurrentCharacter += 1;
  787. }
  788. if (*CurrentCharacter == L'\0') {
  789. break;
  790. }
  791. Count += 1;
  792. Input += 1;
  793. }
  794. return Count;
  795. }
  796. LIBC_API
  797. wchar_t *
  798. wcsstr (
  799. const wchar_t *InputString,
  800. const wchar_t *QueryString
  801. )
  802. /*++
  803. Routine Description:
  804. This routine attempts to find the first occurrence of the wide query string
  805. in the given wide input string.
  806. Arguments:
  807. InputString - Supplies a pointer to the wide input string to search.
  808. QueryString - Supplies a pointer to the wide query string to search for.
  809. Return Value:
  810. Returns a pointer within the input string to the first instance of the
  811. query string.
  812. NULL if no instances of the query string were found in the input string.
  813. --*/
  814. {
  815. size_t QueryIndex;
  816. if ((QueryString == NULL) || (InputString == NULL)) {
  817. return NULL;
  818. }
  819. while (*InputString != L'\0') {
  820. //
  821. // Loop as long as the query string hasn't ended and it seems to be
  822. // matching the current input.
  823. //
  824. QueryIndex = 0;
  825. while ((QueryString[QueryIndex] != L'\0') &&
  826. (QueryString[QueryIndex] == InputString[QueryIndex])) {
  827. QueryIndex += 1;
  828. }
  829. if (QueryString[QueryIndex] == L'\0') {
  830. return (wchar_t *)InputString;
  831. }
  832. InputString += 1;
  833. }
  834. return NULL;
  835. }
  836. LIBC_API
  837. wchar_t *
  838. wcswcs (
  839. const wchar_t *InputString,
  840. const wchar_t *QueryString
  841. )
  842. /*++
  843. Routine Description:
  844. This routine attempts to find the first occurrence of the wide query string
  845. in the given wide input string.
  846. Arguments:
  847. InputString - Supplies a pointer to the wide input string to search.
  848. QueryString - Supplies a pointer to the wide query string to search for.
  849. Return Value:
  850. Returns a pointer within the input string to the first instance of the
  851. query string.
  852. NULL if no instances of the query string were found in the input string.
  853. --*/
  854. {
  855. return wcsstr(InputString, QueryString);
  856. }
  857. LIBC_API
  858. wchar_t *
  859. wcstok (
  860. wchar_t *InputString,
  861. const wchar_t *Separators,
  862. wchar_t **LastToken
  863. )
  864. /*++
  865. Routine Description:
  866. This routine breaks a wide string into a series of tokens delimited by any
  867. character from the given separator set. The first call passes an input
  868. string in. This routine scans looking for a non-separator character, which
  869. marks the first token. It then scans looking for a separator character, and
  870. sets that byte to the null terminator to delimit the first character.
  871. Subsequent calls should pass NULL as the input string, and the context
  872. pointer will be updated so that successive calls return the next tokens.
  873. This routine is thread safe and re-entrant so long as the same context
  874. pointer is not used by multiple threads.
  875. Arguments:
  876. InputString - Supplies a pointer to the wide input string to tokenize. If
  877. supplied, this will reset the value returned in the last token context
  878. pointer.
  879. Separators - Supplies a pointer to a null terminated wide string containing
  880. the set of characters that delimit tokens. This may vary from call to
  881. call of this routine with the same context pointer.
  882. LastToken - Supplies a pointer where a context pointer will be stored
  883. allowing this routine to keep its place and return successive tokens.
  884. Return Value:
  885. Returns a pointer to the next token on success.
  886. NULL if there are no more tokens.
  887. --*/
  888. {
  889. size_t Count;
  890. PWSTR Token;
  891. Token = InputString;
  892. if (Token == NULL) {
  893. Token = *LastToken;
  894. }
  895. if ((Token == NULL) || (*Token == L'\0')) {
  896. *LastToken = NULL;
  897. return NULL;
  898. }
  899. //
  900. // Advance past any separators.
  901. //
  902. Token += wcsspn(Token, Separators);
  903. //
  904. // If this is the end of the string, then there is no token.
  905. //
  906. if (*Token == L'\0') {
  907. *LastToken = NULL;
  908. return NULL;
  909. }
  910. //
  911. // Get the count of characters not in the set.
  912. //
  913. Count = wcscspn(Token, Separators);
  914. assert(Count != 0);
  915. //
  916. // If at the end of the string, return this last token and null out the
  917. // context pointer.
  918. //
  919. if (Token[Count] == L'\0') {
  920. *LastToken = NULL;
  921. //
  922. // Otherwise, null terminate the token and save the subsequent character
  923. // for next time.
  924. //
  925. } else {
  926. Token[Count] = L'\0';
  927. *LastToken = Token + Count + 1;
  928. }
  929. return Token;
  930. }
  931. LIBC_API
  932. size_t
  933. wcsxfrm (
  934. wchar_t *Result,
  935. const wchar_t *Input,
  936. size_t ResultSize
  937. )
  938. /*++
  939. Routine Description:
  940. This routine transforms the given input string in such a way that using
  941. strcmp on two transformed strings will return the same value as strcoll
  942. would return on the untransformed strings. The transformed string is not
  943. necessarily readable. It is used primarily if a string is going to be
  944. compared repeatedly, as it explicitly performs the transformation process
  945. once rather than on each strcoll comparison.
  946. Arguments:
  947. Result - Supplies an optional pointer where the transformed string will be
  948. returned. This can be NULL to just get the size of the transformed
  949. string.
  950. Input - Supplies a pointer to the string to transform according to the
  951. current value of LC_COLLATE.
  952. ResultSize - Supplies the size of the result buffer in bytes. This routine
  953. will not write more than this number of bytes to the result buffer.
  954. Return Value:
  955. Returns the size of the complete transform (even if a buffer is not
  956. supplied or is too small) not including the null terminator byte.
  957. --*/
  958. {
  959. size_t Length;
  960. //
  961. // TODO: Implement collating stuff.
  962. //
  963. Length = wcslen(Input);
  964. if ((Result != NULL) && (ResultSize != 0)) {
  965. wcsncpy(Result, Input, ResultSize);
  966. }
  967. return Length;
  968. }
  969. //
  970. // --------------------------------------------------------- Internal Functions
  971. //