diff options
Diffstat (limited to 'src/pal/src/cruntime/mbstring.cpp')
-rw-r--r-- | src/pal/src/cruntime/mbstring.cpp | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/src/pal/src/cruntime/mbstring.cpp b/src/pal/src/cruntime/mbstring.cpp new file mode 100644 index 0000000000..dd4bcbbdce --- /dev/null +++ b/src/pal/src/cruntime/mbstring.cpp @@ -0,0 +1,257 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*++ + + + +Module Name: + + mbstring.c + +Abstract: + + Implementation of the multi-byte string functions in the C runtime library that + are Windows specific. + +Implementation Notes: + + Assuming it is not possible to change multi-byte code page using + the PAL (_setmbcp does not seem to be required), these functions + should have a trivial implementation (treat as single-byte). If it + is possible, then support for multi-byte code pages will have to + be implemented before these functions can behave correctly for + multi-byte strings. + + + +--*/ + +#include "pal/palinternal.h" +#include "pal/dbgmsg.h" + + +SET_DEFAULT_DEBUG_CHANNEL(CRT); + + +/*++ +Function: + _mbslen + +Determines the number of characters (code points) in a multibyte +character string. + +Parameters + +string Points to a multibyte character string. + +Return Values + +The mbslen subroutine returns the number of multibyte characters in a +multibyte character string. It returns 0 if the string parameter +points to a null character or if a character cannot be formed from the +string pointed to by this parameter. + +--*/ +size_t +__cdecl +_mbslen( + const unsigned char *string) +{ + size_t ret = 0; + CPINFO cpinfo; + PERF_ENTRY(_mbslen); + ENTRY("_mbslen (string=%p (%s))\n", string, string); + + if (string) + { + if (GetCPInfo(CP_ACP, &cpinfo) && cpinfo.MaxCharSize == 1) + { + ret = strlen((const char*)string); + } + else + { + while (*string) + { + if (IsDBCSLeadByteEx(CP_ACP, *string)) + { + ++string; + } + ++string; + ++ret; + } + } + } + + LOGEXIT("_mbslen returning size_t %u\n", ret); + PERF_EXIT(_mbslen); + return ret; +} + +/*++ +Function: + _mbsinc + +Return Value + +Returns a pointer to the character that immediately follows string. + +Parameter + +string Character pointer + +Remarks + +The _mbsinc function returns a pointer to the first byte of the +multibyte character that immediately follows string. + +--*/ +unsigned char * +__cdecl +_mbsinc( + const unsigned char *string) +{ + unsigned char *ret; + + PERF_ENTRY(_mbsinc); + ENTRY("_mbsinc (string=%p)\n", string); + + if (string == NULL) + { + ret = NULL; + } + else + { + ret = (unsigned char *) string; + if (IsDBCSLeadByteEx(CP_ACP, *ret)) + { + ++ret; + } + ++ret; + } + + LOGEXIT("_mbsinc returning unsigned char* %p (%s)\n", ret, ret); + PERF_EXIT(_mbsinc); + return ret; +} + + +/*++ +Function: + _mbsninc + +Return Value + +Returns a pointer to string after string has been incremented by count +characters, or NULL if the supplied pointer is NULL. If count is +greater than or equal to the number of characters in string, the +result is undefined. + +Parameters + +string Source string +count Number of characters to increment string pointer + +Remarks + +The _mbsninc function increments string by count multibyte +characters. _mbsninc recognizes multibyte-character sequences +according to the multibyte code page currently in use. + +--*/ +unsigned char * +__cdecl +_mbsninc( + const unsigned char *string, size_t count) +{ + unsigned char *ret; + CPINFO cpinfo; + + PERF_ENTRY(_mbsninc); + ENTRY("_mbsninc (string=%p, count=%lu)\n", string, count); + if (string == NULL) + { + ret = NULL; + } + else + { + ret = (unsigned char *) string; + if (GetCPInfo(CP_ACP, &cpinfo) && cpinfo.MaxCharSize == 1) + { + ret += min(count, strlen((const char*)string)); + } + else + { + while (count-- && (*ret != 0)) + { + if (IsDBCSLeadByteEx(CP_ACP, *ret)) + { + ++ret; + } + ++ret; + } + } + } + LOGEXIT("_mbsninc returning unsigned char* %p (%s)\n", ret, ret); + PERF_EXIT(_mbsninc); + return ret; +} + +/*++ +Function: + _mbsdec + +Return Value + +_mbsdec returns a pointer to the character that immediately precedes +current; _mbsdec returns NULL if the value of start is greater than or +equal to that of current. + +Parameters + +start Pointer to first byte of any multibyte character in the source + string; start must precede current in the source string + +current Pointer to first byte of any multibyte character in the source + string; current must follow start in the source string + +--*/ +unsigned char * +__cdecl +_mbsdec( + const unsigned char *start, + const unsigned char *current) +{ + unsigned char *ret; + unsigned char *strPtr; + CPINFO cpinfo; + + PERF_ENTRY(_mbsdec); + ENTRY("_mbsdec (start=%p, current=%p)\n", start, current); + + if (current <= start) + { + ret = NULL; + } + else if (GetCPInfo(CP_ACP, &cpinfo) && cpinfo.MaxCharSize == 1) + { + ret = (unsigned char *) current - 1; + } + else + { + ret = strPtr = (unsigned char *) start; + while (strPtr < current) + { + ret = strPtr; + if (IsDBCSLeadByteEx(CP_ACP, *strPtr)) + { + ++strPtr; + } + ++strPtr; + } + } + LOGEXIT("_mbsdec returning unsigned int %p (%s)\n", ret, ret); + PERF_EXIT(_mbsdec); + return ret; +} |