Symbian S 60プラットフォーム簡体字漢字処理詳細


一.UTF-8符号化文字列


1.リソースファイルのUTF-8符号化文字列
理論的には、リソースファイルから取得された文字列は、表示(ダイレクトスクリーン、アプリケーションタイトル、ボタン、メニュー、および各種UIコントロール)、およびファイルの書き込みなどの操作に直接使用することができる.ただし、Symbian OSのデフォルトコードはWindowsなどのオペレーティングシステムのデフォルトコードとは異なるため、Windowsなどの環境でリソースソースファイル(.rss、.rls、.loc)を編集する際には、ファイルのヘッダをCHARACTER_に追加する必要があります.SET UTF 8が設定され、UTF-8コードで保存され、コンパイルされたリソースファイルの文字列が正常に処理されます.特に、漢字という非ASCII標準文字(ここでのASCII標準文字は単バイト符号化文字を指し、漢字は拡張された多バイト符号化文字であり、一般的にGBK/GB 2312符号化である).
ファイルをUTF-8でエンコードして保存できるエディタには多くの(例えばWindowsのメモ帳)があるが、保存したファイルの先頭にある3バイトの長さのバイト順タグ(Byte Order Mark)を16ビットのエディタで削除して、システム識別(例えばWindowsのコマンドラインのEdit)をコンパイルすることが望ましい.これはS 603.0プラットフォームにとってなおさらである.
2.プログラムファイルのUTF-8符号化文字列
同様に、プログラムソースファイル(.cpp)の文字列もデフォルトではUTF-8符号化ではなく、直接使用するにはUTF-8符号化でプログラムソースファイルを保存する必要があります.たとえば、プログラム・ソース・ファイルには、次のようなものがあります.
_LIT( KUTF8String, " ");
CAknInformationNote* InfoNote;
InfoNote = new ( ELeave ) CAknInformationNote;
InfoNote->ExecuteLD( KUTF8String );

このソースファイルをメモ帳でUTF-8符号化として保存することで、コンパイル後に正常に表示され、符号化変換を必要としないが、コンパイル環境の認識の問題で注意しなければならないのは:
1).シミュレータプラットフォームアプリケーション(WINS、WINSCWなど)は、ファイルの先頭のバイト順タグ(Byte Order Mark)を削除することはできません.
2).ホストプラットフォームアプリケーション(THUMB、ARMI、GCEなど)は、ファイル先頭のバイト順タグ(Byte Order Mark)を削除する必要があります.
ちなみにCarbideにおける簡体字の処理は,工程や文書のテキスト符号化方式の修正に重点を置いている.通過についてinfまたは.mmpインポートのエンジニアリング(この方法が好ましい)は、インポート前のソースファイルがUTF-8符号化で保存されている前の要求に合致する限り、テキスト符号化方式を変更する必要はありません.新しいプロジェクトについては、リソースソースファイルにCHARACTERを追加する以外はSET UTF 8の設定は、ソースファイルのテキスト符号化方式をUTF-8に変更することが望ましい.そうしないと、CarbideはUTF-8符号化処理テキストを行わず、表示が正常ではない.具体的な方法は以下の通りです.
1).プロジェクトフォルダのリソースソースファイル->properties->Infoを右クリックし、Text file ecodingをothersのUTF-8に変更します.
2).プロジェクトフォルダ->properties->Infoを右クリックし、Text file encodingをothersのUTF-8に変更します.
両者を1つ取ればよいが,後者はエンジニアリングのすべてのソースファイルのテキスト符号化方式をUTF-8に変える.また、Carbideでは、テキスト符号化方式の変更、特にリソースソースファイルがある場合は、文字列を再書き込みし、クリアした後にアプリケーションまたは実行(buildまたはrun)を確立することが望ましい.そうしないと、前回の結果がこの確立に影響を与える可能性がある.

二.非UTF-8符号化文字列


前述したように、プログラムソースファイルをUTF-8符号化で保存しない場合、プログラムソースファイル(.cpp)の文字列は、非UTF-8符号化文字列となる.正常に動作するには、符号化変換が必要ですが、UTF-8符号化に変換するのではなく、Unicode(標準のUnicodeはUTF-16とも呼ばれます)符号化に変換する必要があります.例:
_LIT8( KNonUnicodeString, " ");
TPtrC8 point8( KNonUnicodeString );
CCnvCharacterSetConverter* characterSetConverter=CCnvCharacterSetConverter::NewLC();
// Windows Gb2312 Gbk(ASCII , ASCI )
if( converter->PrepareToConvertToOrFromL(KCharacterSetIdentifierGbk,
iEikonEnv->FsSession()) == CCnvCharacterSetConverter::EAvailable )
{
}
else if ( characterSetConverter->PrepareToConvertToOrFromL(KCharacterSetIdentifierGb2312,
iEikonEnv->FsSession())!= CCnvCharacterSetConverter::EAvailable )
{
CleanupStack::PopAndDestroy();
User::Leave( KErrNotSupported );
}
TInt state=CCnvCharacterSetConverter::KStateDefault;
HBufC* UnicodeString = HBufC::NewL( point8 );
TPtr16 point16 = UnicodeString->Des();
if( CCnvCharacterSetConverter::EErrorIllFormedInput ==
characterSetConverter->ConvertToUnicode(point16, point8, state ) )
{
CleanupStack::PopAndDestroy();
User::Leave(KErrArgument);
}
CleanupStack::PopAndDestroy(2); // characterSetConverter UnicodeString

