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 OffsetAdjuster::Adjustment::Adjustment(size_t original_offset, | 18 OffsetAdjuster::Adjustment::Adjustment(size_t original_offset, |
19 size_t original_length, | 19 size_t original_length, |
20 size_t output_length) | 20 size_t output_length) |
21 : original_offset(original_offset), | 21 : original_offset(original_offset), |
22 original_length(original_length), | 22 original_length(original_length), |
23 output_length(output_length) { | 23 output_length(output_length) { |
24 } | 24 } |
25 | 25 |
26 // static | 26 // static |
27 void OffsetAdjuster::AdjustOffsets( | 27 void OffsetAdjuster::AdjustOffsets(const Adjustments& adjustments, |
28 const Adjustments& adjustments, | 28 std::vector<size_t>* offsets_for_adjustment, |
29 std::vector<size_t>* offsets_for_adjustment) { | 29 size_t limit) { |
30 if (!offsets_for_adjustment || adjustments.empty()) | 30 DCHECK(offsets_for_adjustment); |
31 return; | |
32 for (std::vector<size_t>::iterator i(offsets_for_adjustment->begin()); | 31 for (std::vector<size_t>::iterator i(offsets_for_adjustment->begin()); |
33 i != offsets_for_adjustment->end(); ++i) | 32 i != offsets_for_adjustment->end(); ++i) |
34 AdjustOffset(adjustments, &(*i)); | 33 AdjustOffset(adjustments, &(*i), limit); |
35 } | 34 } |
36 | 35 |
37 // static | 36 // static |
38 void OffsetAdjuster::AdjustOffset(const Adjustments& adjustments, | 37 void OffsetAdjuster::AdjustOffset(const Adjustments& adjustments, |
39 size_t* offset) { | 38 size_t* offset, |
| 39 size_t limit) { |
| 40 DCHECK(offset); |
40 if (*offset == string16::npos) | 41 if (*offset == string16::npos) |
41 return; | 42 return; |
42 int adjustment = 0; | 43 int adjustment = 0; |
43 for (Adjustments::const_iterator i = adjustments.begin(); | 44 for (Adjustments::const_iterator i = adjustments.begin(); |
44 i != adjustments.end(); ++i) { | 45 i != adjustments.end(); ++i) { |
45 if (*offset <= i->original_offset) | 46 if (*offset <= i->original_offset) |
46 break; | 47 break; |
47 if (*offset < (i->original_offset + i->original_length)) { | 48 if (*offset < (i->original_offset + i->original_length)) { |
48 *offset = string16::npos; | 49 *offset = string16::npos; |
49 return; | 50 return; |
50 } | 51 } |
51 adjustment += static_cast<int>(i->original_length - i->output_length); | 52 adjustment += static_cast<int>(i->original_length - i->output_length); |
52 } | 53 } |
53 *offset -= adjustment; | 54 *offset -= adjustment; |
| 55 |
| 56 if (*offset > limit) |
| 57 *offset = string16::npos; |
54 } | 58 } |
55 | 59 |
56 // static | 60 // static |
57 void OffsetAdjuster::UnadjustOffsets( | 61 void OffsetAdjuster::UnadjustOffsets( |
58 const Adjustments& adjustments, | 62 const Adjustments& adjustments, |
59 std::vector<size_t>* offsets_for_unadjustment) { | 63 std::vector<size_t>* offsets_for_unadjustment) { |
60 if (!offsets_for_unadjustment || adjustments.empty()) | 64 if (!offsets_for_unadjustment || adjustments.empty()) |
61 return; | 65 return; |
62 for (std::vector<size_t>::iterator i(offsets_for_unadjustment->begin()); | 66 for (std::vector<size_t>::iterator i(offsets_for_unadjustment->begin()); |
63 i != offsets_for_unadjustment->end(); ++i) | 67 i != offsets_for_unadjustment->end(); ++i) |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 const base::StringPiece& utf8, | 233 const base::StringPiece& utf8, |
230 base::OffsetAdjuster::Adjustments* adjustments) { | 234 base::OffsetAdjuster::Adjustments* adjustments) { |
231 string16 result; | 235 string16 result; |
232 UTF8ToUTF16WithAdjustments(utf8.data(), utf8.length(), &result, adjustments); | 236 UTF8ToUTF16WithAdjustments(utf8.data(), utf8.length(), &result, adjustments); |
233 return result; | 237 return result; |
234 } | 238 } |
235 | 239 |
236 string16 UTF8ToUTF16AndAdjustOffsets( | 240 string16 UTF8ToUTF16AndAdjustOffsets( |
237 const base::StringPiece& utf8, | 241 const base::StringPiece& utf8, |
238 std::vector<size_t>* offsets_for_adjustment) { | 242 std::vector<size_t>* offsets_for_adjustment) { |
239 std::for_each(offsets_for_adjustment->begin(), | 243 for (size_t& offset : *offsets_for_adjustment) { |
240 offsets_for_adjustment->end(), | 244 if (offset > utf8.length()) |
241 LimitOffset<base::StringPiece>(utf8.length())); | 245 offset = string16::npos; |
| 246 } |
242 OffsetAdjuster::Adjustments adjustments; | 247 OffsetAdjuster::Adjustments adjustments; |
243 string16 result = UTF8ToUTF16WithAdjustments(utf8, &adjustments); | 248 string16 result = UTF8ToUTF16WithAdjustments(utf8, &adjustments); |
244 OffsetAdjuster::AdjustOffsets(adjustments, offsets_for_adjustment); | 249 OffsetAdjuster::AdjustOffsets(adjustments, offsets_for_adjustment); |
245 return result; | 250 return result; |
246 } | 251 } |
247 | 252 |
248 std::string UTF16ToUTF8AndAdjustOffsets( | 253 std::string UTF16ToUTF8AndAdjustOffsets( |
249 const base::StringPiece16& utf16, | 254 const base::StringPiece16& utf16, |
250 std::vector<size_t>* offsets_for_adjustment) { | 255 std::vector<size_t>* offsets_for_adjustment) { |
251 std::for_each(offsets_for_adjustment->begin(), | 256 for (size_t& offset : *offsets_for_adjustment) { |
252 offsets_for_adjustment->end(), | 257 if (offset > utf16.length()) |
253 LimitOffset<base::StringPiece16>(utf16.length())); | 258 offset = string16::npos; |
| 259 } |
254 std::string result; | 260 std::string result; |
255 PrepareForUTF8Output(utf16.data(), utf16.length(), &result); | 261 PrepareForUTF8Output(utf16.data(), utf16.length(), &result); |
256 OffsetAdjuster::Adjustments adjustments; | 262 OffsetAdjuster::Adjustments adjustments; |
257 ConvertUnicode(utf16.data(), utf16.length(), &result, &adjustments); | 263 ConvertUnicode(utf16.data(), utf16.length(), &result, &adjustments); |
258 OffsetAdjuster::AdjustOffsets(adjustments, offsets_for_adjustment); | 264 OffsetAdjuster::AdjustOffsets(adjustments, offsets_for_adjustment); |
259 return result; | 265 return result; |
260 } | 266 } |
261 | 267 |
262 } // namespace base | 268 } // namespace base |
OLD | NEW |