diff options
author | plundblad@chromium.org <plundblad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-07 10:58:43 +0000 |
---|---|---|
committer | plundblad@chromium.org <plundblad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-07 10:58:43 +0000 |
commit | a0765c2c4cbf30ccf0ed282369d2d104756d1956 (patch) | |
tree | db8905608b3960373c5211276e6c772a7b0df531 /third_party/liblouis | |
parent | cd863872b7508e0d1658ee60f7c82fa30e9df345 (diff) | |
download | chromium_src-a0765c2c4cbf30ccf0ed282369d2d104756d1956.zip chromium_src-a0765c2c4cbf30ccf0ed282369d2d104756d1956.tar.gz chromium_src-a0765c2c4cbf30ccf0ed282369d2d104756d1956.tar.bz2 |
Allow braille translation result to be larger than twice the size of the input.
The liblouis wrapper used to allocate an output buffer that was twice as big
as the number of input characters. There are situations where this is
not enough. The new approach is to retry with a larger buffer up to
a certain limit.
R=dtseng@chromium.org
BUG=none
Review URL: https://codereview.chromium.org/124403002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243251 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/liblouis')
-rw-r--r-- | third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc | 50 |
1 files changed, 36 insertions, 14 deletions
diff --git a/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc b/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc index 390e192..67c6341 100644 --- a/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc +++ b/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc @@ -121,12 +121,13 @@ bool LibLouisWrapper::Translate(const TranslationParams& params, // TODO(jbroman): log this return false; } + // To avoid unsigned/signed comparison warnings. + int inbufsize = inbuf.size(); - int inlen = inbuf.size(); - int outlen = inlen * 2; // TODO(jbroman): choose this size more accurately. - std::vector<widechar> outbuf(outlen); - std::vector<int> text_to_braille(inlen); - std::vector<int> braille_to_text(outlen); + std::vector<widechar> outbuf; + std::vector<int> text_to_braille(inbuf.size()); + std::vector<int> braille_to_text; + int outlen; // Compute the cursor position pointer to pass to liblouis. int out_cursor_position; @@ -139,15 +140,36 @@ bool LibLouisWrapper::Translate(const TranslationParams& params, out_cursor_position_ptr = &out_cursor_position; } - // Invoke liblouis. - int result = lou_translate(params.table_name.c_str(), - &inbuf[0], &inlen, &outbuf[0], &outlen, - NULL /* typeform */, NULL /* spacing */, - &text_to_braille[0], &braille_to_text[0], - out_cursor_position_ptr, dotsIO /* mode */); - if (result == 0) { - // TODO(jbroman): log this - return false; + // 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); + braille_to_text.resize(outalloc); + int result = lou_translate(params.table_name.c_str(), + &inbuf[0], &inlen, &outbuf[0], &outlen, + NULL /* typeform */, NULL /* spacing */, + &text_to_braille[0], &braille_to_text[0], + out_cursor_position_ptr, dotsIO /* mode */); + 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(); + braille_to_text.clear(); } // Massage the result. |