Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 Google Inc. | 1 // Copyright 2013 Google Inc. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not | 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| 4 // use this file except in compliance with the License. You may obtain a copy of | 4 // use this file except in compliance with the License. You may obtain a copy of |
| 5 // the License at | 5 // the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 | 190 |
| 191 bool LibLouisWrapper::BackTranslate(const std::string& table_name, | 191 bool LibLouisWrapper::BackTranslate(const std::string& table_name, |
| 192 const std::vector<unsigned char>& cells, std::string* out) { | 192 const std::vector<unsigned char>& cells, std::string* out) { |
| 193 std::vector<widechar> inbuf; | 193 std::vector<widechar> inbuf; |
| 194 inbuf.reserve(cells.size()); | 194 inbuf.reserve(cells.size()); |
| 195 for (std::vector<unsigned char>::const_iterator it = cells.begin(); | 195 for (std::vector<unsigned char>::const_iterator it = cells.begin(); |
| 196 it != cells.end(); ++it) { | 196 it != cells.end(); ++it) { |
| 197 // Set the high-order bit to prevent liblouis from dropping empty cells. | 197 // Set the high-order bit to prevent liblouis from dropping empty cells. |
| 198 inbuf.push_back(*it | 0x8000); | 198 inbuf.push_back(*it | 0x8000); |
| 199 } | 199 } |
| 200 int inlen = inbuf.size(); | 200 // To avoid unsigned/signed comparison warnings. |
| 201 int outlen = inlen * 2; // TODO(jbroman): choose this size more accurately. | 201 int inbufsize = inbuf.size(); |
| 202 std::vector<widechar> outbuf(outlen); | 202 std::vector<widechar> outbuf; |
| 203 int outlen; | |
| 203 | 204 |
| 204 // Invoke liblouis. | 205 // Invoke liblouis. Do this in a loop since we can't precalculate the |
| 205 int result = lou_backTranslateString(table_name.c_str(), | 206 // translated size. We add an extra slot in the output buffer so that |
| 206 &inbuf[0], &inlen, &outbuf[0], &outlen, | 207 // common cases like single digits or capital letters won't always trigger |
| 208 // retranslations (see the comments above the second exit condition inside | |
| 209 // the loop). We also set an arbitrary upper bound for the allocation | |
| 210 // to make sure the loop exits without running out of memory. | |
| 211 for (int outalloc = (inbufsize + 1) * 2, maxoutalloc = (inbufsize + 1) * 8; | |
| 212 outalloc <= maxoutalloc; outalloc *= 2) { | |
| 213 int inlen = inbufsize; | |
| 214 outlen = outalloc; | |
| 215 outbuf.resize(outalloc); | |
| 216 | |
| 217 int result = lou_backTranslateString( | |
| 218 table_name.c_str(), &inbuf[0], &inlen, &outbuf[0], &outlen, | |
| 207 NULL /* typeform */, NULL /* spacing */, dotsIO /* mode */); | 219 NULL /* typeform */, NULL /* spacing */, dotsIO /* mode */); |
| 208 if (result == 0) { | 220 if (result == 0) { |
| 209 // TODO(njbroman): log this | 221 // TODO(jbroman): log this |
| 210 return false; | 222 return false; |
| 223 } | |
| 224 | |
| 225 // If all of inbuf was not consumed, the output buffer must be too small | |
| 226 // and we have to retry with a larger buffer. | |
|
David Tseng
2014/02/27 22:05:07
nit: |inbuf| and smiliarly below.
| |
| 227 // In addition, if all of outbuf was exhausted, there's no way to know if | |
| 228 // more space was needed, so we'll have to retry the translation in that | |
| 229 // corner case as well. | |
| 230 if (inlen == inbufsize && outlen < outalloc) | |
| 231 break; | |
| 232 outbuf.clear(); | |
| 211 } | 233 } |
| 212 | 234 |
| 213 // Massage the result. | 235 // Massage the result. |
| 214 outbuf.resize(outlen); | 236 outbuf.resize(outlen); |
| 215 std::string text; | 237 std::string text; |
| 216 if (!EncodeUtf8(outbuf, &text)) { | 238 if (!EncodeUtf8(outbuf, &text)) { |
| 217 // TODO(jbroman): log this | 239 // TODO(jbroman): log this |
| 218 return false; | 240 return false; |
| 219 } | 241 } |
| 220 | 242 |
| 221 // Return the back translation result. | 243 // Return the back translation result. |
| 222 out->swap(text); | 244 out->swap(text); |
| 223 return true; | 245 return true; |
| 224 } | 246 } |
| 225 | 247 |
| 226 } // namespace liblouis_nacl | 248 } // namespace liblouis_nacl |
| OLD | NEW |