2012-04-18 7 views
2

私は私が持っている - 。無料パスカルラザロまたはデルファイ

なぜ、どのように私はちゃうだけで右ジャンプ

の説明とボアの人にしたくありません生のバイトデータを含むバイト配列。配列は1000バイトです。私はその1000バイトの配列を調べて、ファイル名に似ているUTF-16 Unicode文字のみを抽出したいと思いますが、文字列が1000バイトの配列のどこにあるかはわかりません。

私は Lazarus Unicode Pagethisを読んだことがありますが、私の問題の構文的アプローチではまだまだわかりません。私は、ユニコード文字は最大4バイトのサイズが可能ですが、通常は2文字(文字とスペース)であることを理解しています。私は特定のUnicode文字を知っている他の分野の成功でUTF8encode(WideCharLenToString(@ MyArrayという、SomeIntValue)を使用している

this threadにさらに存在し、私はについての質問と解決されました。しかし、私は今、彼らのために「狩り」する必要があること今のところ、別の理由で、配列の中で、例えば ""最初の16バイトを見てくださいそれらはUnicodeですか?そうでなければ、次の16を見てください。それらはUnicodeですか?そうなら、それらを文字列に変換し、

誰も私を助けることができますか?

答えて

5

をバイトの実際のレイアウト、またはファイル名のフォーマットを知らない(それはドライブ文字を持っていませんパス、UNCパスを使用するのか、単独のファイル名なのかなど)、ファイル名文字列の境界を捜すのは難しいでしょう。

ファイル名が常にドライブ文字とパスで始まると想定できる場合は、'a'の文字からなる6バイトのUTF-16シーケンスをデコードするまで、1バイトずつループを繰り返すことができます。 'z'または'A'-'Z'、続いて':'および'\'文字である。

var 
    Buffer: array[0..1000-1] of Byte; 
    I: Integer; 
    PCh: PWord; 
    Hi, Lo: Word; 
    Ch: Cardinal; 
    PStart: PWideChar; 
    Len: Integer; 
    FileName: WideString; 
begin 
    ... 

    I := 0; 
    while I <= (SizeOf(Buffer)-6) do 
    begin 
    PCh := PWord(@Buffer[I]); 
    if not (((PCh^ >= Ord('a')) and (PCh^ <= Ord('z'))) or ((PCh^ >= Ord('A')) and (PCh^ <= Ord('Z')))) then 
    begin 
     Inc(I); 
     Continue; 
    end; 
    Inc(PCh);  
    if PCh^ <> Ord(':') then 
    begin 
     Inc(I); 
     Continue; 
    end; 
    Inc(PCh); 
    if PCh^ <> Ord('\') then 
    begin 
     Inc(I); 
     Continue; 
    end; 
    PStart := PWideChar(@Buffer[I]); 
    Len := 0; 
    Inc(I, 6); 
    Inc(PCh); 
    while I <= (SizeOf(Buffer)-2) do 
    begin 
     if (PCh^ < $D800) or (PCh^ > $DFFF) then 
     begin 
     Ch := Cardinal(PCh^); 
     Inc(I, 2); 
     if Ch = 0 then Break; 
     Inc(Len); 
     end else 
     begin 
     if PCh^ > $DBFF then Break; 
     if (I+2) = SizeOf(Buffer) then Break; 
     Hi := PCh^; 
     Inc(PCh); 
     if (PCh^ < $DC00) or (PCh^ > $DFFF) then Break; 
     Lo := PCh^; 
     Ch := ((Cardinal(Hi) - $D800) * $400) + (Cardinal(Lo) - $DC00) + $10000; 
     if Ch > $10FFFF then Break; 
     Inc(I, 4); 
     Inc(Len, 2); 
     end; 
    end; 
    SetString(FileName, PStart, Len); 
    if Len > 0 then 
    begin 
     ... use FileName as nedeed... 
    end; 
    end; 
    ... 
end; 
0

UTF-16コードポイントがいずれか2バイトかある:あなたがそれを見つけた場合は、デコードされたヌル文字または有効なUTF-16シーケンスではありませんバイナリ値、例えばに遭遇するまで、デコードUTF-16シーケンスを保ちます4バイト長。それは手紙と宇宙ではない。孤立して、ほとんどの16ビットワードは有効なUTF-16文字です。 (D800とDBFFの間の値を持つコーデポイントには、完全なUnicode文字を作成するために、DC00-DFFFの範囲の値が続く必要があります)。有効なUTF-16を探しているだけなら、あまり進歩することはありません。 .ext(UTF-16で\ 00e \ 00e \ 00x \ 00tまたは。\ 00e \ 00x \ 00t \ 00のいずれかにエンコードされるファイル名にある特定のパターンを探す必要があります。ビッグエンディアンまたはリトルエンディアン)

関連する問題