summaryrefslogtreecommitdiffstats
path: root/third_party/liblouis
diff options
context:
space:
mode:
authorplundblad@chromium.org <plundblad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-07 10:58:43 +0000
committerplundblad@chromium.org <plundblad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-07 10:58:43 +0000
commita0765c2c4cbf30ccf0ed282369d2d104756d1956 (patch)
treedb8905608b3960373c5211276e6c772a7b0df531 /third_party/liblouis
parentcd863872b7508e0d1658ee60f7c82fa30e9df345 (diff)
downloadchromium_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.cc50
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.