diff options
author | Paolo Carlini <pcarlini@suse.de> | 2003-11-19 11:38:40 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2003-11-19 11:38:40 +0000 |
commit | 1f33554abb31ee66b0b61be508d91d1cafdc4b0b (patch) | |
tree | 48b77e87f53dc351f35e235fae841c52872e9b68 | |
parent | edfe1ac771642d4061ee0767271f4a89861e7b92 (diff) | |
download | gcc-1f33554abb31ee66b0b61be508d91d1cafdc4b0b.zip gcc-1f33554abb31ee66b0b61be508d91d1cafdc4b0b.tar.gz gcc-1f33554abb31ee66b0b61be508d91d1cafdc4b0b.tar.bz2 |
codecvt_members.cc (do_out): If we can upper bound the total number of external chars to something smaller...
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
-rw-r--r-- | libstdc++-v3/ChangeLog | 9 | ||||
-rw-r--r-- | libstdc++-v3/config/locale/generic/codecvt_members.cc | 57 | ||||
-rw-r--r-- | libstdc++-v3/config/locale/gnu/codecvt_members.cc | 59 |
3 files changed, 86 insertions, 39 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index dfea3ea..330c0c4 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -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. diff --git a/libstdc++-v3/config/locale/generic/codecvt_members.cc b/libstdc++-v3/config/locale/generic/codecvt_members.cc index 183439d..8bdc227 100644 --- a/libstdc++-v3/config/locale/generic/codecvt_members.cc +++ b/libstdc++-v3/config/locale/generic/codecvt_members.cc @@ -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) diff --git a/libstdc++-v3/config/locale/gnu/codecvt_members.cc b/libstdc++-v3/config/locale/gnu/codecvt_members.cc index 7d80076..54930fc0c 100644 --- a/libstdc++-v3/config/locale/gnu/codecvt_members.cc +++ b/libstdc++-v3/config/locale/gnu/codecvt_members.cc @@ -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) |