]> git.saurik.com Git - apple/libc.git/blobdiff - locale/FreeBSD/wcsrtombs.c
Libc-1082.20.4.tar.gz
[apple/libc.git] / locale / FreeBSD / wcsrtombs.c
index 70e0f5f0ef387315c7f5a65affbff34a5fe03dd9..483b862b7184c0f2aef2739877b770b6c559dcdc 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2002 Tim J. Robbins.
+ * Copyright (c) 2002-2004 Tim J. Robbins.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/locale/wcsrtombs.c,v 1.2 2002/09/06 11:23:45 tjr Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/locale/wcsrtombs.c,v 1.6 2004/07/21 10:54:57 tjr Exp $");
+
+#include "xlocale_private.h"
 
-#include <errno.h>
 #include <limits.h>
 #include <stdlib.h>
 #include <string.h>
 #include <wchar.h>
+#include "mblocal.h"
 
 size_t
-wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len,
-    mbstate_t * __restrict ps __unused)
+wcsrtombs_l(char * __restrict dst, const wchar_t ** __restrict src, size_t len,
+    mbstate_t * __restrict ps, locale_t loc)
 {
-       char buf[MB_LEN_MAX];
-       const wchar_t *s;
-       size_t nbytes;
-       int nb;
-
-       s = *src;
-       nbytes = 0;
-
-       if (dst == NULL) {
-               for (;;) {
-                       if ((nb = (int)wcrtomb(buf, *s, NULL)) < 0)
-                               /* Invalid character - wcrtomb() sets errno. */
-                               return ((size_t)-1);
-                       else if (*s == L'\0')
-                               return (nbytes + nb - 1);
-                       s++;
-                       nbytes += nb;
-               }
-               /*NOTREACHED*/
-       }
+       NORMALIZE_LOCALE(loc);
+       if (ps == NULL)
+               ps = &loc->__mbs_wcsrtombs;
+       return (loc->__lc_ctype->__wcsnrtombs(dst, src, SIZE_T_MAX, len, ps, loc));
+}
 
-       while (len > 0) {
-               if (len > (size_t)MB_CUR_MAX) {
-                       /* Enough space to translate in-place. */
-                       if ((nb = (int)wcrtomb(dst, *s, NULL)) < 0) {
-                               *src = s;
-                               return ((size_t)-1);
-                       }
-               } else {
-                       /* May not be enough space; use temp. buffer. */
-                       if ((nb = (int)wcrtomb(buf, *s, NULL)) < 0) {
-                               *src = s;
-                               return ((size_t)-1);
-                       }
-                       if (nb > (int)len)
-                               /* MB sequence for character won't fit. */
-                               break;
-                       memcpy(dst, buf, nb);
-               }
-               if (*s == L'\0') {
-                       *src = NULL;
-                       return (nbytes + nb - 1);
-               }
-               s++;
-               dst += nb;
-               len -= nb;
-               nbytes += nb;
-       }
-       *src = s;
-       return (nbytes);
+size_t
+wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len,
+    mbstate_t * __restrict ps)
+{
+       return wcsrtombs_l(dst, src, len, ps, __current_locale());
 }