1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/i18n/case_conversion.h"
7 #include "base/numerics/safe_conversions.h"
8 #include "base/strings/string16.h"
9 #include "base/strings/string_util.h"
10 #include "third_party/icu/source/common/unicode/uchar.h"
11 #include "third_party/icu/source/common/unicode/unistr.h"
12 #include "third_party/icu/source/common/unicode/ustring.h"
19 // Provides a uniform interface for upper/lower/folding which take take
20 // slightly varying parameters.
21 typedef int32_t (*CaseMapperFunction
)(UChar
* dest
, int32_t dest_capacity
,
22 const UChar
* src
, int32_t src_length
,
25 int32_t ToUpperMapper(UChar
* dest
, int32_t dest_capacity
,
26 const UChar
* src
, int32_t src_length
,
28 // Use default locale.
29 return u_strToUpper(dest
, dest_capacity
, src
, src_length
, NULL
, error
);
32 int32_t ToLowerMapper(UChar
* dest
, int32_t dest_capacity
,
33 const UChar
* src
, int32_t src_length
,
35 // Use default locale.
36 return u_strToLower(dest
, dest_capacity
, src
, src_length
, NULL
, error
);
39 int32_t FoldCaseMapper(UChar
* dest
, int32_t dest_capacity
,
40 const UChar
* src
, int32_t src_length
,
42 return u_strFoldCase(dest
, dest_capacity
, src
, src_length
,
43 U_FOLD_CASE_DEFAULT
, error
);
46 // Provides similar functionality as UnicodeString::caseMap but on string16.
47 string16
CaseMap(StringPiece16 string
, CaseMapperFunction case_mapper
) {
52 // Provide an initial guess that the string length won't change. The typical
53 // strings we use will very rarely change length in this process, so don't
54 // optimize for that case.
55 dest
.resize(string
.size());
61 // ICU won't terminate the string if there's not enough room for the null
62 // terminator, but will otherwise. So we don't need to save room for that.
63 // Don't use WriteInto, which assumes null terminators.
64 int32_t new_length
= case_mapper(
65 &dest
[0], saturated_cast
<int32_t>(dest
.size()),
66 string
.data(), saturated_cast
<int32_t>(string
.size()),
68 dest
.resize(new_length
);
69 } while (error
== U_BUFFER_OVERFLOW_ERROR
);
75 string16
ToLower(StringPiece16 string
) {
76 return CaseMap(string
, &ToLowerMapper
);
79 string16
ToUpper(StringPiece16 string
) {
80 return CaseMap(string
, &ToUpperMapper
);
83 string16
FoldCase(StringPiece16 string
) {
84 return CaseMap(string
, &FoldCaseMapper
);