Merge "Fix max directionality in AndroidCharacter.getDirectionalities"
This commit is contained in:
@@ -25,9 +25,10 @@
|
|||||||
#include "unicode/uchar.h"
|
#include "unicode/uchar.h"
|
||||||
|
|
||||||
#define PROPERTY_UNDEFINED (-1)
|
#define PROPERTY_UNDEFINED (-1)
|
||||||
|
#define JAVA_LANG_CHARACTER_MAX_DIRECTIONALITY 18
|
||||||
|
|
||||||
// ICU => JDK mapping
|
// ICU => JDK mapping
|
||||||
static int directionality_map[U_CHAR_DIRECTION_COUNT] = {
|
static int directionality_map[JAVA_LANG_CHARACTER_MAX_DIRECTIONALITY + 1] = {
|
||||||
0, // U_LEFT_TO_RIGHT (0) => DIRECTIONALITY_LEFT_TO_RIGHT (0)
|
0, // U_LEFT_TO_RIGHT (0) => DIRECTIONALITY_LEFT_TO_RIGHT (0)
|
||||||
1, // U_RIGHT_TO_LEFT (1) => DIRECTIONALITY_RIGHT_TO_LEFT (1)
|
1, // U_RIGHT_TO_LEFT (1) => DIRECTIONALITY_RIGHT_TO_LEFT (1)
|
||||||
3, // U_EUROPEAN_NUMBER (2) => DIRECTIONALITY_EUROPEAN_NUMBER (3)
|
3, // U_EUROPEAN_NUMBER (2) => DIRECTIONALITY_EUROPEAN_NUMBER (3)
|
||||||
@@ -75,7 +76,7 @@ static void getDirectionalities(JNIEnv* env, jobject obj, jcharArray srcArray,
|
|||||||
int c = 0x00010000 + ((src[i] - 0xD800) << 10) +
|
int c = 0x00010000 + ((src[i] - 0xD800) << 10) +
|
||||||
(src[i + 1] & 0x3FF);
|
(src[i + 1] & 0x3FF);
|
||||||
int dir = u_charDirection(c);
|
int dir = u_charDirection(c);
|
||||||
if (dir < 0 || dir >= U_CHAR_DIRECTION_COUNT)
|
if (dir < 0 || dir > JAVA_LANG_CHARACTER_MAX_DIRECTIONALITY)
|
||||||
dir = PROPERTY_UNDEFINED;
|
dir = PROPERTY_UNDEFINED;
|
||||||
else
|
else
|
||||||
dir = directionality_map[dir];
|
dir = directionality_map[dir];
|
||||||
@@ -85,7 +86,7 @@ static void getDirectionalities(JNIEnv* env, jobject obj, jcharArray srcArray,
|
|||||||
} else {
|
} else {
|
||||||
int c = src[i];
|
int c = src[i];
|
||||||
int dir = u_charDirection(c);
|
int dir = u_charDirection(c);
|
||||||
if (dir < 0 || dir >= U_CHAR_DIRECTION_COUNT)
|
if (dir < 0 || dir > JAVA_LANG_CHARACTER_MAX_DIRECTIONALITY)
|
||||||
dest[i] = PROPERTY_UNDEFINED;
|
dest[i] = PROPERTY_UNDEFINED;
|
||||||
else
|
else
|
||||||
dest[i] = directionality_map[dir];
|
dest[i] = directionality_map[dir];
|
||||||
@@ -96,7 +97,7 @@ static void getDirectionalities(JNIEnv* env, jobject obj, jcharArray srcArray,
|
|||||||
static jint getEastAsianWidth(JNIEnv* env, jobject obj, jchar input)
|
static jint getEastAsianWidth(JNIEnv* env, jobject obj, jchar input)
|
||||||
{
|
{
|
||||||
int width = u_getIntPropertyValue(input, UCHAR_EAST_ASIAN_WIDTH);
|
int width = u_getIntPropertyValue(input, UCHAR_EAST_ASIAN_WIDTH);
|
||||||
if (width < 0 || width >= U_EA_COUNT)
|
if (width < 0 || width > u_getIntPropertyMaxValue(UCHAR_EAST_ASIAN_WIDTH))
|
||||||
width = PROPERTY_UNDEFINED;
|
width = PROPERTY_UNDEFINED;
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
@@ -121,6 +122,7 @@ static void getEastAsianWidths(JNIEnv* env, jobject obj, jcharArray srcArray,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int maxWidth = u_getIntPropertyMaxValue(UCHAR_EAST_ASIAN_WIDTH);
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
const int srci = start + i;
|
const int srci = start + i;
|
||||||
if (src[srci] >= 0xD800 && src[srci] <= 0xDBFF &&
|
if (src[srci] >= 0xD800 && src[srci] <= 0xDBFF &&
|
||||||
@@ -129,7 +131,7 @@ static void getEastAsianWidths(JNIEnv* env, jobject obj, jcharArray srcArray,
|
|||||||
int c = 0x00010000 + ((src[srci] - 0xD800) << 10) +
|
int c = 0x00010000 + ((src[srci] - 0xD800) << 10) +
|
||||||
(src[srci + 1] & 0x3FF);
|
(src[srci + 1] & 0x3FF);
|
||||||
int width = u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH);
|
int width = u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH);
|
||||||
if (width < 0 || width >= U_EA_COUNT)
|
if (width < 0 || width > maxWidth)
|
||||||
width = PROPERTY_UNDEFINED;
|
width = PROPERTY_UNDEFINED;
|
||||||
|
|
||||||
dest[i++] = width;
|
dest[i++] = width;
|
||||||
@@ -137,7 +139,7 @@ static void getEastAsianWidths(JNIEnv* env, jobject obj, jcharArray srcArray,
|
|||||||
} else {
|
} else {
|
||||||
int c = src[srci];
|
int c = src[srci];
|
||||||
int width = u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH);
|
int width = u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH);
|
||||||
if (width < 0 || width >= U_EA_COUNT)
|
if (width < 0 || width > maxWidth)
|
||||||
width = PROPERTY_UNDEFINED;
|
width = PROPERTY_UNDEFINED;
|
||||||
|
|
||||||
dest[i] = width;
|
dest[i] = width;
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,d
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.text;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
|
||||||
|
import android.platform.test.annotations.Presubmit;
|
||||||
|
import android.support.test.filters.SmallTest;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@Presubmit
|
||||||
|
@SmallTest
|
||||||
|
public class AndroidCharacterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetDirectionalities_nonSupplementaryCharacters() {
|
||||||
|
int size = Character.MAX_VALUE + 1
|
||||||
|
- (Character.MAX_SURROGATE - Character.MIN_SURROGATE + 1);
|
||||||
|
char[] chars = new char[size];
|
||||||
|
byte[] java_lang_results = new byte[size];
|
||||||
|
int index = 0;
|
||||||
|
for (int cp = 0; cp <= Character.MAX_VALUE; cp++) {
|
||||||
|
// Exempt unassigned code point due to b/120074586
|
||||||
|
if (Character.getType(cp) != Character.UNASSIGNED) {
|
||||||
|
if (cp < Character.MIN_SURROGATE || cp > Character.MAX_SURROGATE) {
|
||||||
|
chars[index] = (char) cp;
|
||||||
|
java_lang_results[index] = Character.getDirectionality(cp);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] android_text_results = new byte[size];
|
||||||
|
AndroidCharacter.getDirectionalities(chars, android_text_results, index);
|
||||||
|
assertArrayEquals(java_lang_results, android_text_results);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetDirectionalities_supplementaryCharacters() {
|
||||||
|
int maxNumberOfChars = Character.MAX_CODE_POINT - Character.MIN_SUPPLEMENTARY_CODE_POINT
|
||||||
|
+ 1;
|
||||||
|
int size = maxNumberOfChars * 2;
|
||||||
|
char[] chars = new char[size];
|
||||||
|
byte[] java_lang_results = new byte[size];
|
||||||
|
int index = 0;
|
||||||
|
for (int cp = Character.MIN_SUPPLEMENTARY_CODE_POINT; cp <= Character.MAX_CODE_POINT;
|
||||||
|
cp++) {
|
||||||
|
// Exempt unassigned code point due to b/120074586
|
||||||
|
if (Character.getType(cp) != Character.UNASSIGNED) {
|
||||||
|
chars[index] = Character.highSurrogate(cp);
|
||||||
|
chars[index + 1] = Character.lowSurrogate(cp);
|
||||||
|
java_lang_results[index] = java_lang_results[index + 1] = Character
|
||||||
|
.getDirectionality(cp);
|
||||||
|
index += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] android_text_results = new byte[size];
|
||||||
|
AndroidCharacter.getDirectionalities(chars, android_text_results, index);
|
||||||
|
assertArrayEquals(java_lang_results, android_text_results);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user