[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[port139ml:02310] Re: TASK日本語ファイル名対応



たかはしもとのぶです。

>>確かにそうかも知れませんね。ちょっと UTF-8 で出力するように改造してみ
>>ましょう。といっても明日あさってと予定がたて込んでるので、ちょっとだめ
>
>わぁ〜〜い m(_ _)m

オプションで従来のロジックと切替えられるようにしようかとか考えたんです
が、とりあえずさくっと作ってみました。

--- ntfs.c.org	Mon Jan 13 06:58:16 2003
+++ ntfs.c	Sat Feb 15 21:42:12 2003
@@ -103,7 +103,7 @@
 void 
 uni2ascii(char *uni, int ulen, char *asc, int alen)
 {
-	int i, l;
+	int i, l, j;
 
 
 	/* find the maximum that we can go
@@ -115,15 +115,31 @@
 	else
 		l = ulen;
 
-	for (i = 0; i < l; i++) {
-		/* If this value is NULL, then stop */
-		if (uni[i*2] == 0 && uni[i*2 + 1] == 0)
-			break;
+	i = 0; j = 0;
 
-		if (isprint((int)uni[i*2]))
-			asc[i] = uni[i*2];
-		else
-			asc[i] = '?';
+	while (i < l) {
+	  unsigned short *uni2p = (unsigned short *)uni;
+	  /* If this value is NULL, then stop */
+	  if (uni2p[j] == 0)
+	    break;
+	  /* If this value is NULL, then stop */
+
+          if (uni2p[j] <= 0x7f) {
+	    asc[i] = uni2p[j] & 0x007f;
+	    i++;
+	  }
+	  else if (uni2p[j] <= 0x7ff) {
+	    asc[i] = 0xc0 | ((uni2p[j] & 0x7c0) >> 6);
+	    asc[i+1] = 0x80 | (uni2p[j] & 0x003f);
+	    i = i + 2;
+	  }
+	  else if (uni2p[j] > 0x800) {
+	    asc[i] = 0xe0 | ((uni2p[j] & 0xf000) >> 12);
+	    asc[i+1] = 0x80 | (uni2p[j] & 0xfc0) >> 6;
+	    asc[i+2] = 0x80 | (uni2p[j] & 0x003f);
+	    i = i + 3;
+	  }
+	  j++;
 	}
 	/* NULL Terminate */
 	asc[i] = '\0';

上記パッチを適用することで、とりあえず UTF-8 で出力されるようになります。

ただし、現在 char *asc でもらってきている文字列の長さが 128 〜 256 位
しかとられてませんので、このままだと長いファイル名を変換すると、簡単に
バッファオーバーフローします。

# UTF-8 にすると、最悪 ASCII 文字列の三倍長さが必要ですので。

まぁ、その辺りをどう本家にフィードバックするかは、少しやっていただける
と嬉しいです。たとえば、オプションで UTF-8 出力するかを制御するように
するかとか、UTF-8 することによってこれ以外に文字列長が長くなる可能性の
あるところがないかとか。

なぜ iconv() 使わなかったかは、依存するライブラリを増やさない方がよい
だろうということと、上記の通り対してコード量が増えるわけでもないという
理由です。

-----
TAKAHASHI, Motonobu (たかはしもとのぶ)         monyo@xxxxxxxxxxxxxx
                                               http://www.monyo.com/