Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/mingw/mingwex/wcrtomb.c')
-rwxr-xr-xwinsup/mingw/mingwex/wcrtomb.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/winsup/mingw/mingwex/wcrtomb.c b/winsup/mingw/mingwex/wcrtomb.c
new file mode 100755
index 000000000..08a5fccae
--- /dev/null
+++ b/winsup/mingw/mingwex/wcrtomb.c
@@ -0,0 +1,94 @@
+#include "mb_wc_common.h"
+#include <wchar.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+
+static int __MINGW_ATTRIB_NONNULL(1)
+ __wcrtomb_cp (char *dst, wchar_t wc, const unsigned int cp,
+ const unsigned int mb_max)
+{
+ if (wc > 255)
+ {
+ errno = EILSEQ;
+ return -1;
+ }
+
+ if (cp == 0)
+ {
+ *dst = (char) wc;
+ return 1;
+ }
+ else
+ {
+ int invalid_char = 0;
+
+ int size = WideCharToMultiByte(get_cp_from_locale(),
+ 0 /* Is this correct flag? */,
+ &wc, 1, dst, mb_max,
+ NULL, &invalid_char);
+ if (size == 0 || invalid_char)
+ {
+ errno = EILSEQ;
+ return -1;
+ }
+ return size;
+ }
+}
+
+size_t
+wcrtomb (char *dst, wchar_t wc, mbstate_t * __UNUSED_PARAM (ps))
+{
+ char byte_bucket [MB_LEN_MAX];
+ char* tmp_dst = dst ? dst : byte_bucket;
+ return (size_t)__wcrtomb_cp (tmp_dst, wc, get_cp_from_locale (),
+ MB_CUR_MAX);
+}
+
+size_t wcsrtombs (char *dst, const wchar_t **src, size_t len,
+ mbstate_t * __UNUSED_PARAM (ps))
+{
+ int ret = 0;
+ size_t n = 0;
+ const unsigned int cp = get_cp_from_locale();
+ const unsigned int mb_max = MB_CUR_MAX;
+
+ if (src == NULL || *src == NULL) /* undefined behavior */
+ return 0;
+
+ if (dst != NULL)
+ {
+ const wchar_t ** saved_src = src;
+ while (n < len)
+ {
+ if ((ret = __wcrtomb_cp (dst, **src, cp, mb_max)) <= 0)
+ return (size_t) -1;
+ n += ret;
+ dst += ret;
+ if (*(dst - 1) == '\0')
+ {
+ *saved_src = (wchar_t) NULL;;
+ return (n - 1);
+ }
+ *src++;
+ }
+ }
+ else
+ {
+ char byte_bucket [MB_LEN_MAX];
+ while (n < len)
+ {
+ if ((ret = __wcrtomb_cp (byte_bucket, **src, cp, mb_max))
+ <= 0)
+ return (size_t) -1;
+ n += ret;
+ if (byte_bucket [ret - 1] == '\0')
+ return (n - 1);
+ *src++;
+ }
+ }
+ return n;
+}