summaryrefslogtreecommitdiff
path: root/src/pal/src/cruntime/mbstring.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pal/src/cruntime/mbstring.cpp')
-rw-r--r--src/pal/src/cruntime/mbstring.cpp257
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;
+}