UnicodeStringはUnicode符号化の文字列であり、ファイルの表示や書き込みなどの操作に直接使用できます.簡体字列の表示は符号化の問題に加えてフォントの選択にも注意し,特にUIコントロールにはLatinBold 12()(2版),AknLayoutUtils::FontFromId(ElatinBold 12)(3版)を用いることが望ましい.簡体字列に表示される関連ドキュメントは、ルーチンが多く、ここではあまり話さない.ファイルの中の簡体字の漢字列の読み書きについては、いくつかの注意点を提出します.

1.自分で書いて自分で読む


Symbianのファイルサービスを利用して文字列をファイルに書き込むのは、一般的にフォーマット付きで、ファイルの頭文字は文字列に続く長さと符号化を表すために使用されるので、どんなファイルでも読むことができるわけではありません.例えば、メモ帳で編集したファイルは、フォーマットが正しい限り正しく読めません.このフォーマットは手書きで書くのは煩わしいです.だからプログラムの内部のファイルの読み書きに対して、最も良いのは:何を持って書くのは何を使って読んで、何を持って読むのは何を使って書きます.

2.UTF-8符号化簡体字シリアル読み書きファイル


リソースファイルから読み出すも、cppで定義されたUTF-8符号化文字列は、符号化変換を必要とせずに直接書くことができます.例:
// 
_LIT( KFileName, "//private//xxxxxxxx//aTextFile.txt" );
RFs FileServerSession;
User::LeaveIfError(FileServerSession.Connect());
RFile file;
if ( file.Replace(FileServerSession, KFileName, EFileWrite ) != KErrNone )
{
return;
}
CleanupClosePushL( file );
_LIT( KUTF8String, " ");// HBufC* UTF8ResourceString = StringLoader::LoadLC( R_UTF8_RESOURCE_STRING );
RFileWriteStream StreamWriteToFile( file );
CleanupClosePushL( StreamWriteToFile );
StreamWriteToFile << KUTF8String;// StreamWriteToFile << *UTF8ResourceString
CleanupStack::PopAndDestroy(2); //file StreamWriteToFile

//
RFs FileServerSession;
RFile file;
User::LeaveIfError(FileServerSession.Connect());
CleanupClosePushL(FileServerSession);
User::LeaveIfError(file.Open(FileServerSession,KHelloFileName, EFileStreamText));
CleanupClosePushL(file);
RFileReadStream StreamReadFromFile(file);
CleanupClosePushL(StreamReadFromFile);
HBufC* StreamData= HBufC::NewLC(StreamReadFromFile, 32);
CleanupStack::PopAndDestroy(3); //file StreamReadFromFile StreamData
FileServerSession.Close();

得られたStreamDataは以下の通りです.
CAknInformationNote* InfoNote;
InfoNote = new ( ELeave ) CAknInformationNote;
InfoNote->ExecuteLD( *StreamData )

を行ないます.

3.非UTF-8符号化簡体字列読み書きファイル:


