| 150 | } |
| 151 | |
| 152 | void NormalizeDigits(std::string & utf8) |
| 153 | { |
| 154 | size_t const n = utf8.size(); |
| 155 | size_t const m = n >= 2 ? n - 2 : 0; |
| 156 | |
| 157 | size_t i = 0; |
| 158 | while (i < n && utf8[i] != '\xEF') |
| 159 | ++i; |
| 160 | size_t j = i; |
| 161 | |
| 162 | // Following invariant holds before/between/after loop iterations below: |
| 163 | // * utf8[0, i) represents a checked part of the input string. |
| 164 | // * utf8[0, j) represents a normalized version of the utf8[0, i). |
| 165 | while (i < m) |
| 166 | { |
| 167 | if (utf8[i] == '\xEF' && utf8[i + 1] == '\xBC') |
| 168 | { |
| 169 | auto const n = utf8[i + 2]; |
| 170 | if (n >= '\x90' && n <= '\x99') |
| 171 | { |
| 172 | utf8[j++] = n - 0x90 + '0'; |
| 173 | i += 3; |
| 174 | } |
| 175 | else |
| 176 | { |
| 177 | utf8[j++] = utf8[i++]; |
| 178 | utf8[j++] = utf8[i++]; |
| 179 | } |
| 180 | } |
| 181 | else |
| 182 | { |
| 183 | utf8[j++] = utf8[i++]; |
| 184 | } |
| 185 | } |
| 186 | while (i < n) |
| 187 | utf8[j++] = utf8[i++]; |
| 188 | utf8.resize(j); |
| 189 | } |
| 190 | |
| 191 | void NormalizeDigits(UniString & us) |
| 192 | { |