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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
114 } | 114 } |
115 | 115 |
116 bool LibLouisWrapper::Translate(const TranslationParams& params, | 116 bool LibLouisWrapper::Translate(const TranslationParams& params, |
117 TranslationResult* out) { | 117 TranslationResult* out) { |
118 // Convert the character set of the input text. | 118 // Convert the character set of the input text. |
119 std::vector<widechar> inbuf; | 119 std::vector<widechar> inbuf; |
120 if (!DecodeUtf8(params.text, &inbuf)) { | 120 if (!DecodeUtf8(params.text, &inbuf)) { |
121 // TODO(jbroman): log this | 121 // TODO(jbroman): log this |
122 return false; | 122 return false; |
123 } | 123 } |
124 // To avoid unsigned/signed comparison warnings. | |
125 int inbufsize = inbuf.size(); | |
124 | 126 |
125 int inlen = inbuf.size(); | 127 std::vector<widechar> outbuf; |
126 int outlen = inlen * 2; // TODO(jbroman): choose this size more accurately. | 128 std::vector<int> text_to_braille(inbuf.size()); |
127 std::vector<widechar> outbuf(outlen); | 129 std::vector<int> braille_to_text; |
128 std::vector<int> text_to_braille(inlen); | 130 int outlen; |
David Tseng
2014/01/06 18:59:45
nit: outbufsize
| |
129 std::vector<int> braille_to_text(outlen); | |
130 | 131 |
131 // Compute the cursor position pointer to pass to liblouis. | 132 // Compute the cursor position pointer to pass to liblouis. |
132 int out_cursor_position; | 133 int out_cursor_position; |
133 int* out_cursor_position_ptr; | 134 int* out_cursor_position_ptr; |
134 if (params.cursor_position < 0) { | 135 if (params.cursor_position < 0) { |
135 out_cursor_position = -1; | 136 out_cursor_position = -1; |
136 out_cursor_position_ptr = NULL; | 137 out_cursor_position_ptr = NULL; |
137 } else { | 138 } else { |
138 out_cursor_position = params.cursor_position; | 139 out_cursor_position = params.cursor_position; |
139 out_cursor_position_ptr = &out_cursor_position; | 140 out_cursor_position_ptr = &out_cursor_position; |
140 } | 141 } |
141 | 142 |
142 // Invoke liblouis. | 143 // Invoke liblouis. Do this in a loop since we can't precalculate the |
143 int result = lou_translate(params.table_name.c_str(), | 144 // translated size. We add an extra slot in the output buffer so that |
144 &inbuf[0], &inlen, &outbuf[0], &outlen, | 145 // common cases like single digits or capital letters won't always trigger |
145 NULL /* typeform */, NULL /* spacing */, | 146 // retranslations (see the coments above the second exit condition inside |
David Tseng
2014/01/06 18:59:45
s/coments/comments
| |
146 &text_to_braille[0], &braille_to_text[0], | 147 // the loop). We also set an arbitrary upper bound for the allocation |
147 out_cursor_position_ptr, dotsIO /* mode */); | 148 // to make sure the loop exits without running out of memory. |
148 if (result == 0) { | 149 for (int outalloc = (inbufsize + 1) * 2, maxoutalloc = (inbufsize + 1) * 8; |
149 // TODO(jbroman): log this | 150 outalloc <= maxoutalloc; outalloc *= 2) { |
150 return false; | 151 int inlen = inbufsize; |
152 outlen = outalloc; | |
153 outbuf.resize(outalloc); | |
154 braille_to_text.resize(outalloc); | |
155 int result = lou_translate(params.table_name.c_str(), | |
156 &inbuf[0], &inlen, &outbuf[0], &outlen, | |
157 NULL /* typeform */, NULL /* spacing */, | |
158 &text_to_braille[0], &braille_to_text[0], | |
159 out_cursor_position_ptr, dotsIO /* mode */); | |
160 if (result == 0) { | |
161 // TODO(jbroman): log this | |
162 return false; | |
163 } | |
164 // If all of inbuf was not consumed, the output buffer must be too small | |
165 // and we have to retry with a larger buffer. | |
166 // In addition, if all of outbuf was exhausted, there's no way to know if | |
167 // more space was needed, so we'll have to retry the translation in that | |
168 // corner case as well. | |
169 if (inlen == inbufsize && outlen < outalloc) | |
170 break; | |
171 outbuf.clear(); | |
David Tseng
2014/01/06 18:59:45
Is it true that 8-dot tables are always 1-1 mappin
| |
172 braille_to_text.clear(); | |
151 } | 173 } |
152 | 174 |
153 // Massage the result. | 175 // Massage the result. |
154 std::vector<unsigned char> cells; | 176 std::vector<unsigned char> cells; |
155 cells.reserve(outlen); | 177 cells.reserve(outlen); |
156 for (int i = 0; i < outlen; i++) { | 178 for (int i = 0; i < outlen; i++) { |
157 cells.push_back(outbuf[i]); | 179 cells.push_back(outbuf[i]); |
158 } | 180 } |
159 braille_to_text.resize(outlen); | 181 braille_to_text.resize(outlen); |
160 | 182 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
195 // TODO(jbroman): log this | 217 // TODO(jbroman): log this |
196 return false; | 218 return false; |
197 } | 219 } |
198 | 220 |
199 // Return the back translation result. | 221 // Return the back translation result. |
200 out->swap(text); | 222 out->swap(text); |
201 return true; | 223 return true; |
202 } | 224 } |
203 | 225 |
204 } // namespace liblouis_nacl | 226 } // namespace liblouis_nacl |
OLD | NEW |