前述したように、非UTF 8符号化簡体字列は符号化変換を行う必要があり、主に2つの方法がある.
  • 1).文字列をUnicodeコードに変換してファイルに書き込んだ後、直接読み込む:
  • // 
    _LIT( KFileName, "//private//xxxxxxxx//aTextFile.txt" );
    RFs FileServerSession;
    User::LeaveIfError(FileServerSession.Connect());
    RFile file;
    if ( file.Replace(FileServerSession, KFileName, EFileWrite ) != KErrNone )
    {
    return;
    }
    CleanupClosePushL( file );

    _LIT8( KNonUnicodeString, " ");
    TPtrC8 point8( KNonUnicodeString );
    CCnvCharacterSetConverter* characterSetConverter=CCnvCharacterSetConverter::NewLC();
    if( converter->PrepareToConvertToOrFromL(KCharacterSetIdentifierGbk,
    iEikonEnv->FsSession()) == CCnvCharacterSetConverter::EAvailable )
    {
    }
    else if ( characterSetConverter->PrepareToConvertToOrFromL(KCharacterSetIdentifierGb2312,
    iEikonEnv->FsSession())!= CCnvCharacterSetConverter::EAvailable )
    {
    CleanupStack::PopAndDestroy();
    User::Leave( KErrNotSupported );
    }
    TInt state=CCnvCharacterSetConverter::KStateDefault;
    HBufC* UnicodeString = HBufC::NewL( point8 );
    TPtr16 point16 = UnicodeString->Des();
    if( CCnvCharacterSetConverter::EErrorIllFormedInput ==
    characterSetConverter->ConvertToUnicode(point16, point8, state ) )
    {
    CleanupStack::PopAndDestroy();
    User::Leave(KErrArgument);
    }

    RFileWriteStream StreamWriteToFile( file );
    CleanupClosePushL( StreamWriteToFile );
    StreamWriteToFile << *UnicodeString;
    CleanupStack::PopAndDestroy(4);//file StreamWriteToFile characterSetConverter UnicodeString
    FileServerSession.Close();

    直接読み取りの方法は、UTF-8符号化簡体字列読み書きファイルの読み取り操作と同じである.
  • 2).文字列を直接ファイルに書き込んでから変換を読み込む:
  • 直接ファイルを書く方法はUTF-8符号化簡体字列読み書きファイルの書き込み操作と同じである.
    // 
    RFs FileServerSession;
    RFile file;
    User::LeaveIfError(FileServerSession.Connect());
    CleanupClosePushL(FileServerSession);
    User::LeaveIfError(file.Open(FileServerSession,KHelloFileName, EFileStreamText));
    CleanupClosePushL(file);
    RFileReadStream StreamReadFromFile(file);
    CleanupClosePushL(StreamReadFromFile);
    HBufC* StreamData = HBufC::NewLC(StreamReadFromFile, 32);
    HBufC8* StreamData8 = HBufC8::NewLC( StreamData->Length() );
    StreamData8->Des().Copy(*StreamData);

    TPtrC8 point8( *StreamData8 );
    CCnvCharacterSetConverter* characterSetConverter=CCnvCharacterSetConverter::NewLC();
    if( converter->PrepareToConvertToOrFromL(KCharacterSetIdentifierGbk,
    iEikonEnv->FsSession()) == CCnvCharacterSetConverter::EAvailable )
    {
    }
    else if ( characterSetConverter->PrepareToConvertToOrFromL(KCharacterSetIdentifierGb2312,
    iEikonEnv->FsSession())!= CCnvCharacterSetConverter::EAvailable )
    {
    CleanupStack::PopAndDestroy();
    User::Leave( KErrNotSupported );
    }
    TInt state=CCnvCharacterSetConverter::KStateDefault;
    HBufC* UnicodeString = HBufC::NewL( point8 );
    TPtr16 point16 = UnicodeString->Des();
    if( CCnvCharacterSetConverter::EErrorIllFormedInput ==
    characterSetConverter->ConvertToUnicode(point16, point8, state ) )
    {
    CleanupStack::PopAndDestroy();
    User::Leave(KErrArgument);
    }

    CleanupStack::PopAndDestroy(6); //file StreamReadFromFile StreamData StreamData8 characterSetConverter UnicodeString
    FileServerSession.Close();

    得られたUnicodeStringは、
    CAknInformationNote* InfoNote;
    InfoNote = new ( ELeave ) CAknInformationNote;
    InfoNote->ExecuteLD( *UnicodeString );

    を行ないます.
    以上のコードの統合開発環境は次のとおりです.
    Active Perl 5.6.1 build 631
    Java Runtime Enviroment v1.5.0_07
    CodeWarrior Personal Edition 3.1
    S60 3RD EDITION SDK FOR SYMBIAN OS, FOR C++
    コマンドラインで作成されたアプリケーションで正常(WINSCW、GCCE)であることを確認します.他のアプリケーションの確立やIDEが相応の変化を必要としたり、まったく実行できない場合は、ここでは考え方と方法を提供するだけです.
    要するに、簡体字の処理は、文字符号化の把握が最も重要であり、結局は異なる符号化状況に応じて相応の符号化変換操作を行うことである.最も理想的で開発環境の影響を受けない方法は個人的には、リソースファイル法、すなわち文字列をUTF-8符号化でリソースソースファイルに保存し、UTF-8符号化で処理するように設定することであると考えられる.最も簡便で、最も効果的で、ローカライズされた移植に便利です.他の方法は、参照と実行可能なスキームを提供するだけです.
    実際,本論文で論じた手法は簡体字漢字だけでなく,理論的にはすべての非ANSII標準文字に適用できる.

    追記:バイト順タグ(Byte Order Mark)


    BOM(Byte Order Mark)は、Unicode規格(UTF-16)導入後、Unicode純テキストファイルに対してそのビット順を判断するタグであり、UTF-16 Little Endianバイト順(0 xFF,0 xFE)であり、UTF-16 Big Endianで(0 xFE,0 xFF)である.対応するUTF-16からUTF-8への変換が行われると、ここで2バイトは、3バイトのUTF-8符号化バイトシーケンスタグとして処理される.