フォーラム


ゲスト  

ようこそ ゲスト さん。このフォーラムに投稿するには 登録が必要です。

ページ: [1]
トピック: Mobile 用にサロゲートペアを考慮した Substring() を考える
DEKO
管理者
投稿数: 2693
Mobile 用にサロゲートペアを考慮した Substring() を考える
on: 2015/07/30 14:48 Thu

すんごい手抜きな方法は以下の通りです。

unit uMobileSurrogate;

interface

function Surrogate_SubString(s: string; const aStart, aLength: Integer): string;

implementation

function Surrogate_SubString(s: string; const aStart, aLength: Integer): string;
var
U4Src, U4Dst: UCS4String;
begin
U4Src := UnicodeStringToUCS4String(s);
U4Dst := Copy(U4Src, aStart, aLength);
SetLength(U4Dst, Length(U4Dst) + 1);
U4Dst[Length(U4Dst) - 1] := $00000000;
result := UCS4StringToUnicodeString(U4Dst);
end;

end.

 
すごく長い文字列を処理するのでなければ、速度的 (&メモリ使用量的) なペナルティは無視できると思います。

SetLength() してるのは Copy() が配列のコピーなので、UCS4String の最後に Null ターミネーターを付けてくれないからです。UCS4StringToUnicodeString() は Null ターミネーターがないと中途半端な文字列を返します。

DEKO
管理者
投稿数: 2693
Re: Mobile 用にサロゲートペアを考慮した Substring() を考える
on: 2015/07/30 15:20 Thu

RTL 読む限りでは SetLength() 後の Null ターミネーター代入は不要ですが、なんとなく気持ち悪いので入れてあります (^^;A

DEKO
管理者
投稿数: 2693
Re: Mobile 用にサロゲートペアを考慮した Substring() を考える
on: 2015/07/30 15:29 Thu

(RawByteString を含む) AnsiString も OS 固有の API も使っていないのでモバイルコンパイラ (NEXGEN) でも正しく動作します…というか、ご要望 (誰の?) がそれだったのでちゃんと動くようにしてあります。

マトモにやるなら、UnicodeString を1エレメントずつ WORD に変換し、上位ビットが 11011 で始まるかどうかを判定し、サロゲートペアであるかどうかを確認しながらコピーしてください。この際には ZEROBASEDSTRING であるかどうかも考慮してくださいね。

See Also:
[Unicode (VCL Tips)]
http://ht-deko.com/tech013.html

ページ: [1]
WP Forum Server by ForumPress | LucidCrew
バージョン: 1.7.5 ; ページロード: 0.025 sec.