summaryrefslogtreecommitdiffstats
path: root/third_party
diff options
context:
space:
mode:
authorplundblad@chromium.org <plundblad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-28 02:20:57 +0000
committerplundblad@chromium.org <plundblad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-28 02:20:57 +0000
commit593a7c08527f209bfa0649634ae7873ca84ef7bc (patch)
tree8d8257aefcf4c4266ef4cb7e7ded3f100d3e19a7 /third_party
parentb051cdb6465736e7233cd22b807e255554378206 (diff)
downloadchromium_src-593a7c08527f209bfa0649634ae7873ca84ef7bc.zip
chromium_src-593a7c08527f209bfa0649634ae7873ca84ef7bc.tar.gz
chromium_src-593a7c08527f209bfa0649634ae7873ca84ef7bc.tar.bz2
Fix braille backtranslation size limit.
Sometimes, a contracted string results in more than twice the size of the input being the result of back translation. This is especially true for small strings (e.g. a single letter k translating to knowledgable). This CL uses a similar approach as https://codereview.chromium.org/124403002 expanding the allocated buffer, working around liblouis api quirks. BUG=310285 R=dtseng@chromium.org Review URL: https://codereview.chromium.org/183653002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@254023 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
-rw-r--r--third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc40
1 files changed, 31 insertions, 9 deletions
diff --git a/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc b/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc
index 67c6341..2fff14e 100644
--- a/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc
+++ b/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc
@@ -197,17 +197,39 @@ bool LibLouisWrapper::BackTranslate(const std::string& table_name,
// Set the high-order bit to prevent liblouis from dropping empty cells.
inbuf.push_back(*it | 0x8000);
}
- int inlen = inbuf.size();
- int outlen = inlen * 2; // TODO(jbroman): choose this size more accurately.
- std::vector<widechar> outbuf(outlen);
+ // To avoid unsigned/signed comparison warnings.
+ int inbufsize = inbuf.size();
+ std::vector<widechar> outbuf;
+ int outlen;
+
+ // Invoke liblouis. Do this in a loop since we can't precalculate the
+ // translated size. We add an extra slot in the output buffer so that
+ // common cases like single digits or capital letters won't always trigger
+ // retranslations (see the comments above the second exit condition inside
+ // the loop). We also set an arbitrary upper bound for the allocation
+ // to make sure the loop exits without running out of memory.
+ for (int outalloc = (inbufsize + 1) * 2, maxoutalloc = (inbufsize + 1) * 8;
+ outalloc <= maxoutalloc; outalloc *= 2) {
+ int inlen = inbufsize;
+ outlen = outalloc;
+ outbuf.resize(outalloc);
- // Invoke liblouis.
- int result = lou_backTranslateString(table_name.c_str(),
- &inbuf[0], &inlen, &outbuf[0], &outlen,
+ int result = lou_backTranslateString(
+ table_name.c_str(), &inbuf[0], &inlen, &outbuf[0], &outlen,
NULL /* typeform */, NULL /* spacing */, dotsIO /* mode */);
- if (result == 0) {
- // TODO(njbroman): log this
- return false;
+ if (result == 0) {
+ // TODO(jbroman): log this
+ return false;
+ }
+
+ // If all of inbuf was not consumed, the output buffer must be too small
+ // and we have to retry with a larger buffer.
+ // In addition, if all of outbuf was exhausted, there's no way to know if
+ // more space was needed, so we'll have to retry the translation in that
+ // corner case as well.
+ if (inlen == inbufsize && outlen < outalloc)
+ break;
+ outbuf.clear();
}
// Massage the result.