// natCharacter.cc - Native part of Character class. /* Copyright (C) 1998, 1999 Free Software Foundation This file is part of libgcj. This software is copyrighted work licensed under the terms of the Libgcj License. Please consult the file "LIBGCJ_LICENSE" for details. */ #include <config.h> #include <gcj/cni.h> #include <jvm.h> #include <java/lang/Character.h> #include <java-chartables.h> #define asize(x) ((sizeof (x)) / sizeof (x[0])) static jchar to_lower_title (jchar ch) { for (unsigned int i = 0; i < asize (title_to_upper_table); ++i) { // We can assume that the entries in the two tables are // parallel. This is checked in the script. if (title_to_upper_table[i][1] == ch || title_to_upper_table[i][0] == ch) return title_to_lower_table[i][1]; } return ch; } static jchar to_upper_title (jchar ch) { for (unsigned int i = 0; i < asize (title_to_lower_table); ++i) { // We can assume that the entries in the two tables are // parallel. This is checked in the script. if (title_to_lower_table[i][1] == ch || title_to_lower_table[i][0] == ch) return title_to_upper_table[i][1]; } return ch; } jboolean java::lang::Character::isTitleCase (jchar ch) { for (unsigned int i = 0; i < asize (title_to_lower_table); ++i) { if (title_to_lower_table[i][0] == ch) return true; } return false; } jchar java::lang::Character::toTitleCase (jchar ch) { // Both titlecase mapping tables have the same length. This is // checked in the chartables script. for (unsigned int i = 0; i < asize (title_to_lower_table); ++i) { if (title_to_lower_table[i][0] == ch) return ch; if (title_to_lower_table[i][1] == ch) return title_to_lower_table[i][0]; if (title_to_upper_table[i][1] == ch) return title_to_upper_table[i][0]; } return toUpperCase (ch); } #ifdef COMPACT_CHARACTER static int table_search (const jchar table[][2], int table_len, jchar ch) { int low, high, i, old; low = 0; high = table_len; i = high / 2; while (true) { if (ch < table[i][0]) high = i; else if (ch > table[i][1]) low = i; else return i; old = i; i = (high + low) / 2; if (i == old) break; } return -1; } jint java::lang::Character::digit_value (jchar ch) { int index = table_search (digit_table, asize (digit_table), ch); if (index == -1) return -1; jchar base = digit_table[index][0]; // Tamil doesn't have a digit `0'. So we special-case it here. if (base == TAMIL_DIGIT_ONE) return ch - base + 1; return ch - base; } jint java::lang::Character::getNumericValue (jchar ch) { jint d = digit (ch, 36); if (d != -1) return d; for (unsigned int i = 0; i < asize (numeric_table); ++i) { if (numeric_table[i] == ch) return numeric_value[i]; } return -1; } jint java::lang::Character::getType (jchar ch) { int index = table_search (all_table, asize (all_table), ch); if (index != -1) return category_table[index]; return UNASSIGNED; } jboolean java::lang::Character::isLowerCase (jchar ch) { if (ch >= 0x2000 && ch <= 0x2fff) return false; if (table_search (lower_case_table, asize (lower_case_table), ch) != -1) return true; int low, high, i, old; low = 0; high = asize (lower_anomalous_table); i = high / 2; while (true) { if (ch < lower_anomalous_table[i]) high = i; else if (ch > lower_anomalous_table[i]) low = i; else return true; old = i; i = (high + low) / 2; if (i == old) break; } return false; } jboolean java::lang::Character::isSpaceChar (jchar ch) { return table_search (space_table, asize (space_table), ch) != -1; } jboolean java::lang::Character::isUpperCase (jchar ch) { if (ch >= 0x2000 && ch <= 0x2fff) return false; return table_search (upper_case_table, asize (upper_case_table), ch) != -1; } jchar java::lang::Character::toLowerCase (jchar ch) { int index = table_search (upper_case_table, asize (upper_case_table), ch); if (index == -1) return to_lower_title (ch); return (jchar) (ch - upper_case_table[index][0] + upper_case_map_table[index]); } jchar java::lang::Character::toUpperCase (jchar ch) { int index = table_search (lower_case_table, asize (lower_case_table), ch); if (index == -1) return to_upper_title (ch); return (jchar) (ch - lower_case_table[index][0] + lower_case_map_table[index]); } #else /* COMPACT_CHARACTER */ jint java::lang::Character::digit_value (jchar ch) { if (type_table[ch] == DECIMAL_DIGIT_NUMBER) return attribute_table[ch]; return -1; } jint java::lang::Character::getNumericValue (jchar ch) { jint d = digit (ch, 36); if (d != -1) return d; // Some characters require two attributes. We special-case them here. if (ch >= ROMAN_START && ch <= ROMAN_END) return secondary_attribute_table[ch - ROMAN_START]; if (type_table[ch] == LETTER_NUMBER || type_table[ch] == OTHER_NUMBER) return attribute_table[ch]; return -1; } jint java::lang::Character::getType (jchar ch) { return type_table[ch]; } jboolean java::lang::Character::isLowerCase (jchar ch) { if (ch >= 0x2000 && ch <= 0x2fff) return false; return type_table[ch] == LOWERCASE_LETTER; } jboolean java::lang::Character::isSpaceChar (jchar ch) { return (type_table[ch] == SPACE_SEPARATOR || type_table[ch] == LINE_SEPARATOR || type_table[ch] == PARAGRAPH_SEPARATOR); } jboolean java::lang::Character::isUpperCase (jchar ch) { if (ch >= 0x2000 && ch <= 0x2fff) return false; return type_table[ch] == UPPERCASE_LETTER; } jchar java::lang::Character::toLowerCase (jchar ch) { if (type_table[ch] == UPPERCASE_LETTER) return attribute_table[ch]; return to_lower_title (ch); } jchar java::lang::Character::toUpperCase (jchar ch) { if (type_table[ch] == LOWERCASE_LETTER) return attribute_table[ch]; return to_upper_title (ch); } #endif /* COMPACT_CHARACTER */