1cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka/* 2cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * Copyright (C) 2012 The Android Open Source Project 3cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * 4cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); 5cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * you may not use this file except in compliance with the License. 6cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * You may obtain a copy of the License at 7cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * 8cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0 9cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * 10cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software 11cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, 12cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * See the License for the specific language governing permissions and 14cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * limitations under the License. 15cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka */ 16cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka 17cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaokapackage com.android.inputmethod.latin; 18cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka 19cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaokaimport android.text.TextUtils; 20cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka 21cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaokaimport java.util.ArrayList; 2211d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaokaimport java.util.Locale; 23cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka 24cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaokapublic class StringUtils { 25cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka private StringUtils() { 26cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka // This utility class is not publicly instantiable. 27cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka } 28cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka 29cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka public static int codePointCount(String text) { 30cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka if (TextUtils.isEmpty(text)) return 0; 31cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka return text.codePointCount(0, text.length()); 32cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka } 33cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka 34344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka public static boolean containsInArray(String key, String[] array) { 35344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka for (final String element : array) { 36344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka if (key.equals(element)) return true; 37cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka } 38cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka return false; 39cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka } 40cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka 41344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka public static boolean containsInCsv(String key, String csv) { 42344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka if (TextUtils.isEmpty(csv)) return false; 43344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka return containsInArray(key, csv.split(",")); 44344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka } 45344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka 46344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka public static String appendToCsvIfNotExists(String key, String csv) { 47344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka if (TextUtils.isEmpty(csv)) return key; 48344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka if (containsInCsv(key, csv)) return csv; 49344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka return csv + "," + key; 50344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka } 51344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka 52344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka public static String removeFromCsvIfExists(String key, String csv) { 53344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka if (TextUtils.isEmpty(csv)) return ""; 54344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka final String[] elements = csv.split(","); 55344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka if (!containsInArray(key, elements)) return csv; 56344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka final ArrayList<String> result = new ArrayList<String>(elements.length - 1); 57344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka for (final String element : elements) { 58344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka if (!key.equals(element)) result.add(element); 59344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka } 60344af156744c6866090fb70f151efd66668c1e20Tadashi G. Takaoka return TextUtils.join(",", result); 61cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka } 62cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka 63cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka /** 64cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * Returns true if a and b are equal ignoring the case of the character. 65cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * @param a first character to check 66cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * @param b second character to check 67cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * @return {@code true} if a and b are equal, {@code false} otherwise. 68cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka */ 69cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka public static boolean equalsIgnoreCase(char a, char b) { 70cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka // Some language, such as Turkish, need testing both cases. 71cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka return a == b 72cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka || Character.toLowerCase(a) == Character.toLowerCase(b) 73cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka || Character.toUpperCase(a) == Character.toUpperCase(b); 74cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka } 75cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka 76cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka /** 77cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * Returns true if a and b are equal ignoring the case of the characters, including if they are 78cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * both null. 79cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * @param a first CharSequence to check 80cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * @param b second CharSequence to check 81cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * @return {@code true} if a and b are equal, {@code false} otherwise. 82cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka */ 83cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka public static boolean equalsIgnoreCase(CharSequence a, CharSequence b) { 84cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka if (a == b) 85cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka return true; // including both a and b are null. 86cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka if (a == null || b == null) 87cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka return false; 88cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka final int length = a.length(); 89cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka if (length != b.length()) 90cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka return false; 91cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka for (int i = 0; i < length; i++) { 92cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka if (!equalsIgnoreCase(a.charAt(i), b.charAt(i))) 93cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka return false; 94cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka } 95cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka return true; 96cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka } 97cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka 98cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka /** 99cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * Returns true if a and b are equal ignoring the case of the characters, including if a is null 100cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * and b is zero length. 101cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * @param a CharSequence to check 102cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * @param b character array to check 103cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * @param offset start offset of array b 104cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * @param length length of characters in array b 105cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * @return {@code true} if a and b are equal, {@code false} otherwise. 106cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * @throws IndexOutOfBoundsException 107cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * if {@code offset < 0 || length < 0 || offset + length > data.length}. 108cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * @throws NullPointerException if {@code b == null}. 109cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka */ 110cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka public static boolean equalsIgnoreCase(CharSequence a, char[] b, int offset, int length) { 111cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka if (offset < 0 || length < 0 || length > b.length - offset) 112cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka throw new IndexOutOfBoundsException("array.length=" + b.length + " offset=" + offset 113cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka + " length=" + length); 114cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka if (a == null) 115cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka return length == 0; // including a is null and b is zero length. 116cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka if (a.length() != length) 117cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka return false; 118cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka for (int i = 0; i < length; i++) { 119cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka if (!equalsIgnoreCase(a.charAt(i), b[offset + i])) 120cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka return false; 121cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka } 122cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka return true; 123cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka } 124cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka 125cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka /** 1260806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang * Returns true if cs contains any upper case characters. 1270806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang * 1280806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang * @param cs the CharSequence to check 1290806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang * @return {@code true} if cs contains any upper case characters, {@code false} otherwise. 1300806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang */ 1310806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang public static boolean hasUpperCase(final CharSequence cs) { 1320806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang final int length = cs.length(); 1330806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang for (int i = 0, cp = 0; i < length; i += Character.charCount(cp)) { 1340806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang cp = Character.codePointAt(cs, i); 1350806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang if (Character.isUpperCase(cp)) { 1360806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang return true; 1370806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang } 1380806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang } 1390806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang return false; 1400806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang } 1410806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang 1420806bb01d9e857db9fbac38b9b6e77feb9e9e4c9Tom Ouyang /** 143cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * Remove duplicates from an array of strings. 144cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * 145a4c7733cf7b5c0f970d1a8e52ee52b6199f56031Tadashi G. Takaoka * This method will always keep the first occurrence of all strings at their position 146cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka * in the array, removing the subsequent ones. 147cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka */ 148cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka public static void removeDupes(final ArrayList<CharSequence> suggestions) { 149cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka if (suggestions.size() < 2) return; 150cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka int i = 1; 151cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka // Don't cache suggestions.size(), since we may be removing items 152cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka while (i < suggestions.size()) { 153cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka final CharSequence cur = suggestions.get(i); 154cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka // Compare each suggestion with each previous suggestion 155cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka for (int j = 0; j < i; j++) { 156cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka CharSequence previous = suggestions.get(j); 157cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka if (TextUtils.equals(cur, previous)) { 158adf218eed544f2239ca5394b8a6bcc542d89a4d9Jean Chalard suggestions.remove(i); 159cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka i--; 160cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka break; 161cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka } 162cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka } 163cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka i++; 164cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka } 165cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka } 16611d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka 16711d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka public static String toTitleCase(String s, Locale locale) { 16811d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka if (s.length() <= 1) { 16911d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka // TODO: is this really correct? Shouldn't this be s.toUpperCase()? 17011d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka return s; 17111d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka } 17211d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka // TODO: fix the bugs below 17311d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka // - This does not work for Greek, because it returns upper case instead of title case. 17411d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka // - It does not work for Serbian, because it fails to account for the "lj" character, 17511d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka // which should be "Lj" in title case and "LJ" in upper case. 17611d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka // - It does not work for Dutch, because it fails to account for the "ij" digraph, which 17711d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka // are two different characters but both should be capitalized as "IJ" as if they were 17811d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka // a single letter. 17911d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka // - It also does not work with unicode surrogate code points. 18011d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka return s.toUpperCase(locale).charAt(0) + s.substring(1); 18111d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka } 18280111f08e284655808380663f0b68547b981da72Jean Chalard 18380111f08e284655808380663f0b68547b981da72Jean Chalard public static int[] toCodePointArray(final String string) { 18480111f08e284655808380663f0b68547b981da72Jean Chalard final char[] characters = string.toCharArray(); 18580111f08e284655808380663f0b68547b981da72Jean Chalard final int length = characters.length; 18680111f08e284655808380663f0b68547b981da72Jean Chalard final int[] codePoints = new int[Character.codePointCount(characters, 0, length)]; 18780111f08e284655808380663f0b68547b981da72Jean Chalard int codePoint = Character.codePointAt(characters, 0); 18880111f08e284655808380663f0b68547b981da72Jean Chalard int dsti = 0; 18980111f08e284655808380663f0b68547b981da72Jean Chalard for (int srci = Character.charCount(codePoint); 19080111f08e284655808380663f0b68547b981da72Jean Chalard srci < length; srci += Character.charCount(codePoint), ++dsti) { 19180111f08e284655808380663f0b68547b981da72Jean Chalard codePoints[dsti] = codePoint; 19280111f08e284655808380663f0b68547b981da72Jean Chalard codePoint = Character.codePointAt(characters, srci); 19380111f08e284655808380663f0b68547b981da72Jean Chalard } 19480111f08e284655808380663f0b68547b981da72Jean Chalard codePoints[dsti] = codePoint; 19580111f08e284655808380663f0b68547b981da72Jean Chalard return codePoints; 19680111f08e284655808380663f0b68547b981da72Jean Chalard } 197cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka} 198