gcj/19


gcj

19. UTF-8

さすがにいつまでもLatin1(ISO 8859-1)決め打ち(→gcj/15)はまずい。そろそろUTF-8をサポートするか。

Unicode

Unicodeは時代別に変遷がある。(注:いい加減な説明)

  1. UCS-2(16bit)
  2. UCS-4(32bit)
  3. UTF-32(U+000000〜U+10FFFF) ← 今ここ

UCS-2

UCS-4

UTF-16

UTF-32

UTF-8

RFC 3629 日本語訳原文

16進数2進数
0000 0000-0000 007F0xxxxxxx
0000 0080-0000 07FF110xxxxx 10xxxxxx
0000 0800-0000 FFFF1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

実装方針

UTF-8

実装

  1. 変換後の長さを調べる。
  2. 調べた長さに従って、変換結果を格納するためのバッファを用意する。
  3. 実際に変換していく。

javalang.cpp

UTF-8からjava.lang.Stringに変換する関数を追加

jstring _Jv_NewStringUTF(const char* bytes) {
	int len = 0;
	for (const unsigned char* p = (const unsigned char*)bytes; *p != '\0'; p++, len++) {
		if (*p >= 0xe0)
			p += 2;
		else if (*p >= 0xc0)
			p++;
	}
	jstring s = new ::java::lang::String();
	s->data = JvNewCharArray(len);
	s->count = len;
	jchar* ch = _Jv_GetStringChars(s);
	for (const unsigned char* p = (const unsigned char*)bytes; *p != '\0'; p++, ch++) {
		if (*p >= 0xe0) {
			*ch = ((p[0] & 0x0f) << 12) | ((p[1] & 0x3f) << 6) | (p[2] & 0x3f);
			p += 2;
		} else if (*p >= 0xc0) {
			*ch = ((p[0] & 0x1f) << 6) | (p[1] & 0x3f);
			p++;
		} else {
			*ch = *p & 0x7f;
		}
	}
	return s;
}

Class.cpp

今までインチキしていた部分を修正

[修正前] *p = JvNewStringLatin1(((_Jv_Utf8Const*)*p)->data);
[修正後] *p = JvNewStringUTF(((_Jv_Utf8Const*)*p)->data);

java/lang/String.java

今回直接使うわけじゃないけど、ついでにコンストラクタを追加。

	public String(char[] chars) {
		count = chars.length;
		data = new char[count];
		for (int i = 0; i < count; i++)
			data[i] = chars[i];
	}

テスト

一文字ずつ(gcjがUnicodeに変換)と文字列(_Jv_NewStringUTF使用)とで結果を比較。

A.java

public class A {
	public static void main(String[] args) {
		char[] chars = new char[] { 'こ', 'ん', 'に', 'ち', 'は', '世', '界' };
		String s = "こんにちは世界";
		for (int i = 0; i < chars.length; i++) {
			char ch1 = chars[i], ch2 = s.charAt(i);
			System.out.print((int)ch1);
			System.out.print(" - ");
			System.out.print((int)ch2);
			System.out.println(ch1 == ch2 ? " : OK" : " : NG");
		}
	}
}

実行結果

12371 - 12371 : OK
12435 - 12435 : OK
12395 - 12395 : OK
12385 - 12385 : OK
12399 - 12399 : OK
19990 - 19990 : OK
30028 - 30028 : OK

作業結果

掲載保留中(スマソ

Monaでの実行結果

ちなみにMonaではUTF-8の日本語文字列を表示可能なので、UTF-16 -> UTF-8 にしてやれば System.out.println で表示可能と思われる(@ BayGUIのたーみなる)。

gcj.gif

コメント

コメントはありません。 コメント/gcj/19?

お名前:

MENU

now: 3

リンク


最新の20件
2018-09-03 2018-05-09 2017-09-29 2017-01-10 2016-12-11 2016-10-04 2016-08-14 2016-06-05 2016-05-29 2016-04-15 2015-12-28 2013-02-25 2013-02-21 2013-02-20 2013-02-12 2013-02-11 2013-02-10
最新の20件
2010-02-01 2010-01-31 2010-01-30 2010-01-29 2010-01-16

Counter: 4895, today: 2, yesterday: 0

添付ファイル: filegcj.gif 765件 [詳細] file19.zip 713件 [詳細]

リロード   新規 編集 凍結 差分 添付 複製 改名   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS

Last-modified: 2008-03-28 (金) 15:48:00 (3831d);  Modified by mona
PukiWiki 1.4.6 Copyright © 2001-2005 PukiWiki Developers Team. License is GPL.
Based on "PukiWiki" 1.3 by yu-ji
Powered by PHP 5.2.17
HTML convert time to 0.041 sec.