]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
codecvt_members.cc (do_out): If we can upper bound the total number of external chars...
authorPaolo Carlini <pcarlini@suse.de>
Wed, 19 Nov 2003 11:38:40 +0000 (11:38 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Wed, 19 Nov 2003 11:38:40 +0000 (11:38 +0000)
2003-11-19  Paolo Carlini  <pcarlini@suse.de>

* config/locale/gnu/codecvt_members.cc (do_out): If
we can upper bound the total number of external chars
to something smaller than __to_end - __to, avoid the
temporary buffer, the memcopy and simplify the loop.
* config/locale/generic/codecvt_members.cc (do_out):
Likewise.

From-SVN: r73733

libstdc++-v3/ChangeLog
libstdc++-v3/config/locale/generic/codecvt_members.cc
libstdc++-v3/config/locale/gnu/codecvt_members.cc

index dfea3ea9ec9b47a12eae025b0479fec5559ceab7..330c0c49341afe88d71681d85177c439d2f92814 100644 (file)
@@ -1,3 +1,12 @@
+2003-11-19  Paolo Carlini  <pcarlini@suse.de>
+
+       * config/locale/gnu/codecvt_members.cc (do_out): If
+       we can upper bound the total number of external chars
+       to something smaller than __to_end - __to, avoid the
+       temporary buffer, the memcopy and simplify the loop.
+       * config/locale/generic/codecvt_members.cc (do_out):
+       Likewise.
+
 2003-11-19  Andreas Tobler  <a.tobler@schweiz.ch>
 
        * testsuite/lib/libstdc++.exp: Add DYLD_LIBRARY_PATH for darwin.
index 183439de4f32dd013c2473a5c9b69f4ac615f1e2..8bdc22779ad7785ec25364fd5f0a63b23349a8c0 100644 (file)
@@ -49,32 +49,51 @@ namespace std
     result __ret = ok;
     // The conversion must be done using a temporary destination buffer
     // since it is not possible to pass the size of the buffer to wcrtomb
-    extern_type __buf[MB_LEN_MAX];
-    // A temporary state must be used since the result of the last
-    // conversion may be thrown away.
     state_type __tmp_state(__state);
-    
+
     // The conversion must be done by calling wcrtomb in a loop rather
     // than using wcsrtombs because wcsrtombs assumes that the input is
     // zero-terminated.
-    while (__from < __from_end && __to < __to_end)
+
+    // Either we can upper bound the total number of external characters to
+    // something smaller than __to_end - __to or the conversion must be done
+    // using a temporary destination buffer since it is not possible to
+    // pass the size of the buffer to wcrtomb
+    if (MB_CUR_MAX * (__from_end - __from) - (__to_end - __to) <= 0)
+      while (__from < __from_end)
+       {
+         const size_t __conv = wcrtomb(__to, *__from, &__tmp_state);
+         if (__conv == static_cast<size_t>(-1))
+           {
+             __ret = error;
+             break;
+           }
+         __state = __tmp_state;
+         __to += __conv;
+         __from++;
+       }
+    else
       {
-       size_t __conv = wcrtomb(__buf, *__from, &__tmp_state);
-       if (__conv == static_cast<size_t>(-1))
-         {
-           __ret = error;
-           break;
-         }
-       else if (__conv > static_cast<size_t>(__to_end - __to))
+       extern_type __buf[MB_LEN_MAX];
+       while (__from < __from_end && __to < __to_end)
          {
-           __ret = partial;
-           break;
+           const size_t __conv = wcrtomb(__buf, *__from, &__tmp_state);
+           if (__conv == static_cast<size_t>(-1))
+             {
+               __ret = error;
+               break;
+             }
+           else if (__conv > static_cast<size_t>(__to_end - __to))
+             {
+               __ret = partial;
+               break;
+             }
+           
+           memcpy(__to, __buf, __conv);
+           __state = __tmp_state;
+           __to += __conv;
+           __from++;
          }
-
-       memcpy(__to, __buf, __conv);
-       __state = __tmp_state;
-       __to += __conv;
-       __from++;
       }
 
     if (__ret == ok && __from < __from_end)
index 7d800765359d9020e87171d5eeee511aea447a42..54930fc0c4a14e0753d940bb71b88ca28dce5af0 100644 (file)
@@ -48,13 +48,10 @@ namespace std
         extern_type*& __to_next) const
   {
     result __ret = ok;
-    // The conversion must be done using a temporary destination buffer
-    // since it is not possible to pass the size of the buffer to wcrtomb
-    extern_type __buf[MB_LEN_MAX];
     // A temporary state must be used since the result of the last
     // conversion may be thrown away.
-    state_type __tmp_state(__state);
-    
+    state_type __tmp_state(__state);   
+
 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
     __c_locale __old = __uselocale(_M_c_locale_codecvt);
 #endif
@@ -62,24 +59,46 @@ namespace std
     // The conversion must be done by calling wcrtomb in a loop rather
     // than using wcsrtombs because wcsrtombs assumes that the input is
     // zero-terminated.
-    while (__from < __from_end && __to < __to_end)
+
+    // Either we can upper bound the total number of external characters to
+    // something smaller than __to_end - __to or the conversion must be done
+    // using a temporary destination buffer since it is not possible to
+    // pass the size of the buffer to wcrtomb
+    if (MB_CUR_MAX * (__from_end - __from) - (__to_end - __to) <= 0)
+      while (__from < __from_end)
+       {
+         const size_t __conv = wcrtomb(__to, *__from, &__tmp_state);
+         if (__conv == static_cast<size_t>(-1))
+           {
+             __ret = error;
+             break;
+           }
+         __state = __tmp_state;
+         __to += __conv;
+         __from++;
+       }
+    else
       {
-       size_t __conv = wcrtomb(__buf, *__from, &__tmp_state);
-       if (__conv == static_cast<size_t>(-1))
+       extern_type __buf[MB_LEN_MAX];
+       while (__from < __from_end && __to < __to_end)
          {
-           __ret = error;
-           break;
+           const size_t __conv = wcrtomb(__buf, *__from, &__tmp_state);
+           if (__conv == static_cast<size_t>(-1))
+             {
+               __ret = error;
+               break;
+             }
+           else if (__conv > static_cast<size_t>(__to_end - __to))
+             {
+               __ret = partial;
+               break;
+             }
+           
+           memcpy(__to, __buf, __conv);
+           __state = __tmp_state;
+           __to += __conv;
+           __from++;
          }
-       else if (__conv > static_cast<size_t>(__to_end - __to))
-         {
-           __ret = partial;
-           break;
-         }
-
-       memcpy(__to, __buf, __conv);
-       __state = __tmp_state;
-       __to += __conv;
-       __from++;
       }
 
 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)