| 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 |