diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2014-02-03 18:06:46 -0800 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-02-14 00:34:25 +0100 |
commit | 3c15118fa38aaec13125ff82f9cfeabfdd57fd21 (patch) | |
tree | 6308526095b08d1f7108c4b8eeb47064ea25dc85 /src/corelib/tools/qlocale.cpp | |
parent | ed7458a8a66416c106ad33871a288091058d01ea (diff) |
QLocalePrivate: merge removeGroupSeparators into numberToCLocale
This version will parse the string only once and will not do any
memmove. This is more efficient.
Change-Id: I59026ad0fa61cc3f16146bdcd622fc54cbd8a321
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/corelib/tools/qlocale.cpp')
-rw-r--r-- | src/corelib/tools/qlocale.cpp | 59 |
1 files changed, 52 insertions, 7 deletions
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index ace22272ec..f3c492574e 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -3111,6 +3111,11 @@ bool QLocaleData::numberToCLocale(const QChar *str, int len, break; } + int group_cnt = 0; // counts number of group chars + int decpt_idx = -1; + int last_separator_idx = -1; + int start_of_digits_idx = -1; + while (idx < l) { const QChar in = uc[idx]; @@ -3128,20 +3133,60 @@ bool QLocaleData::numberToCLocale(const QChar *str, int len, else break; } + if (group_sep_mode == ParseGroupSeparators) { + if (start_of_digits_idx == -1 && out >= '0' && out <= '9') { + start_of_digits_idx = idx; + } else if (out == ',') { + // Don't allow group chars after the decimal point + if (decpt_idx != -1) + return false; + + // check distance from the last separator or from the beginning of the digits + // ### FIXME: Some locales allow other groupings! See https://en.wikipedia.org/wiki/Thousands_separator + if (last_separator_idx != -1 && idx - last_separator_idx != 4) + return false; + if (last_separator_idx == -1 && (start_of_digits_idx == -1 || idx - start_of_digits_idx > 3)) + return false; + + last_separator_idx = idx; + ++group_cnt; + + // don't add the group separator + ++idx; + continue; + } else if (out == '.' || out == 'e' || out == 'E') { + // Fail if more than one decimal point + if (out == '.' && decpt_idx != -1) + return false; + if (decpt_idx == -1) + decpt_idx = idx; + + // check distance from the last separator + // ### FIXME: Some locales allow other groupings! See https://en.wikipedia.org/wiki/Thousands_separator + if (last_separator_idx != -1 && idx - last_separator_idx != 4) + return false; + + // stop processing separators + last_separator_idx = -1; + } + } result->append(out); ++idx; } - result->append('\0'); - - // Check separators - if (group_sep_mode == ParseGroupSeparators - && !removeGroupSeparators(result)) - return false; - + if (group_sep_mode == ParseGroupSeparators) { + // group separator post-processing + // did we end in a separator? + if (last_separator_idx + 1 == idx) + return false; + // were there enough digits since the last separator? + if (last_separator_idx != -1 && idx - last_separator_idx != 4) + return false; + } + result->append('\0'); return idx == l; } |