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. 4 5 #ifndef BASE_STRINGS_UTF_OFFSET_STRING_CONVERSIONS_H_ 6 #define BASE_STRINGS_UTF_OFFSET_STRING_CONVERSIONS_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/base_export.h" 12 #include "base/strings/string16.h" 13 #include "base/strings/string_piece.h" 14 15 namespace base { 16 17 // Like the conversions in utf_string_conversions.h, but also takes one or more 18 // |offset[s]_for_adjustment| representing insertion/selection points between 19 // characters: if |src| is "abcd", then 0 is before 'a', 2 is between 'b' and 20 // 'c', and 4 is at the end of the string. Valid input offsets range from 0 to 21 // |src_len|. On exit, each offset will have been modified to point at the same 22 // logical position in the output string. If an offset cannot be successfully 23 // adjusted (e.g. because it points into the middle of a multibyte sequence), it 24 // will be set to string16::npos. 25 // 26 // |offset[s]_for_adjustment| may be NULL. 27 BASE_EXPORT bool UTF8ToUTF16AndAdjustOffset(const char* src, 28 size_t src_len, 29 string16* output, 30 size_t* offset_for_adjustment); 31 BASE_EXPORT bool UTF8ToUTF16AndAdjustOffsets( 32 const char* src, 33 size_t src_len, 34 string16* output, 35 std::vector<size_t>* offsets_for_adjustment); 36 37 BASE_EXPORT string16 UTF8ToUTF16AndAdjustOffset(const base::StringPiece& utf8, 38 size_t* offset_for_adjustment); 39 BASE_EXPORT string16 UTF8ToUTF16AndAdjustOffsets( 40 const base::StringPiece& utf8, 41 std::vector<size_t>* offsets_for_adjustment); 42 43 BASE_EXPORT std::string UTF16ToUTF8AndAdjustOffset( 44 const base::StringPiece16& utf16, 45 size_t* offset_for_adjustment); 46 BASE_EXPORT std::string UTF16ToUTF8AndAdjustOffsets( 47 const base::StringPiece16& utf16, 48 std::vector<size_t>* offsets_for_adjustment); 49 50 // Limiting function callable by std::for_each which will replace any value 51 // which is greater than |limit| with npos. Typically this is called with a 52 // string length to clamp offsets into the string to [0, length] (as opposed to 53 // [0, length); see comments above). 54 template <typename T> 55 struct LimitOffset { 56 explicit LimitOffset(size_t limit) 57 : limit_(limit) {} 58 59 void operator()(size_t& offset) { 60 if (offset > limit_) 61 offset = T::npos; 62 } 63 64 size_t limit_; 65 }; 66 67 // Stack object which, on destruction, will update a vector of offsets based on 68 // any supplied adjustments. To use, declare one of these, providing the 69 // address of the offset vector to adjust. Then Add() any number of Adjustments 70 // (each Adjustment gives the |original_offset| of a substring and the lengths 71 // of the substring before and after transforming). When the OffsetAdjuster 72 // goes out of scope, all the offsets in the provided vector will be updated. 73 class BASE_EXPORT OffsetAdjuster { 74 public: 75 struct BASE_EXPORT Adjustment { 76 Adjustment(size_t original_offset, 77 size_t original_length, 78 size_t output_length); 79 80 size_t original_offset; 81 size_t original_length; 82 size_t output_length; 83 }; 84 85 explicit OffsetAdjuster(std::vector<size_t>* offsets_for_adjustment); 86 ~OffsetAdjuster(); 87 88 void Add(const Adjustment& adjustment); 89 90 private: 91 void AdjustOffset(std::vector<size_t>::iterator offset); 92 93 std::vector<size_t>* offsets_for_adjustment_; 94 std::vector<Adjustment> adjustments_; 95 }; 96 97 } // namespace base 98 99 #endif // BASE_STRINGS_UTF_OFFSET_STRING_CONVERSIONS_H_ 100