diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2012-08-17 09:23:34 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2012-08-17 09:23:34 +0000 |
commit | 74d1d0ee8047aafe4f24ef19f009145bc64ea1c5 (patch) | |
tree | 1f2379e37ea2da8cc5b32506a5316b8402f238c2 /winsup/cygwin | |
parent | 46f5dd59581f3405e56a48f351ed97a0af0f70ef (diff) | |
download | newlib-74d1d0ee8047aafe4f24ef19f009145bc64ea1c5.zip newlib-74d1d0ee8047aafe4f24ef19f009145bc64ea1c5.tar.gz newlib-74d1d0ee8047aafe4f24ef19f009145bc64ea1c5.tar.bz2 |
* fhandler_clipboard.cc (fhandler_dev_clipboard::read): Use
read-ahead buffer for reading Windows clipboard if caller's
buffer is too small for complete characters.
* include/limits.h: Remove outdated TODO comment.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r-- | winsup/cygwin/ChangeLog | 7 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_clipboard.cc | 52 | ||||
-rw-r--r-- | winsup/cygwin/include/limits.h | 3 |
3 files changed, 55 insertions, 7 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a732d73..497a343 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,10 @@ +2012-08-17 Thomas Wolff <towo@towo.net> + + * fhandler_clipboard.cc (fhandler_dev_clipboard::read): Use + read-ahead buffer for reading Windows clipboard if caller's + buffer is too small for complete characters. + * include/limits.h: Remove outdated TODO comment. + 2012-08-16 Christopher Faylor <me.cygwin2012@cgf.cx> * cygtls.cc (_cygtls::operator HANDLE): Reverse '?' test stupidity. diff --git a/winsup/cygwin/fhandler_clipboard.cc b/winsup/cygwin/fhandler_clipboard.cc index 86f126c..ad80295 100644 --- a/winsup/cygwin/fhandler_clipboard.cc +++ b/winsup/cygwin/fhandler_clipboard.cc @@ -222,6 +222,7 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len) UINT formatlist[2]; int format; LPVOID cb_data; + int rach; if (!OpenClipboard (NULL)) { @@ -243,12 +244,24 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len) cygcb_t *clipbuf = (cygcb_t *) cb_data; if (pos < clipbuf->len) - { + { ret = ((len > (clipbuf->len - pos)) ? (clipbuf->len - pos) : len); memcpy (ptr, clipbuf->data + pos , ret); pos += ret; } } + else if ((rach = get_readahead ()) >= 0) + { + /* Deliver from read-ahead buffer. */ + char * out_ptr = (char *) ptr; + * out_ptr++ = rach; + ret = 1; + while (ret < len && (rach = get_readahead ()) >= 0) + { + * out_ptr++ = rach; + ret++; + } + } else { wchar_t *buf = (wchar_t *) cb_data; @@ -256,25 +269,54 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len) size_t glen = GlobalSize (hglb) / sizeof (WCHAR) - 1; if (pos < glen) { + /* If caller's buffer is too small to hold at least one + max-size character, redirect algorithm to local + read-ahead buffer, finally fill class read-ahead buffer + with result and feed caller from there. */ + char *conv_ptr = (char *) ptr; + size_t conv_len = len; +#define cprabuf_len MB_LEN_MAX /* max MB_CUR_MAX of all encodings */ + char cprabuf [cprabuf_len]; + if (len < cprabuf_len) + { + conv_ptr = cprabuf; + conv_len = cprabuf_len; + } + /* Comparing apples and oranges here, but the below loop could become extremly slow otherwise. We rather return a few bytes less than possible instead of being even more slow than usual... */ - if (glen > pos + len) - glen = pos + len; + if (glen > pos + conv_len) + glen = pos + conv_len; /* This loop is necessary because the number of bytes returned by sys_wcstombs does not indicate the number of wide chars used for it, so we could potentially drop wide chars. */ while ((ret = sys_wcstombs (NULL, 0, buf + pos, glen - pos)) != (size_t) -1 - && ret > len) + && (ret > conv_len + /* Skip separated high surrogate: */ + || ((buf [pos + glen - 1] & 0xFC00) == 0xD800 && glen - pos > 1))) --glen; if (ret == (size_t) -1) ret = 0; else { - ret = sys_wcstombs ((char *) ptr, (size_t) -1, + ret = sys_wcstombs ((char *) conv_ptr, (size_t) -1, buf + pos, glen - pos); pos = glen; + /* If using read-ahead buffer, copy to class read-ahead buffer + and deliver first byte. */ + if (conv_ptr == cprabuf) + { + puts_readahead (cprabuf, ret); + char *out_ptr = (char *) ptr; + ret = 0; + while (ret < len && (rach = get_readahead ()) >= 0) + { + * out_ptr++ = rach; + ret++; + } + } } } } diff --git a/winsup/cygwin/include/limits.h b/winsup/cygwin/include/limits.h index 61d6ae5..58368ed 100644 --- a/winsup/cygwin/include/limits.h +++ b/winsup/cygwin/include/limits.h @@ -36,8 +36,7 @@ details. */ /* Maximum length of a multibyte character. */ #ifndef MB_LEN_MAX -/* TODO: This is newlib's max value. We should probably rather define our - own _mbtowc_r and _wctomb_r functions which are only codepage dependent. */ +/* Use value from newlib. */ #define MB_LEN_MAX 8 #endif |