aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/lang/natString.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/lang/natString.cc')
-rw-r--r--libjava/java/lang/natString.cc95
1 files changed, 83 insertions, 12 deletions
diff --git a/libjava/java/lang/natString.cc b/libjava/java/lang/natString.cc
index 5a28c1e..c05aeb9 100644
--- a/libjava/java/lang/natString.cc
+++ b/libjava/java/lang/natString.cc
@@ -24,6 +24,7 @@ details. */
#include <java/io/OutputStreamWriter.h>
#include <java/io/ByteArrayInputStream.h>
#include <java/io/InputStreamReader.h>
+#include <java/util/Locale.h>
#include <gnu/gcj/convert/UnicodeToBytes.h>
#include <gnu/gcj/convert/BytesToUnicode.h>
#include <jvm.h>
@@ -33,6 +34,14 @@ static int strhash_count = 0; /* Number of slots used in strhash. */
static int strhash_size = 0; /* Number of slots available in strhash.
* Assumed be power of 2! */
+// Some defines used by toUpperCase / toLowerCase.
+#define ESSET 0x00df
+#define CAPITAL_S 0x0053
+#define SMALL_I 0x0069
+#define CAPITAL_I_WITH_DOT 0x0130
+#define SMALL_DOTLESS_I 0x0131
+#define CAPITAL_I 0x0049
+
#define DELETED_STRING ((jstring)(~0))
#define SET_STRING_IS_INTERNED(STR) /* nothing */
@@ -755,16 +764,32 @@ java::lang::String::replace (jchar oldChar, jchar newChar)
}
jstring
-java::lang::String::toLowerCase ()
+java::lang::String::toLowerCase (java::util::Locale *locale)
{
jint i;
jchar* chrs = JvGetStringChars(this);
jchar ch;
+
+ bool handle_tr = false;
+ if (locale != NULL)
+ {
+ String *lang = locale->getLanguage ();
+ if (lang->length () == 2
+ && lang->charAt (0) == 't'
+ && lang->charAt (1) == 'r')
+ handle_tr = true;
+ }
+
for (i = 0; ; i++)
{
if (i == count)
return this;
jchar origChar = chrs[i];
+
+ if (handle_tr && (origChar == CAPITAL_I
+ || origChar == CAPITAL_I_WITH_DOT))
+ break;
+
ch = java::lang::Character::toLowerCase(origChar);
if (ch != origChar)
break;
@@ -776,34 +801,80 @@ java::lang::String::toLowerCase ()
*dPtr++ = ch; i++;
for (; i < count; i++)
{
- *dPtr++ = java::lang::Character::toLowerCase(chrs[i]);
+ if (handle_tr && chrs[i] == CAPITAL_I)
+ *dPtr++ = SMALL_DOTLESS_I;
+ else if (handle_tr && chrs[i] == CAPITAL_I_WITH_DOT)
+ *dPtr++ = SMALL_I;
+ else
+ *dPtr++ = java::lang::Character::toLowerCase(chrs[i]);
}
return result;
}
jstring
-java::lang::String::toUpperCase ()
+java::lang::String::toUpperCase (java::util::Locale *locale)
{
jint i;
jchar* chrs = JvGetStringChars(this);
jchar ch;
+
+ // When handling a specific locale there might be special rules.
+ // Currently all existing rules are simply handled inline, as there
+ // are only two and they are documented in the online 1.2 docs.
+ bool handle_esset = locale != NULL;
+ bool handle_tr = false;
+ if (locale != NULL)
+ {
+ String *lang = locale->getLanguage ();
+ if (lang->length () == 2
+ && lang->charAt (0) == 't'
+ && lang->charAt (1) == 'r')
+ handle_tr = true;
+ }
+
+ int new_count = count;
+ bool new_string = false;
for (i = 0; ; i++)
{
if (i == count)
- return this;
+ break;
jchar origChar = chrs[i];
- ch = java::lang::Character::toUpperCase(origChar);
- if (ch != origChar)
+
+ if (handle_esset && origChar == ESSET)
+ {
+ ++new_count;
+ new_string = true;
+ }
+ else if (handle_tr && (origChar == SMALL_I
+ || origChar == SMALL_DOTLESS_I))
+ new_string = true;
+ else
+ {
+ ch = java::lang::Character::toUpperCase(origChar);
+ if (ch != origChar)
+ new_string = true;
+ }
+
+ if (new_string && ! handle_esset)
break;
}
- jstring result = JvAllocString(count);
+ if (! new_string)
+ return this;
+ jstring result = JvAllocString(new_count);
jchar *dPtr = JvGetStringChars (result);
- for (int j = 0; j < i; j++)
- *dPtr++ = chrs[j];
- *dPtr++ = ch; i++;
- for (; i < count; i++)
+ for (i = 0; i < count; i++)
{
- *dPtr++ = java::lang::Character::toUpperCase(chrs[i]);
+ if (handle_esset && chrs[i] == ESSET)
+ {
+ *dPtr++ = CAPITAL_S;
+ *dPtr++ = CAPITAL_S;
+ }
+ else if (handle_tr && chrs[i] == SMALL_I)
+ *dPtr++ = CAPITAL_I_WITH_DOT;
+ else if (handle_tr && chrs[i] == SMALL_DOTLESS_I)
+ *dPtr++ = CAPITAL_I;
+ else
+ *dPtr++ = java::lang::Character::toUpperCase(chrs[i]);
}
return result;
}