OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/strings/utf_offset_string_conversions.h" | 5 #include "base/strings/utf_offset_string_conversions.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <memory> | 10 #include <memory> |
11 | 11 |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/strings/string_piece.h" | 13 #include "base/strings/string_piece.h" |
14 #include "base/strings/utf_string_conversion_utils.h" | 14 #include "base/strings/utf_string_conversion_utils.h" |
15 | 15 |
16 namespace base { | 16 namespace base { |
17 | 17 |
| 18 namespace { |
| 19 |
| 20 // Limiting function callable by std::for_each which will replace any value |
| 21 // which is greater than |limit| with npos. |
| 22 struct LimitOffset { |
| 23 explicit LimitOffset(size_t limit) : limit_(limit) {} |
| 24 |
| 25 void operator()(size_t& offset) { |
| 26 if (offset > limit_) |
| 27 offset = string16::npos; |
| 28 } |
| 29 |
| 30 size_t limit_; |
| 31 }; |
| 32 |
| 33 } // namespace |
| 34 |
18 OffsetAdjuster::Adjustment::Adjustment(size_t original_offset, | 35 OffsetAdjuster::Adjustment::Adjustment(size_t original_offset, |
19 size_t original_length, | 36 size_t original_length, |
20 size_t output_length) | 37 size_t output_length) |
21 : original_offset(original_offset), | 38 : original_offset(original_offset), |
22 original_length(original_length), | 39 original_length(original_length), |
23 output_length(output_length) { | 40 output_length(output_length) { |
24 } | 41 } |
25 | 42 |
26 // static | 43 // static |
27 void OffsetAdjuster::AdjustOffsets( | 44 void OffsetAdjuster::AdjustOffsets(const Adjustments& adjustments, |
28 const Adjustments& adjustments, | 45 std::vector<size_t>* offsets_for_adjustment, |
29 std::vector<size_t>* offsets_for_adjustment) { | 46 size_t limit) { |
30 if (!offsets_for_adjustment || adjustments.empty()) | 47 DCHECK(offsets_for_adjustment); |
31 return; | |
32 for (std::vector<size_t>::iterator i(offsets_for_adjustment->begin()); | 48 for (std::vector<size_t>::iterator i(offsets_for_adjustment->begin()); |
33 i != offsets_for_adjustment->end(); ++i) | 49 i != offsets_for_adjustment->end(); ++i) |
34 AdjustOffset(adjustments, &(*i)); | 50 AdjustOffset(adjustments, &(*i), limit); |
35 } | 51 } |
36 | 52 |
37 // static | 53 // static |
38 void OffsetAdjuster::AdjustOffset(const Adjustments& adjustments, | 54 void OffsetAdjuster::AdjustOffset(const Adjustments& adjustments, |
39 size_t* offset) { | 55 size_t* offset, |
| 56 size_t limit) { |
| 57 DCHECK(offset); |
40 if (*offset == string16::npos) | 58 if (*offset == string16::npos) |
41 return; | 59 return; |
42 int adjustment = 0; | 60 int adjustment = 0; |
43 for (Adjustments::const_iterator i = adjustments.begin(); | 61 for (Adjustments::const_iterator i = adjustments.begin(); |
44 i != adjustments.end(); ++i) { | 62 i != adjustments.end(); ++i) { |
45 if (*offset <= i->original_offset) | 63 if (*offset <= i->original_offset) |
46 break; | 64 break; |
47 if (*offset < (i->original_offset + i->original_length)) { | 65 if (*offset < (i->original_offset + i->original_length)) { |
48 *offset = string16::npos; | 66 *offset = string16::npos; |
49 return; | 67 return; |
50 } | 68 } |
51 adjustment += static_cast<int>(i->original_length - i->output_length); | 69 adjustment += static_cast<int>(i->original_length - i->output_length); |
52 } | 70 } |
53 *offset -= adjustment; | 71 *offset -= adjustment; |
| 72 |
| 73 if (*offset > limit) |
| 74 *offset = string16::npos; |
54 } | 75 } |
55 | 76 |
56 // static | 77 // static |
57 void OffsetAdjuster::UnadjustOffsets( | 78 void OffsetAdjuster::UnadjustOffsets( |
58 const Adjustments& adjustments, | 79 const Adjustments& adjustments, |
59 std::vector<size_t>* offsets_for_unadjustment) { | 80 std::vector<size_t>* offsets_for_unadjustment) { |
60 if (!offsets_for_unadjustment || adjustments.empty()) | 81 if (!offsets_for_unadjustment || adjustments.empty()) |
61 return; | 82 return; |
62 for (std::vector<size_t>::iterator i(offsets_for_unadjustment->begin()); | 83 for (std::vector<size_t>::iterator i(offsets_for_unadjustment->begin()); |
63 i != offsets_for_unadjustment->end(); ++i) | 84 i != offsets_for_unadjustment->end(); ++i) |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 const base::StringPiece& utf8, | 250 const base::StringPiece& utf8, |
230 base::OffsetAdjuster::Adjustments* adjustments) { | 251 base::OffsetAdjuster::Adjustments* adjustments) { |
231 string16 result; | 252 string16 result; |
232 UTF8ToUTF16WithAdjustments(utf8.data(), utf8.length(), &result, adjustments); | 253 UTF8ToUTF16WithAdjustments(utf8.data(), utf8.length(), &result, adjustments); |
233 return result; | 254 return result; |
234 } | 255 } |
235 | 256 |
236 string16 UTF8ToUTF16AndAdjustOffsets( | 257 string16 UTF8ToUTF16AndAdjustOffsets( |
237 const base::StringPiece& utf8, | 258 const base::StringPiece& utf8, |
238 std::vector<size_t>* offsets_for_adjustment) { | 259 std::vector<size_t>* offsets_for_adjustment) { |
239 std::for_each(offsets_for_adjustment->begin(), | 260 std::for_each(offsets_for_adjustment->begin(), offsets_for_adjustment->end(), |
240 offsets_for_adjustment->end(), | 261 LimitOffset(utf8.length())); |
241 LimitOffset<base::StringPiece>(utf8.length())); | |
242 OffsetAdjuster::Adjustments adjustments; | 262 OffsetAdjuster::Adjustments adjustments; |
243 string16 result = UTF8ToUTF16WithAdjustments(utf8, &adjustments); | 263 string16 result = UTF8ToUTF16WithAdjustments(utf8, &adjustments); |
244 OffsetAdjuster::AdjustOffsets(adjustments, offsets_for_adjustment); | 264 OffsetAdjuster::AdjustOffsets(adjustments, offsets_for_adjustment); |
245 return result; | 265 return result; |
246 } | 266 } |
247 | 267 |
248 std::string UTF16ToUTF8AndAdjustOffsets( | 268 std::string UTF16ToUTF8AndAdjustOffsets( |
249 const base::StringPiece16& utf16, | 269 const base::StringPiece16& utf16, |
250 std::vector<size_t>* offsets_for_adjustment) { | 270 std::vector<size_t>* offsets_for_adjustment) { |
251 std::for_each(offsets_for_adjustment->begin(), | 271 std::for_each(offsets_for_adjustment->begin(), offsets_for_adjustment->end(), |
252 offsets_for_adjustment->end(), | 272 LimitOffset(utf16.length())); |
253 LimitOffset<base::StringPiece16>(utf16.length())); | |
254 std::string result; | 273 std::string result; |
255 PrepareForUTF8Output(utf16.data(), utf16.length(), &result); | 274 PrepareForUTF8Output(utf16.data(), utf16.length(), &result); |
256 OffsetAdjuster::Adjustments adjustments; | 275 OffsetAdjuster::Adjustments adjustments; |
257 ConvertUnicode(utf16.data(), utf16.length(), &result, &adjustments); | 276 ConvertUnicode(utf16.data(), utf16.length(), &result, &adjustments); |
258 OffsetAdjuster::AdjustOffsets(adjustments, offsets_for_adjustment); | 277 OffsetAdjuster::AdjustOffsets(adjustments, offsets_for_adjustment); |
259 return result; | 278 return result; |
260 } | 279 } |
261 | 280 |
262 } // namespace base | 281 } // namespace base |
OLD | NEW |